提交 8fd6fcd7 创建 作者: Frans Kaashoek's avatar Frans Kaashoek

Per-core delay list

Not important yet; in fact, none of the benchmarks run long enough to do gc
上级 75f5e818
...@@ -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;
} }
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论