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

avoid dups with lock-free insert

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