提交 374fe0a0 创建 作者: Frans Kaashoek's avatar Frans Kaashoek

checkpoint some RCU changes

上级 6600eed0
......@@ -134,6 +134,8 @@ void migrate(void);
// rcu.c
void rcuinit(void);
void rcu_begin_write(struct spinlock *);
void rcu_end_write(struct spinlock *);
// swtch.S
void swtch(struct context**, struct context*);
......
......@@ -50,8 +50,8 @@ mainc(void)
consoleinit(); // I/O devices & their interrupts
uartinit(); // serial port
kvmalloc(); // initialize the kernel page table
nsinit(); // initialize name space module
rcuinit(); // initialize rcu module
nsinit(); // initialize name space module
pinit(); // process table
tvinit(); // trap vectors
binit(); // buffer cache
......
......@@ -4,8 +4,13 @@
#include "queue.h"
// name spaces
// XXX maybe use open hash table, no chain, better cache locality
#define NHASH 100
static int rcu = 0;
#define ACQUIRE(l) (rcu) ? rcu_begin_write(l) : acquire(l)
#define RELEASE(l) (rcu) ? rcu_end_write(l) : release(l)
// XXX cache align
struct elem {
......@@ -39,11 +44,12 @@ nsalloc(void)
{
struct ns *ns = 0;
acquire(&ns_lock);
ns = kmalloc(sizeof(struct ns));
if (ns == 0)
panic("nsalloc");
memset(ns, 0, sizeof(struct ns));
acquire(&ns_lock);
for (int i = 0; i < NHASH; i++) {
TAILQ_INIT(&ns->table[i].chain);
}
......@@ -74,7 +80,7 @@ int
ns_insert(struct ns *ns, int key, void *val)
{
int r = -1;
acquire(&ns->lock);
ACQUIRE(&ns->lock);
struct elem *e = elemalloc();
if (e) {
e->key = key;
......@@ -83,7 +89,7 @@ ns_insert(struct ns *ns, int key, void *val)
TAILQ_INSERT_TAIL(&(ns->table[i].chain), e, chain);
r = 0;
}
release(&ns->lock);
RELEASE(&ns->lock);
return r;
}
......@@ -103,9 +109,9 @@ ns_dolookup(struct ns *ns, int key)
void*
ns_lookup(struct ns *ns, int key)
{
acquire(&ns->lock);
ACQUIRE(&ns->lock);
struct elem *e = ns_dolookup(ns, key);
release(&ns->lock);
RELEASE(&ns->lock);
return (e == 0)? 0 : e->val;
}
......@@ -113,14 +119,14 @@ int
ns_remove(struct ns *ns, int key)
{
int r = -1;
acquire(&ns->lock);
ACQUIRE(&ns->lock);
struct elem *e = ns_dolookup(ns, key);
if (e) {
TAILQ_REMOVE(&(ns->table[key % NHASH].chain), e, chain);
kmfree(e);
r = 0;
}
release(&ns->lock);
RELEASE(&ns->lock);
return r;
}
......
......@@ -10,8 +10,6 @@
#define NRCU 1000
#define NDELAY 500
struct rcu {
void *item;
unsigned long epoch;
......@@ -37,10 +35,11 @@ rcuinit(void)
initlock(&rcu_lock, "rcu");
for (i = 0; i < NRCU; i++) {
r = (struct rcu *) kmalloc(sizeof(struct rcu));
memset(r, 0, sizeof(struct rcu));
r->rcu = rcu_freelist;
rcu_freelist = r;
}
cprintf("rcu_init: allocated %ld bytes\n", sizeof(struct rcu) * NRCU);
cprintf("rcu_init: allocated %d bytes\n", sizeof(struct rcu) * NRCU);
}
struct rcu *
......@@ -71,7 +70,11 @@ rcu_gc(void)
int n = 0;
min_epoch = global_epoch;
acquire(&rcu_lock);
ns_enumerate(nspid, rcu_min);
for (r = rcu_delayed_head; r != NULL; r = nr) {
if (r->epoch >= min_epoch)
break;
......@@ -93,6 +96,7 @@ rcu_gc(void)
r->rcu = rcu_freelist;
rcu_freelist = r;
}
release(&rcu_lock);
// printf("rcu_gc: n=%d ndelayed_free=%d nfree=%d ninuse=%d\n", n, delayed_nfree,
// tree_nfree, tree_ninuse);
}
......@@ -108,40 +112,42 @@ rcu_delayed(void *e, void (*dofree)(void *))
r->item = e;
r->rcu = 0;
r->epoch = global_epoch;
acquire(&rcu_lock);
// printf("rcu_delayed: %ld\n", global_epoch);
if (rcu_delayed_tail != 0)
rcu_delayed_tail->rcu = r;
rcu_delayed_tail = r;
if (rcu_delayed_head == 0) rcu_delayed_head = r;
release(&rcu_lock);
delayed_nfree++;
ninuse--;
}
void
rcu_begin_read(int tid)
rcu_begin_read()
{
proc->epoch = global_epoch;
__sync_synchronize();
}
void
rcu_end_read(int tid)
rcu_end_read()
{
proc->epoch = INF;
}
void
rcu_begin_write(int tid)
rcu_begin_write(struct spinlock *l)
{
acquire(&rcu_lock);
acquire(l);
}
void
rcu_end_write(int tid)
rcu_end_write(struct spinlock *l)
{
// for other data structures using rcu, use atomic add:
__sync_fetch_and_add(&global_epoch, 1);
release(l);
rcu_gc();
release(&rcu_lock);
}
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论