Rename wq to cilk

上级 53b19d0a
...@@ -29,6 +29,7 @@ LDFLAGS += -m elf_x86_64 ...@@ -29,6 +29,7 @@ LDFLAGS += -m elf_x86_64
OBJS = \ OBJS = \
bio.o \ bio.o \
cga.o \ cga.o \
cilk.o \
condvar.o \ condvar.o \
console.o \ console.o \
crange.o \ crange.o \
...@@ -68,7 +69,6 @@ OBJS = \ ...@@ -68,7 +69,6 @@ OBJS = \
vm.o \ vm.o \
trap.o \ trap.o \
trapasm.o \ trapasm.o \
wq.o \
incbin.o incbin.o
OBJS := $(addprefix $(O)/, $(OBJS)) OBJS := $(addprefix $(O)/, $(OBJS))
......
...@@ -12,20 +12,20 @@ ...@@ -12,20 +12,20 @@
// } // }
// void foo(uptr a0, uptr a1) { // void foo(uptr a0, uptr a1) {
// char *arg = (char*) a0; // char *arg = (char*) a0;
// wq_push(goo, a0, 0); // cilk_push(goo, a0, 0);
// arg[0] = 'f'; // arg[0] = 'f';
// cprintf("foo\n"); // cprintf("foo\n");
// } // }
// void example(void) { // void example(void) {
// char arg[2]; // char arg[2];
// wq_start(); // cilk_start();
// wq_push(foo, (uptr)arg, 0); // cilk_push(foo, (uptr)arg, 0);
// cprintf("example\n"); // cprintf("example\n");
// wq_end(); // cilk_end();
// cprintf("%c %c\n", arg[0], arg[1]); // cprintf("%c %c\n", arg[0], arg[1]);
// } // }
#if WQENABLE #if CILKENABLE
#include "types.h" #include "types.h"
#include "kernel.h" #include "kernel.h"
#include "amd64.h" #include "amd64.h"
...@@ -38,10 +38,10 @@ ...@@ -38,10 +38,10 @@
#include "mtrace.h" #include "mtrace.h"
#include "qlock.h" #include "qlock.h"
#define NSLOTS (1 << WQSHIFT) #define NSLOTS (1 << CILKSHIFT)
struct wqueue { struct cilkqueue {
struct wqthread *thread[NSLOTS]; struct cilkthread *thread[NSLOTS];
volatile int head __mpalign__; volatile int head __mpalign__;
qlock_t lock; qlock_t lock;
...@@ -49,15 +49,15 @@ struct wqueue { ...@@ -49,15 +49,15 @@ struct wqueue {
__padout__; __padout__;
} __mpalign__; } __mpalign__;
struct wqthread { struct cilkthread {
u64 rip; u64 rip;
u64 arg0; u64 arg0;
u64 arg1; u64 arg1;
struct wqframe *frame; // parent wqframe struct cilkframe *frame; // parent cilkframe
__padout__; __padout__;
} __mpalign__; } __mpalign__;
struct wqstat { struct cilkstat {
u64 push; u64 push;
u64 full; u64 full;
u64 pop; u64 pop;
...@@ -65,47 +65,47 @@ struct wqstat { ...@@ -65,47 +65,47 @@ struct wqstat {
__padout__; __padout__;
} __mpalign__; } __mpalign__;
struct wqueue queue[NCPU] __mpalign__; struct cilkqueue queue[NCPU] __mpalign__;
struct wqstat stat[NCPU] __mpalign__; struct cilkstat stat[NCPU] __mpalign__;
static struct wqueue * static struct cilkqueue *
wq_cur(void) cilk_cur(void)
{ {
return &queue[mycpu()->id]; return &queue[mycpu()->id];
} }
static struct wqframe * static struct cilkframe *
wq_frame(void) cilk_frame(void)
{ {
return mycpu()->wqframe; return mycpu()->cilkframe;
} }
static struct wqstat * static struct cilkstat *
wq_stat(void) cilk_stat(void)
{ {
return &stat[mycpu()->id]; return &stat[mycpu()->id];
} }
static int static int
__wq_push(struct wqueue *q, struct wqthread *t) __cilk_push(struct cilkqueue *q, struct cilkthread *t)
{ {
int i; int i;
i = q->head; i = q->head;
if ((i - q->tail) == NSLOTS) { if ((i - q->tail) == NSLOTS) {
wq_stat()->full++; cilk_stat()->full++;
return -1; return -1;
} }
i = i & (NSLOTS-1); i = i & (NSLOTS-1);
q->thread[i] = t; q->thread[i] = t;
q->head++; q->head++;
wq_stat()->push++; cilk_stat()->push++;
return 0; return 0;
} }
static struct wqthread * static struct cilkthread *
__wq_pop(struct wqueue *q) __cilk_pop(struct cilkqueue *q)
{ {
struct qnode qn; struct qnode qn;
int i; int i;
...@@ -120,12 +120,12 @@ __wq_pop(struct wqueue *q) ...@@ -120,12 +120,12 @@ __wq_pop(struct wqueue *q)
q->head--; q->head--;
ql_unlock(&q->lock, &qn); ql_unlock(&q->lock, &qn);
wq_stat()->pop++; cilk_stat()->pop++;
return q->thread[i]; return q->thread[i];
} }
static struct wqthread * static struct cilkthread *
__wq_steal(struct wqueue *q) __cilk_steal(struct cilkqueue *q)
{ {
struct qnode qn; struct qnode qn;
int i; int i;
...@@ -140,19 +140,19 @@ __wq_steal(struct wqueue *q) ...@@ -140,19 +140,19 @@ __wq_steal(struct wqueue *q)
q->tail++; q->tail++;
ql_unlock(&q->lock, &qn); ql_unlock(&q->lock, &qn);
wq_stat()->steal++; cilk_stat()->steal++;
return q->thread[i]; return q->thread[i];
} }
static void static void
__wq_run(struct wqthread *th) __cilk_run(struct cilkthread *th)
{ {
void (*fn)(uptr arg0, uptr arg1) = (void*)th->rip; void (*fn)(uptr arg0, uptr arg1) = (void*)th->rip;
struct wqframe *old = mycpu()->wqframe; struct cilkframe *old = mycpu()->cilkframe;
mycpu()->wqframe = th->frame; mycpu()->cilkframe = th->frame;
fn(th->arg0, th->arg1); fn(th->arg0, th->arg1);
mycpu()->wqframe = old; mycpu()->cilkframe = old;
subfetch(&th->frame->ref, 1); subfetch(&th->frame->ref, 1);
kfree(th); kfree(th);
} }
...@@ -161,12 +161,12 @@ __wq_run(struct wqthread *th) ...@@ -161,12 +161,12 @@ __wq_run(struct wqthread *th)
// Guarantees some core will at some point execute the work. // Guarantees some core will at some point execute the work.
// The current core might execute the work immediately. // The current core might execute the work immediately.
void void
wq_push(void *rip, u64 arg0, u64 arg1) cilk_push(void *rip, u64 arg0, u64 arg1)
{ {
void (*fn)(uptr, uptr) = rip; void (*fn)(uptr, uptr) = rip;
struct wqthread *th; struct cilkthread *th;
th = (struct wqthread *) kalloc(); th = (struct cilkthread *) kalloc();
if (th == NULL) { if (th == NULL) {
fn(arg0, arg1); fn(arg0, arg1);
return; return;
...@@ -174,27 +174,27 @@ wq_push(void *rip, u64 arg0, u64 arg1) ...@@ -174,27 +174,27 @@ wq_push(void *rip, u64 arg0, u64 arg1)
th->rip = (uptr) rip; th->rip = (uptr) rip;
th->arg0 = arg0; th->arg0 = arg0;
th->arg1 = arg1; th->arg1 = arg1;
th->frame = wq_frame(); th->frame = cilk_frame();
if (__wq_push(wq_cur(), th)) { if (__cilk_push(cilk_cur(), th)) {
kfree(th); kfree(th);
fn(arg0, arg1); fn(arg0, arg1);
} else } else
fetchadd(&wq_frame()->ref, 1); fetchadd(&cilk_frame()->ref, 1);
} }
// Try to execute one wqthread. // Try to execute one cilkthread.
// Check local queue then steal from other queues. // Check local queue then steal from other queues.
int int
wq_trywork(void) cilk_trywork(void)
{ {
struct wqthread *th; struct cilkthread *th;
int i; int i;
pushcli(); pushcli();
th = __wq_pop(wq_cur()); th = __cilk_pop(cilk_cur());
if (th != NULL) { if (th != NULL) {
__wq_run(th); __cilk_run(th);
popcli(); popcli();
return 1; return 1;
} }
...@@ -204,9 +204,9 @@ wq_trywork(void) ...@@ -204,9 +204,9 @@ wq_trywork(void)
if (i == mycpu()->id) if (i == mycpu()->id)
continue; continue;
th = __wq_steal(&queue[i]); th = __cilk_steal(&queue[i]);
if (th != NULL) { if (th != NULL) {
__wq_run(th); __cilk_run(th);
popcli(); popcli();
return 1; return 1;
} }
...@@ -219,41 +219,41 @@ wq_trywork(void) ...@@ -219,41 +219,41 @@ wq_trywork(void)
// Start a new work queue frame. // Start a new work queue frame.
// We don't allow nested work queue frames. // We don't allow nested work queue frames.
void void
wq_start(void) cilk_start(void)
{ {
pushcli(); pushcli();
if (myproc()->wqframe.ref != 0) if (myproc()->cilkframe.ref != 0)
panic("wq_start"); panic("cilk_start");
mycpu()->wqframe = &myproc()->wqframe; mycpu()->cilkframe = &myproc()->cilkframe;
} }
// End of the current work queue frame. // End of the current work queue frame.
// The core works while the reference count of the current // The core works while the reference count of the current
// work queue frame is not 0. // work queue frame is not 0.
void void
wq_end(void) cilk_end(void)
{ {
while (wq_frame()->ref != 0) { while (cilk_frame()->ref != 0) {
struct wqthread *th; struct cilkthread *th;
int i; int i;
while ((th = __wq_pop(wq_cur())) != NULL) while ((th = __cilk_pop(cilk_cur())) != NULL)
__wq_run(th); __cilk_run(th);
for (i = 0; i < NCPU; i++) { for (i = 0; i < NCPU; i++) {
th = __wq_steal(&queue[i]); th = __cilk_steal(&queue[i]);
if (th != NULL) { if (th != NULL) {
__wq_run(th); __cilk_run(th);
break; break;
} }
} }
} }
mycpu()->wqframe = NULL; mycpu()->cilkframe = NULL;
popcli(); popcli();
} }
void void
wq_dump(void) cilk_dump(void)
{ {
int i; int i;
for (i = 0; i < NCPU; i++) for (i = 0; i < NCPU; i++)
...@@ -268,7 +268,7 @@ __test_stub(uptr a0, uptr a1) ...@@ -268,7 +268,7 @@ __test_stub(uptr a0, uptr a1)
} }
void void
testwq(void) testcilk(void)
{ {
enum { iters = 1000 }; enum { iters = 1000 };
static volatile int running = 1; static volatile int running = 1;
...@@ -279,33 +279,33 @@ testwq(void) ...@@ -279,33 +279,33 @@ testwq(void)
if (mycpu()->id == 0) { if (mycpu()->id == 0) {
microdelay(1); microdelay(1);
s = rdtsc(); s = rdtsc();
wq_start(); cilk_start();
for (i = 0; i < iters; i++) for (i = 0; i < iters; i++)
wq_push(__test_stub, i, i); cilk_push(__test_stub, i, i);
wq_end(); cilk_end();
e = rdtsc(); e = rdtsc();
cprintf("testwq: %lu\n", (e-s)/iters); cprintf("testcilk: %lu\n", (e-s)/iters);
wq_dump(); cilk_dump();
running = 0; running = 0;
} else { } else {
while (running) while (running)
wq_trywork(); cilk_trywork();
} }
popcli(); popcli();
} }
void void
initwqframe(struct wqframe *wq) initcilkframe(struct cilkframe *cilk)
{ {
memset(wq, 0, sizeof(*wq)); memset(cilk, 0, sizeof(*cilk));
} }
void void
initwq(void) initcilk(void)
{ {
int i; int i;
for (i = 0; i < NCPU; i++) for (i = 0; i < NCPU; i++)
ql_init(&queue[i].lock, "queue lock"); ql_init(&queue[i].lock, "queue lock");
} }
#endif // WQENABLE #endif // CILKENABLE
...@@ -248,8 +248,8 @@ consoleintr(int (*getc)(void)) ...@@ -248,8 +248,8 @@ consoleintr(int (*getc)(void))
consputc(BACKSPACE); consputc(BACKSPACE);
} }
break; break;
case C('W'): // Work queue stats case C('C'): // cilk stats
wq_dump(); cilk_dump();
break; break;
case C('L'): // Prof stats case C('L'): // Prof stats
profdump(); profdump();
......
#include "mmu.h" #include "mmu.h"
struct wqframe; struct cilkframe;
// Per-CPU state // Per-CPU state
struct cpu { struct cpu {
...@@ -10,7 +10,7 @@ struct cpu { ...@@ -10,7 +10,7 @@ struct cpu {
struct segdesc gdt[NSEGS]; // x86 global descriptor table struct segdesc gdt[NSEGS]; // x86 global descriptor table
struct taskstate ts; // Used by x86 to find stack for interrupt struct taskstate ts; // Used by x86 to find stack for interrupt
struct context *scheduler; // swtch() here to enter scheduler struct context *scheduler; // swtch() here to enter scheduler
struct wqframe *wqframe; struct cilkframe *cilkframe;
// Cpu-local storage variables; see below // Cpu-local storage variables; see below
struct cpu *cpu; struct cpu *cpu;
......
...@@ -190,7 +190,7 @@ exec(char *path, char **argv) ...@@ -190,7 +190,7 @@ exec(char *path, char **argv)
args.path = path; args.path = path;
args.argv = argv; args.argv = argv;
wq_start(); cilk_start();
for(i=0, off=elf.phoff; i<elf.phnum; i++, off+=sizeof(ph)){ for(i=0, off=elf.phoff; i<elf.phnum; i++, off+=sizeof(ph)){
Elf64_Word type; Elf64_Word type;
if(readi(ip, (char*)&type, if(readi(ip, (char*)&type,
...@@ -199,7 +199,7 @@ exec(char *path, char **argv) ...@@ -199,7 +199,7 @@ exec(char *path, char **argv)
goto bad; goto bad;
if(type != ELF_PROG_LOAD) if(type != ELF_PROG_LOAD)
continue; continue;
wq_push(dosegment, (uptr)&args, (uptr)off); cilk_push(dosegment, (uptr)&args, (uptr)off);
} }
if (odp) { if (odp) {
...@@ -210,14 +210,14 @@ exec(char *path, char **argv) ...@@ -210,14 +210,14 @@ exec(char *path, char **argv)
ip = 0; ip = 0;
} }
wq_push(doheap, (uptr)&args, (uptr)0); cilk_push(doheap, (uptr)&args, (uptr)0);
// dostack reads from the user address space. The wq // dostack reads from the user address space. The wq
// stuff doesn't switch to the user address space. // stuff doesn't switch to the user address space.
//wq_push(dostack, (uptr)&args, (uptr)0); //cilk_push(dostack, (uptr)&args, (uptr)0);
dostack((uptr)&args, (uptr)0); dostack((uptr)&args, (uptr)0);
wq_end(); cilk_end();
// Commit to the user image. // Commit to the user image.
oldvmap = myproc()->vmap; oldvmap = myproc()->vmap;
......
...@@ -11,9 +11,9 @@ static inline uptr v2p(void *a) { return (uptr) a - KBASE; } ...@@ -11,9 +11,9 @@ static inline uptr v2p(void *a) { return (uptr) a - KBASE; }
static inline void *p2v(uptr a) { return (void *) a + KBASE; } static inline void *p2v(uptr a) { return (void *) a + KBASE; }
struct trapframe; struct trapframe;
struct cilkframe;
struct spinlock; struct spinlock;
struct condvar; struct condvar;
struct wqframe;
struct context; struct context;
struct vmnode; struct vmnode;
struct inode; struct inode;
...@@ -325,20 +325,27 @@ struct vmap * vmap_copy(struct vmap *, int); ...@@ -325,20 +325,27 @@ struct vmap * vmap_copy(struct vmap *, int);
// wq.c // wq.c
#if WQENABLE #if WQENABLE
void wq_push(void *rip, u64 arg0, u64 arg1);
void wq_start(void);
void wq_end(void);
void wq_dump(void);
int wq_trywork(void); int wq_trywork(void);
void initwqframe(struct wqframe *wq);
#else #else
#define wq_push(rip, arg0, arg1) do { \ #define wq_trywork() 0
#endif
// cilk.c
#if CILKENABLE
void cilk_push(void *rip, u64 arg0, u64 arg1);
void cilk_start(void);
void cilk_end(void);
void cilk_dump(void);
int cilk_trywork(void);
void initcilkframe(struct cilkframe *wq);
#else
#define cilk_push(rip, arg0, arg1) do { \
void (*fn)(uptr, uptr) = rip; \ void (*fn)(uptr, uptr) = rip; \
fn(arg0, arg1); \ fn(arg0, arg1); \
} while(0) } while(0)
#define wq_start() do { } while(0) #define cilk_start() do { } while(0)
#define wq_end() do { } while(0) #define cilk_end() do { } while(0)
#define wq_dump() do { } while(0) #define cilk_dump() do { } while(0)
#define wq_trywork() 0 #define cilk_trywork() 0
#define initwqframe(x) do { } while (0) #define initcilkframe(x) do { } while (0)
#endif #endif
...@@ -23,7 +23,7 @@ extern void initinode(void); ...@@ -23,7 +23,7 @@ extern void initinode(void);
extern void initdisk(void); extern void initdisk(void);
extern void inituser(void); extern void inituser(void);
extern void inithz(void); extern void inithz(void);
extern void initwq(void); extern void initcilk(void);
extern void initsamp(void); extern void initsamp(void);
extern void initpci(void); extern void initpci(void);
extern void initnet(void); extern void initnet(void);
...@@ -103,8 +103,8 @@ cmain(u64 mbmagic, u64 mbaddr) ...@@ -103,8 +103,8 @@ cmain(u64 mbmagic, u64 mbaddr)
initbio(); // buffer cache initbio(); // buffer cache
initinode(); // inode cache initinode(); // inode cache
initdisk(); // disk initdisk(); // disk
#if WQENABLE #if CILKENABLE
initwq(); // work queues initcilk();
#endif #endif
initsamp(); initsamp();
initlockstat(); initlockstat();
......
...@@ -13,27 +13,25 @@ ...@@ -13,27 +13,25 @@
#define CACHELINE 64 // cache line size #define CACHELINE 64 // cache line size
#define CPUKSTACKS (NPROC + NCPU) #define CPUKSTACKS (NPROC + NCPU)
#define QUANTUM 10 // scheduling time quantum and tick length (in msec) #define QUANTUM 10 // scheduling time quantum and tick length (in msec)
#define WQSHIFT 4 // 2^WORKSHIFT work queue slots #define CILKSHIFT 4 // 2^WORKSHIFT work queue slots
#define VICTIMAGE 1000000 // cycles a proc executes before an eligible victim #define VICTIMAGE 1000000 // cycles a proc executes before an eligible victim
#define VERBOSE 0 // print kernel diagnostics #define VERBOSE 0 // print kernel diagnostics
#define SPINLOCK_DEBUG 1 // Debug spin locks #define SPINLOCK_DEBUG 1 // Debug spin locks
#define LOCKSTAT 0 #define LOCKSTAT 0
#define VERIFYFREE LOCKSTAT #define VERIFYFREE LOCKSTAT
#define ALLOC_MEMSET 1 #define ALLOC_MEMSET 1
#define WQENABLE 0
#if defined(HW_josmp) #if defined(HW_josmp)
#define NCPU 16 // maximum number of CPUs #define NCPU 16 // maximum number of CPUs
#define MTRACE 0 #define MTRACE 0
#define WQENABLE 0 // Enable work queue
#define PERFSIZE (1<<30ull) #define PERFSIZE (1<<30ull)
#elif defined(HW_qemu) #elif defined(HW_qemu)
#define NCPU 4 // maximum number of CPUs #define NCPU 4 // maximum number of CPUs
#define MTRACE 0 #define MTRACE 0
#define WQENABLE 0 // Enable work queue
#define PERFSIZE (16<<20ull) #define PERFSIZE (16<<20ull)
#elif defined(HW_ud0) #elif defined(HW_ud0)
#define NCPU 4 // maximum number of CPUs #define NCPU 4 // maximum number of CPUs
#define MTRACE 0 #define MTRACE 0
#define WQENABLE 0 // Enable work queue
#define PERFSIZE (512<<20ull) #define PERFSIZE (512<<20ull)
#else #else
#error "Unknown HW" #error "Unknown HW"
......
...@@ -206,7 +206,7 @@ allocproc(void) ...@@ -206,7 +206,7 @@ allocproc(void)
snprintf(p->lockname, sizeof(p->lockname), "cv:proc:%d", p->pid); snprintf(p->lockname, sizeof(p->lockname), "cv:proc:%d", p->pid);
initlock(&p->lock, p->lockname+3, LOCKSTAT_PROC); initlock(&p->lock, p->lockname+3, LOCKSTAT_PROC);
initcondvar(&p->cv, p->lockname); initcondvar(&p->cv, p->lockname);
initwqframe(&p->wqframe); initcilkframe(&p->cilkframe);
if (ns_insert(nspid, KI(p->pid), (void *) p) < 0) if (ns_insert(nspid, KI(p->pid), (void *) p) < 0)
panic("allocproc: ns_insert"); panic("allocproc: ns_insert");
......
...@@ -13,7 +13,7 @@ struct context { ...@@ -13,7 +13,7 @@ struct context {
} __attribute__((packed)); } __attribute__((packed));
// Work queue frame // Work queue frame
struct wqframe { struct cilkframe {
volatile u64 ref; volatile u64 ref;
}; };
...@@ -63,7 +63,7 @@ struct proc { ...@@ -63,7 +63,7 @@ struct proc {
struct mtrace_stacks mtrace_stacks; struct mtrace_stacks mtrace_stacks;
#endif #endif
struct runq *runq; struct runq *runq;
struct wqframe wqframe; struct cilkframe cilkframe;
STAILQ_ENTRY(proc) runqlink; STAILQ_ENTRY(proc) runqlink;
struct condvar *oncv; // Where it is sleeping, for kill() struct condvar *oncv; // Where it is sleeping, for kill()
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论