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

avoid dups with lock-free insert

上级 3bc01fa3
...@@ -100,7 +100,7 @@ void mpstartthem(void); ...@@ -100,7 +100,7 @@ void mpstartthem(void);
// ns.c // ns.c
void nsinit(void); void nsinit(void);
struct ns* nsalloc(void); struct ns* nsalloc(int allowdup);
int ns_allockey(struct ns*); int ns_allockey(struct ns*);
int ns_insert(struct ns*, int key, void*); int ns_insert(struct ns*, int key, void*);
void* ns_lookup(struct ns*, int); void* ns_lookup(struct ns*, int);
......
...@@ -24,7 +24,7 @@ struct bucket { ...@@ -24,7 +24,7 @@ struct bucket {
} __attribute__((aligned (CACHELINE))); } __attribute__((aligned (CACHELINE)));
struct ns { struct ns {
int used; int allowdup;
int nextkey; int nextkey;
struct bucket table[NHASH]; struct bucket table[NHASH];
}; };
...@@ -36,7 +36,7 @@ nsinit(void) ...@@ -36,7 +36,7 @@ nsinit(void)
// XXX should be using our missing scalable allocator module // XXX should be using our missing scalable allocator module
struct ns* struct ns*
nsalloc(void) nsalloc(int allowdup)
{ {
struct ns *ns = 0; struct ns *ns = 0;
...@@ -45,6 +45,7 @@ nsalloc(void) ...@@ -45,6 +45,7 @@ nsalloc(void)
panic("nsalloc"); panic("nsalloc");
memset(ns, 0, sizeof(struct ns)); memset(ns, 0, sizeof(struct ns));
ns->nextkey = 1; ns->nextkey = 1;
ns->allowdup = allowdup;
return ns; return ns;
} }
...@@ -70,23 +71,34 @@ ns_allockey(struct ns *ns) ...@@ -70,23 +71,34 @@ ns_allockey(struct ns *ns)
int int
ns_insert(struct ns *ns, int key, void *val) ns_insert(struct ns *ns, int key, void *val)
{ {
int r = -1;
struct elem *e = elemalloc(); struct elem *e = elemalloc();
if (e) { if (e) {
e->key = key; e->key = key;
e->val = val; e->val = val;
uint i = key % NHASH; uint i = key % NHASH;
rcu_begin_write(0); rcu_begin_write(0);
for (;;) {
struct elem *x = ns->table[i].chain; retry:
e->next = x; (void) 0;
if (__sync_bool_compare_and_swap(&ns->table[i].chain, x, e)) struct elem *root = ns->table[i].chain;
break; if (!ns->allowdup) {
for (struct elem *x = root; x; x = x->next) {
if (x->key == key) {
rcu_end_write(0);
rcu_delayed(e, kmfree);
return -1;
} }
}
}
e->next = root;
if (!__sync_bool_compare_and_swap(&ns->table[i].chain, root, e))
goto retry;
rcu_end_write(0); rcu_end_write(0);
r = 0; return 0;
} }
return r; return -1;
} }
void* void*
......
...@@ -25,11 +25,11 @@ pinit(void) ...@@ -25,11 +25,11 @@ pinit(void)
{ {
int c; int c;
nspid = nsalloc(); nspid = nsalloc(0);
if (nspid == 0) if (nspid == 0)
panic("pinit"); panic("pinit");
nsrunq = nsalloc(); nsrunq = nsalloc(1);
if (nsrunq == 0) if (nsrunq == 0)
panic("pinit runq"); panic("pinit runq");
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论