提交 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,6 +73,9 @@ gc_free_elem(struct gc *r) ...@@ -73,6 +73,9 @@ gc_free_elem(struct gc *r)
static void static void
gc_free_epoch(u64 epoch) gc_free_epoch(u64 epoch)
{ {
cprintf("free epoch %d\n", epoch);
for (int j = 0; j < NCPU; j++) {
if (__sync_bool_compare_and_swap(&global_epoch, epoch, epoch+1)) { if (__sync_bool_compare_and_swap(&global_epoch, epoch, epoch+1)) {
// only one core succeeds; that core in charge of freeing epoch // only one core succeeds; that core in charge of freeing epoch
struct gc *head; struct gc *head;
...@@ -80,13 +83,13 @@ gc_free_epoch(u64 epoch) ...@@ -80,13 +83,13 @@ gc_free_epoch(u64 epoch)
uint32 fe = (epoch - (NEPOCH-2)) % NEPOCH; uint32 fe = (epoch - (NEPOCH-2)) % NEPOCH;
int cas; int cas;
if (gc_epoch[fe].epoch != epoch - (NEPOCH-2)) if (gc_epoch[fe][j].epoch != epoch - (NEPOCH-2))
panic("gc_free_epoch"); panic("gc_free_epoch");
// unhook list for fe epoch atomically // unhook list for fe epoch atomically
head = gc_epoch[fe].next; head = gc_epoch[fe][j].next;
// this shouldn't fail, because no core is modifying it. // this shouldn't fail, because no core is modifying it.
cas = __sync_bool_compare_and_swap(&gc_epoch[fe].next, head, 0); cas = __sync_bool_compare_and_swap(&gc_epoch[fe][j].next, head, 0);
if (!cas) panic("gc_free_epoch"); if (!cas) panic("gc_free_epoch");
// free list items on the delayed list // free list items on the delayed list
for (r = head; r != NULL; r = nr) { for (r = head; r != NULL; r = nr) {
...@@ -99,9 +102,10 @@ gc_free_epoch(u64 epoch) ...@@ -99,9 +102,10 @@ gc_free_epoch(u64 epoch)
int x = __sync_fetch_and_sub(&ndelayed, 1); int x = __sync_fetch_and_sub(&ndelayed, 1);
if (x < 0) panic("gc_free_epoch"); if (x < 0) panic("gc_free_epoch");
} }
if (gc_epoch[fe].next != 0) if (gc_epoch[fe][j].next != 0)
panic("gc_free_epoch"); panic("gc_free_epoch");
gc_epoch[fe].epoch = gc_epoch[fe].epoch + NEPOCH; gc_epoch[fe][j].epoch = gc_epoch[fe][j].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,8 +160,8 @@ gc_delayed_int(struct gc *r) ...@@ -156,8 +160,8 @@ 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();
} }
...@@ -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 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论