提交 d678eac0 创建 作者: Robert Morris's avatar Robert Morris

hack to farm mmap()s out to wq

上级 22ed1efb
...@@ -18,6 +18,7 @@ UPROGS= \ ...@@ -18,6 +18,7 @@ UPROGS= \
usertests \ usertests \
lockstat \ lockstat \
preadtest \ preadtest \
scripttest \
ftest \ ftest \
perf perf
......
#include "types.h"
#include "stat.h"
#include "fcntl.h"
#include "user.h"
#include "lib.h"
#include "amd64.h"
#include "ipc.hh"
#include "mmu.h"
int
main(int ac, char **av)
{
char *p = (char*) PGROUNDUP((u64)(sbrk(0) + 0x80000));
u64 len = 1000*4096;
u64 chunk = 128*4096; // max vmnode size
#if 0
char *q = p;
while(q < p + len){
u64 x = len - (q - p);
if(x > chunk)
x = chunk;
if(map(q, x) < 0){
fprintf(1, "map failed\n");
exit();
}
q += x;
}
#else
script(p, len, chunk);
#endif
memset(p, 1, len);
exit();
}
...@@ -47,6 +47,7 @@ long sys_listen(int, int); ...@@ -47,6 +47,7 @@ long sys_listen(int, int);
long sys_accept(int, void*, void*); long sys_accept(int, void*, void*);
long sys_pread(int fd, void *ubuf, size_t count, off_t offset); long sys_pread(int fd, void *ubuf, size_t count, off_t offset);
long sys_async(int, size_t, off_t, u32, u32); long sys_async(int, size_t, off_t, u32, u32);
long sys_script(void *addr, u64 len, u64 chunk);
extern long (*syscalls[])(u64, u64, u64, u64, u64, u64); extern long (*syscalls[])(u64, u64, u64, u64, u64, u64);
// other exported/imported functions // other exported/imported functions
......
...@@ -29,4 +29,5 @@ ...@@ -29,4 +29,5 @@
#define SYS_accept 28 #define SYS_accept 28
#define SYS_pread 29 #define SYS_pread 29
#define SYS_async 30 #define SYS_async 30
#define SYS_ncount 31 /* total number of system calls */ #define SYS_script 31
#define SYS_ncount 32 /* total number of system calls */
...@@ -29,6 +29,7 @@ int unmap(void *addr, int len); ...@@ -29,6 +29,7 @@ int unmap(void *addr, int len);
void halt(void); void halt(void);
ssize_t pread(int, void*, size_t, off_t); ssize_t pread(int, void*, size_t, off_t);
int async(int, size_t, off_t, u32, u32); int async(int, size_t, off_t, u32, u32);
int script(void *addr, u64 len, u64 chunk);
// ulib.c // ulib.c
int stat(char*, struct stat*); int stat(char*, struct stat*);
......
...@@ -60,7 +60,7 @@ struct vmap { ...@@ -60,7 +60,7 @@ struct vmap {
void decref(); void decref();
vmap* copy(int share); vmap* copy(int share);
vma* lookup(uptr start, uptr len); vma* lookup(uptr start, uptr len);
int insert(vmnode *n, uptr va_start); int insert(vmnode *n, uptr va_start, int dotlb);
int remove(uptr start, uptr len); int remove(uptr start, uptr len);
int pagefault(uptr va, u32 err); int pagefault(uptr va, u32 err);
......
...@@ -44,6 +44,7 @@ OBJS = \ ...@@ -44,6 +44,7 @@ OBJS = \
trap.o \ trap.o \
trapasm.o \ trapasm.o \
wq.o \ wq.o \
script.o \
incbin.o incbin.o
OBJS := $(addprefix $(O)/kernel/, $(OBJS)) OBJS := $(addprefix $(O)/kernel/, $(OBJS))
......
...@@ -78,5 +78,6 @@ long (*syscalls[])(u64, u64, u64, u64, u64, u64) = { ...@@ -78,5 +78,6 @@ long (*syscalls[])(u64, u64, u64, u64, u64, u64) = {
SYSCALL(accept), SYSCALL(accept),
SYSCALL(pread), SYSCALL(pread),
SYSCALL(async), SYSCALL(async),
SYSCALL(script),
}; };
...@@ -58,7 +58,7 @@ dosegment(uptr a0, u64 a1) ...@@ -58,7 +58,7 @@ dosegment(uptr a0, u64 a1)
args->ip, ph.offset, ph.filesz)) == 0) args->ip, ph.offset, ph.filesz)) == 0)
goto bad; goto bad;
if(args->vmap->insert(vmn, ph.vaddr) < 0) if(args->vmap->insert(vmn, ph.vaddr, 1) < 0)
goto bad; goto bad;
prof_end(dosegment_prof); prof_end(dosegment_prof);
...@@ -82,7 +82,7 @@ static void dostack(uptr a0, u64 a1) ...@@ -82,7 +82,7 @@ static void dostack(uptr a0, u64 a1)
// Allocate a one-page stack at the top of the (user) address space // Allocate a one-page stack at the top of the (user) address space
if((vmn = new vmnode(USTACKPAGES)) == 0) if((vmn = new vmnode(USTACKPAGES)) == 0)
goto bad; goto bad;
if(args->vmap->insert(vmn, USERTOP-(USTACKPAGES*PGSIZE)) < 0) if(args->vmap->insert(vmn, USERTOP-(USTACKPAGES*PGSIZE), 1) < 0)
goto bad; goto bad;
vmn = 0; vmn = 0;
...@@ -133,7 +133,7 @@ static void doheap(uptr a0, u64 a1) ...@@ -133,7 +133,7 @@ static void doheap(uptr a0, u64 a1)
// XXX pre-allocate 32 pages.. // XXX pre-allocate 32 pages..
if((vmn = new vmnode(32)) == 0) if((vmn = new vmnode(32)) == 0)
goto bad; goto bad;
if(args->vmap->insert(vmn, BRK) < 0) if(args->vmap->insert(vmn, BRK, 1) < 0)
goto bad; goto bad;
vmn = 0; vmn = 0;
prof_end(doheap_prof); prof_end(doheap_prof);
......
...@@ -277,7 +277,7 @@ inituser(void) ...@@ -277,7 +277,7 @@ inituser(void)
vmnode *vmn = new vmnode(PGROUNDUP(_initcode_size) / PGSIZE); vmnode *vmn = new vmnode(PGROUNDUP(_initcode_size) / PGSIZE);
if(vmn == 0) if(vmn == 0)
panic("userinit: vmn_allocpg"); panic("userinit: vmn_allocpg");
if(p->vmap->insert(vmn, 0) < 0) if(p->vmap->insert(vmn, 0, 1) < 0)
panic("userinit: vmap_insert"); panic("userinit: vmap_insert");
if(p->vmap->copyout(0, _initcode_start, _initcode_size) < 0) if(p->vmap->copyout(0, _initcode_start, _initcode_size) < 0)
panic("userinit: copyout"); panic("userinit: copyout");
...@@ -391,6 +391,7 @@ scheduler(void) ...@@ -391,6 +391,7 @@ scheduler(void)
if (idle[mycpu()->id]) { if (idle[mycpu()->id]) {
int worked; int worked;
do { do {
assert(mycpu()->ncli == 0);
worked = wq_trywork(); worked = wq_trywork();
} while(worked); } while(worked);
sti(); sti();
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
#include "cpu.hh" #include "cpu.hh"
#include "bits.hh" #include "bits.hh"
#include "kmtrace.hh" #include "kmtrace.hh"
#include "sched.h" #include "sched.hh"
#include "vm.hh" #include "vm.hh"
#include <stddef.h> #include <stddef.h>
......
#include "types.h"
#include "kernel.hh"
#include "spinlock.h"
#include "condvar.h"
#include "cpu.hh"
#include "proc.hh"
#include "fs.h"
#include "wq.hh"
#include "ipc.hh"
#include "vm.hh"
#include "file.hh"
void
script_mmap_work(struct work *w, void *a0, void *a1, void *a2, void *a3)
{
void *addr = (void *) a0;
u64 len = (u64) a1;
atomic<int> *donep = (atomic<int> *) a2;
struct proc *p = (struct proc *) a3;
vmnode *vmn = new vmnode(PGROUNDUP(len) / PGSIZE);
if(vmn == 0)
panic("sys_script: new vmnode");
if(p->vmap->insert(vmn, PGROUNDDOWN((u64)addr), 0) < 0)
panic("sys_script: insert");
*donep += 1;
}
long
sys_script(void *addr, u64 len, u64 chunk)
{
atomic<int> done;
done = 0;
int queued = 0;
char *q = (char*) addr;
while(q < (char*)addr + len){
u64 x = len - (q - (char*)addr);
if(x > chunk)
x = chunk;
struct work *w = allocwork();
if(w == 0)
panic("sys_script allocwork");
w->rip = (void*) script_mmap_work;
w->arg0 = (void *) q;
w->arg1 = (void *) x;
w->arg2 = (void *) &done;
w->arg3 = (void *) myproc();
if(wq_push(w) < 0)
panic("sys_script wq_push");
queued++;
q += chunk;
}
while(done < queued){
// yield();
wq_trywork();
}
tlbflush();
return 0;
}
...@@ -111,7 +111,7 @@ sys_map(void) ...@@ -111,7 +111,7 @@ sys_map(void)
if (vmn == 0) if (vmn == 0)
return -1; return -1;
if (myproc()->vmap->insert(vmn, PGROUNDDOWN(addr)) < 0) { if (myproc()->vmap->insert(vmn, PGROUNDDOWN(addr), 1) < 0) {
delete vmn; delete vmn;
return -1; return -1;
} }
......
...@@ -275,7 +275,7 @@ vmap::lookup(uptr start, uptr len) ...@@ -275,7 +275,7 @@ vmap::lookup(uptr start, uptr len)
} }
int int
vmap::insert(vmnode *n, uptr vma_start) vmap::insert(vmnode *n, uptr vma_start, int dotlb)
{ {
vma *e; vma *e;
...@@ -309,7 +309,8 @@ vmap::insert(vmnode *n, uptr vma_start) ...@@ -309,7 +309,8 @@ vmap::insert(vmnode *n, uptr vma_start)
break; break;
} }
}); });
tlbflush(); if(dotlb)
tlbflush();
return 0; return 0;
} }
......
...@@ -38,3 +38,4 @@ SYSCALL(listen) ...@@ -38,3 +38,4 @@ SYSCALL(listen)
SYSCALL(accept) SYSCALL(accept)
SYSCALL(pread) SYSCALL(pread)
SYSCALL(async) SYSCALL(async)
SYSCALL(script)
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论