提交 845e50fe 创建 作者: Nickolai Zeldovich's avatar Nickolai Zeldovich

rcu nits

上级 31786361
......@@ -11,7 +11,7 @@
struct rcu {
void *item;
unsigned long epoch;
struct rcu *rcu;
struct rcu *next;
void (*dofree)(void *);
};
static struct { struct rcu *x __attribute__((aligned (CACHELINE))); } rcu_delayed_head[NCPU];
......@@ -21,6 +21,8 @@ static struct { uint x __attribute__((aligned (CACHELINE))); } min_epoch[NCPU];
static struct { struct spinlock l __attribute__((aligned (CACHELINE))); } rcu_lock[NCPU];
static struct { int v __attribute__((aligned (CACHELINE))); } delayed_nfree[NCPU];
enum { rcu_debug = 0 };
void
rcuinit(void)
{
......@@ -60,40 +62,50 @@ rcu_gc(void)
for (r = rcu_delayed_head[cpu->id].x; r != NULL; r = nr) {
if (r->epoch >= min_epoch[cpu->id].x)
break;
// cprintf("free: %d\n", r->epoch);
// cprintf("free: %d (%x %x)\n", r->epoch, r->dofree, r->item);
if (r->dofree == 0)
panic("rcu_gc");
r->dofree(r->item);
delayed_nfree[cpu->id].v--;
n++;
rcu_delayed_head[cpu->id].x = r->rcu;
rcu_delayed_head[cpu->id].x = r->next;
if (rcu_delayed_head[cpu->id].x == 0)
rcu_delayed_tail[cpu->id].x = 0;
nr = r->rcu;
nr = r->next;
kmfree(r);
}
release(&rcu_lock[cpu->id].l);
// cprintf("rcu_gc: cpu %d n %d delayed_nfree=%d min_epoch=%d\n",
// cpu->id, n, delayed_nfree[cpu->id], min_epoch[cpu->id]);
popcli();
// cprintf("rcu_gc: n %d ndelayed_free=%d\n", n, delayed_nfree);
// global_epoch can be bumped anywhere; this seems as good a place as any
__sync_fetch_and_add(&global_epoch, 1);
}
// XXX Use atomic instruction to update list (instead of holding lock)
void
rcu_delayed(void *e, void (*dofree)(void *))
{
if (rcu_debug) {
cprintf("rcu_delayed: %x %x\n", dofree, e);
for (struct rcu *r = rcu_delayed_head[cpu->id].x; r; r = r->next)
if (r->item == e && r->dofree == dofree)
panic("rcu_delayed double free");
}
struct rcu *r = rcu_alloc();
if (r == 0)
panic("rcu_delayed");
r->dofree = dofree;
r->item = e;
r->rcu = 0;
r->next = 0;
r->epoch = global_epoch;
pushcli();
acquire(&rcu_lock[cpu->id].l);
// cprintf("rcu_delayed: %d\n", global_epoch);
if (rcu_delayed_tail[cpu->id].x != 0)
rcu_delayed_tail[cpu->id].x->rcu = r;
rcu_delayed_tail[cpu->id].x->next = r;
rcu_delayed_tail[cpu->id].x = r;
if (rcu_delayed_head[cpu->id].x == 0)
rcu_delayed_head[cpu->id].x = r;
......@@ -131,9 +143,6 @@ rcu_end_write(struct spinlock *l)
{
rcu_end_read();
// global_epoch can be bumped anywhere; this seems as good a place as any
__sync_fetch_and_add(&global_epoch, 1);
if (l) release(l);
}
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论