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

recursive read rcu sections; optional rcu write lock

上级 a1845865
...@@ -91,6 +91,7 @@ struct proc { ...@@ -91,6 +91,7 @@ struct proc {
SLIST_ENTRY(proc) child_next; SLIST_ENTRY(proc) child_next;
struct condvar cv; struct condvar cv;
uint epoch; uint epoch;
uint rcu_read_depth;
char lockname[16]; char lockname[16];
}; };
......
...@@ -97,30 +97,33 @@ rcu_delayed(void *e, void (*dofree)(void *)) ...@@ -97,30 +97,33 @@ rcu_delayed(void *e, void (*dofree)(void *))
void void
rcu_begin_read(void) rcu_begin_read(void)
{ {
proc->epoch = global_epoch; if (proc->rcu_read_depth++ == 0)
proc->epoch = global_epoch;
__sync_synchronize(); __sync_synchronize();
} }
void void
rcu_end_read(void) rcu_end_read(void)
{ {
proc->epoch = INF; if (--proc->rcu_read_depth == 0)
proc->epoch = INF;
} }
void void
rcu_begin_write(struct spinlock *l) rcu_begin_write(struct spinlock *l)
{ {
acquire(l); rcu_begin_read();
if (l) acquire(l);
__sync_synchronize();
} }
// XXX if a process never calls rcu_end_write() we have a problem; run
// rcu_gc from a kernel thread periodically?
void void
rcu_end_write(struct spinlock *l) rcu_end_write(struct spinlock *l)
{ {
// for other data structures using rcu, use atomic add: // global_epoch can be bumped anywhere; this seems as good a place as any
__sync_fetch_and_add(&global_epoch, 1); __sync_fetch_and_add(&global_epoch, 1);
release(l);
// rcu_gc(); if (l) release(l);
rcu_end_read();
} }
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论