提交 5515a5e3 创建 作者: Silas Boyd-Wickizer's avatar Silas Boyd-Wickizer

Merge.

...@@ -32,6 +32,7 @@ OBJS = \ ...@@ -32,6 +32,7 @@ OBJS = \
cga.o \ cga.o \
condvar.o \ condvar.o \
console.o \ console.o \
crange.o \
e1000.o \ e1000.o \
exec.o \ exec.o \
file.o \ file.o \
...@@ -53,6 +54,7 @@ OBJS = \ ...@@ -53,6 +54,7 @@ OBJS = \
proc.o \ proc.o \
prof.o \ prof.o \
gc.o \ gc.o \
rnd.o \
sampler.o \ sampler.o \
sched.o \ sched.o \
spinlock.o \ spinlock.o \
......
差异被折叠。
...@@ -31,7 +31,7 @@ struct gc { ...@@ -31,7 +31,7 @@ struct gc {
}; };
int type; int type;
} __mpalign__; } __mpalign__;
struct gc gc_epoch[NEPOCH] __mpalign__; struct gc gc_epoch[NEPOCH][NCPU] __mpalign__;
u64 global_epoch __mpalign__; u64 global_epoch __mpalign__;
int ndelayed __mpalign__; int ndelayed __mpalign__;
...@@ -73,35 +73,39 @@ gc_free_elem(struct gc *r) ...@@ -73,35 +73,39 @@ gc_free_elem(struct gc *r)
static void static void
gc_free_epoch(u64 epoch) gc_free_epoch(u64 epoch)
{ {
if (__sync_bool_compare_and_swap(&global_epoch, epoch, epoch+1)) { cprintf("free epoch %d\n", epoch);
// only one core succeeds; that core in charge of freeing epoch
struct gc *head; for (int j = 0; j < NCPU; j++) {
struct gc *r, *nr; if (__sync_bool_compare_and_swap(&global_epoch, epoch, epoch+1)) {
uint32 fe = (epoch - (NEPOCH-2)) % NEPOCH; // only one core succeeds; that core in charge of freeing epoch
int cas; struct gc *head;
struct gc *r, *nr;
if (gc_epoch[fe].epoch != epoch - (NEPOCH-2)) uint32 fe = (epoch - (NEPOCH-2)) % NEPOCH;
panic("gc_free_epoch"); int cas;
// unhook list for fe epoch atomically if (gc_epoch[fe][j].epoch != epoch - (NEPOCH-2))
head = gc_epoch[fe].next;
// this shouldn't fail, because no core is modifying it.
cas = __sync_bool_compare_and_swap(&gc_epoch[fe].next, head, 0);
if (!cas) panic("gc_free_epoch");
// free list items on the delayed list
for (r = head; r != NULL; r = nr) {
if (r->epoch > epoch-(NEPOCH-2)) {
cprintf("%lu %lu\n", r->epoch, epoch-(NEPOCH-2));
panic("gc_free_epoch"); panic("gc_free_epoch");
// unhook list for fe epoch atomically
head = gc_epoch[fe][j].next;
// this shouldn't fail, because no core is modifying it.
cas = __sync_bool_compare_and_swap(&gc_epoch[fe][j].next, head, 0);
if (!cas) panic("gc_free_epoch");
// free list items on the delayed list
for (r = head; r != NULL; r = nr) {
if (r->epoch > epoch-(NEPOCH-2)) {
cprintf("%lu %lu\n", r->epoch, epoch-(NEPOCH-2));
panic("gc_free_epoch");
}
nr = r->next;
gc_free_elem(r);
int x = __sync_fetch_and_sub(&ndelayed, 1);
if (x < 0) panic("gc_free_epoch");
} }
nr = r->next; if (gc_epoch[fe][j].next != 0)
gc_free_elem(r); panic("gc_free_epoch");
int x = __sync_fetch_and_sub(&ndelayed, 1); gc_epoch[fe][j].epoch = gc_epoch[fe][j].epoch + NEPOCH;
if (x < 0) panic("gc_free_epoch");
} }
if (gc_epoch[fe].next != 0)
panic("gc_free_epoch");
gc_epoch[fe].epoch = gc_epoch[fe].epoch + NEPOCH;
} }
} }
...@@ -148,7 +152,7 @@ gc_delayed_int(struct gc *r) ...@@ -148,7 +152,7 @@ gc_delayed_int(struct gc *r)
{ {
pushcli(); pushcli();
u64 myepoch = myproc()->epoch; u64 myepoch = myproc()->epoch;
u64 minepoch = gc_epoch[myepoch % NEPOCH].epoch; u64 minepoch = gc_epoch[myepoch % NEPOCH][mycpu()->id].epoch;
// cprintf("%d: gc_delayed: %lu ndelayed %d\n", myproc()->pid, global_epoch, ndelayed); // cprintf("%d: gc_delayed: %lu ndelayed %d\n", myproc()->pid, global_epoch, ndelayed);
if (myepoch != minepoch) { if (myepoch != minepoch) {
cprintf("%d: myepoch %lu minepoch %lu\n", myproc()->pid, myepoch, minepoch); cprintf("%d: myepoch %lu minepoch %lu\n", myproc()->pid, myepoch, minepoch);
...@@ -156,9 +160,9 @@ gc_delayed_int(struct gc *r) ...@@ -156,9 +160,9 @@ gc_delayed_int(struct gc *r)
} }
r->epoch = myepoch; r->epoch = myepoch;
do { do {
r->next = gc_epoch[myepoch % NEPOCH].next; r->next = gc_epoch[myepoch % NEPOCH][mycpu()->id].next;
} while (!__sync_bool_compare_and_swap(&(gc_epoch[myepoch % NEPOCH].next), r->next, r)); } while (!__sync_bool_compare_and_swap(&(gc_epoch[myepoch % NEPOCH][mycpu()->id].next), r->next, r));
popcli(); popcli();
} }
void void
...@@ -210,5 +214,6 @@ initgc(void) ...@@ -210,5 +214,6 @@ initgc(void)
} }
global_epoch = NEPOCH-2; global_epoch = NEPOCH-2;
for (int i = 0; i < NEPOCH; i++) for (int i = 0; i < NEPOCH; i++)
gc_epoch[i].epoch = i; for (int j = 0; j < NEPOCH; j++)
gc_epoch[i][j].epoch = i;
} }
...@@ -102,6 +102,15 @@ int dirlink(struct inode*, char*, u32); ...@@ -102,6 +102,15 @@ int dirlink(struct inode*, char*, u32);
void dir_init(struct inode *dp); void dir_init(struct inode *dp);
void dir_flush(struct inode *dp); void dir_flush(struct inode *dp);
// gc.c
void initgc(void);
void gc_begin_epoch();
void gc_end_epoch();
void gc_delayed(void*, void (*dofree)(void*));
void gc_delayed2(int, u64, void (*dofree)(int, u64));
void gc_start(void);
void gc_worker(void);
// hwvm.c // hwvm.c
void freevm(pml4e_t*); void freevm(pml4e_t*);
pml4e_t* setupkvm(void); pml4e_t* setupkvm(void);
...@@ -225,14 +234,9 @@ extern int profenable; ...@@ -225,14 +234,9 @@ extern int profenable;
void profreset(void); void profreset(void);
void profdump(void); void profdump(void);
// rcu.c
void initgc(void); // rnd.c
void gc_begin_epoch(); u64 rnd();
void gc_end_epoch();
void gc_delayed(void*, void (*dofree)(void*));
void gc_delayed2(int, u64, void (*dofree)(int, u64));
void gc_start(void);
void gc_worker(void);
// sampler.c // sampler.c
void sampstart(void); void sampstart(void);
......
#include "param.h"
#include "types.h"
#include "kernel.h"
#include "cpu.h"
struct seed {
u64 v;
} __mapalign__;
static struct seed seeds[NCPU] __mpalign__;
u64
rnd(void)
{
if (seeds[mycpu()->id].v == 0) {
seeds[mycpu()->id].v = ticks;
}
seeds[mycpu()->id].v =
seeds[mycpu()->id].v * 6364136223846793005 + 1442695040888963407;
return seeds[mycpu()->id].v;
}
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论