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

Merge branch 'scale' of ssh://amsterdam.csail.mit.edu/home/am0/6.828/xv6 into scale

...@@ -44,13 +44,13 @@ binit(void) ...@@ -44,13 +44,13 @@ binit(void)
b->flags = 0; b->flags = 0;
initlock(&b->lock, "bcache-lock"); initlock(&b->lock, "bcache-lock");
initcondvar(&b->cv, "bcache-cv"); initcondvar(&b->cv, "bcache-cv");
if (ns_insert(bufns, b->sector, b) < 0) if (ns_insert(bufns, KI(b->sector), b) < 0)
panic("binit ns_insert"); panic("binit ns_insert");
} }
} }
static void * static void *
evict(uint key, void *bp) evict(void *vkey, void *bp)
{ {
struct buf *b = bp; struct buf *b = bp;
acquire(&b->lock); acquire(&b->lock);
...@@ -61,7 +61,7 @@ evict(uint key, void *bp) ...@@ -61,7 +61,7 @@ evict(uint key, void *bp)
} }
static void * static void *
evict_valid(uint key, void *bp) evict_valid(void *vkey, void *bp)
{ {
struct buf *b = bp; struct buf *b = bp;
acquire(&b->lock); acquire(&b->lock);
...@@ -83,7 +83,7 @@ bget(uint dev, uint sector, int *writer) ...@@ -83,7 +83,7 @@ bget(uint dev, uint sector, int *writer)
// Try for cached block. // Try for cached block.
// XXX ignore dev // XXX ignore dev
rcu_begin_read(); rcu_begin_read();
b = ns_lookup(bufns, sector); b = ns_lookup(bufns, KI(sector));
if (b) { if (b) {
if (b->dev != dev) if (b->dev != dev)
panic("dev mismatch"); panic("dev mismatch");
...@@ -113,7 +113,7 @@ bget(uint dev, uint sector, int *writer) ...@@ -113,7 +113,7 @@ bget(uint dev, uint sector, int *writer)
if (victim == 0) if (victim == 0)
panic("bget all busy"); panic("bget all busy");
victim->flags |= B_BUSY; victim->flags |= B_BUSY;
ns_remove(bufns, victim->sector, victim); ns_remove(bufns, KI(victim->sector), victim);
release(&victim->lock); release(&victim->lock);
rcu_delayed(victim, kmfree); rcu_delayed(victim, kmfree);
...@@ -126,7 +126,7 @@ bget(uint dev, uint sector, int *writer) ...@@ -126,7 +126,7 @@ bget(uint dev, uint sector, int *writer)
initlock(&b->lock, b->lockname+3); initlock(&b->lock, b->lockname+3);
initcondvar(&b->cv, b->lockname); initcondvar(&b->cv, b->lockname);
rcu_begin_read(); rcu_begin_read();
if (ns_insert(bufns, b->sector, b) < 0) { if (ns_insert(bufns, KI(b->sector), b) < 0) {
rcu_delayed(b, kmfree); rcu_delayed(b, kmfree);
goto loop; goto loop;
} }
......
...@@ -99,15 +99,45 @@ void mpinit(void); ...@@ -99,15 +99,45 @@ void mpinit(void);
void mpstartthem(void); void mpstartthem(void);
// ns.c // ns.c
enum {
nskey_int = 1,
nskey_ii,
nskey_str,
nskey_iis
};
struct nskey {
int type;
union {
uint i;
struct {
uint a;
uint b;
} ii;
char *s;
struct {
uint a;
uint b;
char *s;
} iis;
} u;
};
#define KI(v) (struct nskey){.type=nskey_int,.u.i=v}
#define KII(x,y) (struct nskey){.type=nskey_ii,.u.ii.a=x,.u.ii.b=y}
#define KS(v) (struct nskey){.type=nskey_str,.u.s=v}
#define KIIS(x,y,z) (struct nskey){.type=nskey_iis,.u.iis.a=x, \
.u.iis.b=y, \
.u.iis.s=z}
void nsinit(void); void nsinit(void);
struct ns* nsalloc(int allowdup); struct ns* nsalloc(int allowdup);
int ns_allockey(struct ns*); int ns_allockey(struct ns*);
int ns_insert(struct ns*, uint key, void*); int ns_insert(struct ns*, struct nskey key, void*);
void* ns_lookup(struct ns*, uint); void* ns_lookup(struct ns*, struct nskey key);
int ns_remove(struct ns *ns, uint key, void *val); int ns_remove(struct ns *ns, struct nskey key, void *val);
void* ns_enumerate(struct ns *ns, void *(*f)(uint, void *)); void* ns_enumerate(struct ns *ns, void *(*f)(void *, void *));
void* ns_enumerate_key(struct ns *ns, uint key, void *(*f)(void *)); void* ns_enumerate_key(struct ns *ns, struct nskey key, void *(*f)(void *));
// picirq.c // picirq.c
void picenable(int); void picenable(int);
...@@ -166,6 +196,7 @@ char* safestrcpy(char*, const char*, int); ...@@ -166,6 +196,7 @@ char* safestrcpy(char*, const char*, int);
int strlen(const char*); int strlen(const char*);
int strncmp(const char*, const char*, uint); int strncmp(const char*, const char*, uint);
char* strncpy(char*, const char*, int); char* strncpy(char*, const char*, int);
int strcmp(const char *p, const char *q);
// syscall.c // syscall.c
int argint(int, int*); int argint(int, int*);
......
...@@ -143,7 +143,7 @@ iinit(void) ...@@ -143,7 +143,7 @@ iinit(void)
ip->inum = -i-1; ip->inum = -i-1;
initlock(&ip->lock, "icache-lock"); initlock(&ip->lock, "icache-lock");
initcondvar(&ip->cv, "icache-cv"); initcondvar(&ip->cv, "icache-cv");
ns_insert(ins, ip->inum, ip); ns_insert(ins, KII(ip->dev, ip->inum), ip);
} }
} }
...@@ -205,7 +205,7 @@ iupdate(struct inode *ip) ...@@ -205,7 +205,7 @@ iupdate(struct inode *ip)
} }
static void * static void *
evict(uint key, void *p) evict(void *vkey, void *p)
{ {
struct inode *ip = p; struct inode *ip = p;
acquire(&ip->lock); acquire(&ip->lock);
...@@ -230,9 +230,8 @@ iget(uint dev, uint inum) ...@@ -230,9 +230,8 @@ iget(uint dev, uint inum)
retry: retry:
// Try for cached inode. // Try for cached inode.
rcu_begin_read(); rcu_begin_read();
ip = ns_lookup(ins, inum); // XXX ignore dev ip = ns_lookup(ins, KII(dev, inum));
if (ip) { if (ip) {
if (ip->dev != dev) panic("iget dev mismatch");
// tricky: first bump ref, then check free flag // tricky: first bump ref, then check free flag
__sync_fetch_and_add(&ip->ref, 1); __sync_fetch_and_add(&ip->ref, 1);
if (ip->flags & I_FREE) { if (ip->flags & I_FREE) {
...@@ -265,7 +264,7 @@ iget(uint dev, uint inum) ...@@ -265,7 +264,7 @@ iget(uint dev, uint inum)
goto retry_evict; goto retry_evict;
} }
release(&victim->lock); release(&victim->lock);
ns_remove(ins, victim->inum, victim); ns_remove(ins, KII(victim->dev, victim->inum), victim);
rcu_delayed(victim, kmfree); rcu_delayed(victim, kmfree);
ip = kmalloc(sizeof(*ip)); ip = kmalloc(sizeof(*ip));
...@@ -277,7 +276,7 @@ iget(uint dev, uint inum) ...@@ -277,7 +276,7 @@ iget(uint dev, uint inum)
snprintf(ip->lockname, sizeof(ip->lockname), "cv:ino:%d", ip->inum); snprintf(ip->lockname, sizeof(ip->lockname), "cv:ino:%d", ip->inum);
initlock(&ip->lock, ip->lockname+3); initlock(&ip->lock, ip->lockname+3);
initcondvar(&ip->cv, ip->lockname); initcondvar(&ip->cv, ip->lockname);
if (ns_insert(ins, ip->inum, ip) < 0) { if (ns_insert(ins, KII(ip->dev, ip->inum), ip) < 0) {
rcu_delayed(ip, kmfree); rcu_delayed(ip, kmfree);
goto retry; goto retry;
} }
......
...@@ -2,12 +2,9 @@ ...@@ -2,12 +2,9 @@
// file-system name cache // file-system name cache
// //
// to do: // to do:
// use ns.c namespaces // eviction
// maybe generation #s don't need to be in on-disk inode // maybe generation #s don't need to be in on-disk inode
// if namecache only referred to cached inodes // if namecache only referred to cached inodes
// insert when file created, not just looked up
// eviction
// verify that it hits when it is supposed to
// //
#include "types.h" #include "types.h"
...@@ -24,66 +21,39 @@ ...@@ -24,66 +21,39 @@
#include "file.h" #include "file.h"
struct spinlock nc_lock; struct spinlock nc_lock;
struct ns *ncns;
// map the tuple <dev,dinum,name> to cinum; // map the tuple <dev,dinum,name> to cinum;
struct nce { struct nce {
int valid;
uint dev;
uint dinum; // directory inumber
char name[DIRSIZ];
uint cinum; // child inumber uint cinum; // child inumber
uint gen; // child ip->gen uint gen; // child ip->gen
}; };
#define NCE 128
struct nce nce[NCE];
void void
nc_init() nc_init()
{ {
ncns = nsalloc(0);
initlock(&nc_lock, "namecache"); initlock(&nc_lock, "namecache");
} }
// nc_lock must be held
struct nce *
nc_lookup1(struct inode *dir, char *name)
{
for(int i = 0; i < NCE; i++){
struct nce *e = &nce[i];
if(e->valid && e->dev == dir->dev && e->dinum == dir->inum &&
namecmp(name, e->name) == 0){
return e;
}
}
return 0;
}
struct inode * struct inode *
nc_lookup(struct inode *dir, char *name) nc_lookup(struct inode *dir, char *name)
{ {
uint inum = 0; rcu_begin_read();
uint gen = 0; struct nce *e = ns_lookup(ncns, KIIS(dir->dev, dir->inum, name));
if (!e)
acquire(&nc_lock); return 0;
struct nce *e = nc_lookup1(dir, name);
if(e){
inum = e->cinum;
gen = e->gen;
}
release(&nc_lock);
if(inum){ struct inode *ip = iget(dir->dev, e->cinum);
struct inode *ip = iget(dir->dev, inum); // this is a bit ugly
// this is a bit ugly // maybe there should be a real inode cache and
// maybe there should be a real inode cache and // the namecache should contain direct refs.
// the namecache should contain direct refs. int ok = (ip->gen == e->gen);
int ok = (ip->gen == gen); rcu_end_read();
if(ok){ if(ok){
return ip; return ip;
} else {
iput(ip);
return 0;
}
} else { } else {
iput(ip);
return 0; return 0;
} }
} }
...@@ -95,43 +65,26 @@ nc_insert(struct inode *dir, char *name, struct inode *ip) ...@@ -95,43 +65,26 @@ nc_insert(struct inode *dir, char *name, struct inode *ip)
// though ip is not locked, it's still OK to // though ip is not locked, it's still OK to
// look at ip->gen. // look at ip->gen.
acquire(&nc_lock); rcu_begin_read();
struct nce *e = ns_lookup(ncns, KIIS(dir->dev, dir->inum, name));
struct nce *e = nc_lookup1(dir, name);
if(e){ if(e){
if(e->cinum != ip->inum || e->gen != ip->gen){ if(e->cinum != ip->inum || e->gen != ip->gen){
// someone forgot to call nc_invalidate() // someone forgot to call nc_invalidate()
panic("nc_insert change"); panic("nc_insert change");
} }
release(&nc_lock); rcu_end_read();
return; return;
} }
rcu_end_read();
int i; e = kmalloc(sizeof(*e));
for(i = 0; i < NCE; i++){ e->cinum = ip->inum;
e = &nce[i]; e->gen = ip->gen;
if(e->valid == 0){ ns_insert(ncns, KIIS(dir->dev, dir->inum, name), e);
e->valid = 1;
e->dev = dir->dev;
e->dinum = dir->inum;
strncpy(e->name, name, DIRSIZ);
e->cinum = ip->inum;
e->gen = ip->gen;
break;
}
}
if(i >= NCE)
cprintf("namecache full\n");
release(&nc_lock);
} }
void void
nc_invalidate(struct inode *dir, char *name) nc_invalidate(struct inode *dir, char *name)
{ {
acquire(&nc_lock); ns_remove(ncns, KIIS(dir->dev, dir->inum, name), 0);
struct nce *e = nc_lookup1(dir, name);
if(e)
e->valid = 0;
release(&nc_lock);
} }
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
#include "defs.h" #include "defs.h"
#include "spinlock.h" #include "spinlock.h"
#include "param.h" #include "param.h"
#include <stddef.h>
// name spaces // name spaces
// XXX maybe use open hash table, no chain, better cache locality // XXX maybe use open hash table, no chain, better cache locality
...@@ -13,10 +14,22 @@ ...@@ -13,10 +14,22 @@
#endif #endif
struct elem { struct elem {
uint key;
void *val; void *val;
int next_lock; int next_lock;
struct elem * volatile next; struct elem * volatile next;
union {
uint ikey;
struct {
uint a;
uint b;
} iikey;
char skey[0];
struct {
uint a;
uint b;
char s[0];
} iiskey;
};
}; };
struct bucket { struct bucket {
...@@ -50,16 +63,94 @@ nsalloc(int allowdup) ...@@ -50,16 +63,94 @@ nsalloc(int allowdup)
} }
static struct elem * static struct elem *
elemalloc(void) elemalloc(struct nskey *k)
{ {
struct elem *e = 0; struct elem *e = 0;
e = kmalloc(sizeof(struct elem)); int sz;
switch (k->type) {
case nskey_int:
sz = offsetof(struct elem, ikey) + sizeof(e->ikey);
break;
case nskey_ii:
sz = offsetof(struct elem, iikey) + sizeof(e->iikey);
break;
case nskey_str:
sz = offsetof(struct elem, skey) + strlen(k->u.s) + 1;
break;
case nskey_iis:
sz = offsetof(struct elem, iiskey.s) + strlen(k->u.iis.s) + 1;
break;
default:
panic("key type");
}
e = kmalloc(sz);
if (e == 0) if (e == 0)
return 0; return 0;
memset(e, 0, sizeof(struct elem)); memset(e, 0, sz);
return e; return e;
} }
static int
h(struct nskey *k)
{
switch (k->type) {
case nskey_int:
return k->u.i % NHASH;
case nskey_ii:
return (k->u.ii.a ^ k->u.ii.b) % NHASH;
case nskey_str:
return k->u.s[0] % NHASH; // XXX
case nskey_iis:
return (k->u.iis.a ^ k->u.iis.b ^ k->u.iis.s[0]) % NHASH;
default:
panic("key type");
}
}
static void
setkey(struct elem *e, struct nskey *k)
{
switch (k->type) {
case nskey_int:
e->ikey = k->u.i;
break;
case nskey_ii:
e->iikey.a = k->u.ii.a;
e->iikey.b = k->u.ii.b;
break;
case nskey_str:
strncpy(e->skey, k->u.s, strlen(k->u.s) + 1);
break;
case nskey_iis:
e->iiskey.a = k->u.iis.a;
e->iiskey.b = k->u.iis.b;
strncpy(e->iiskey.s, k->u.iis.s, strlen(k->u.iis.s) + 1);
break;
default:
panic("key type");
}
}
static int
cmpkey(struct elem *e, struct nskey *k)
{
switch (k->type) {
case nskey_int:
return e->ikey == k->u.i;
case nskey_ii:
return e->iikey.a == k->u.ii.a && e->iikey.b == k->u.ii.b;
case nskey_str:
return !strcmp(e->skey, k->u.s);
case nskey_iis:
return e->iiskey.a == k->u.iis.a &&
e->iiskey.b == k->u.iis.b &&
!strcmp(e->iiskey.s, k->u.iis.s);
default:
panic("key type");
}
}
// XXX need something more scalable; partition the name space? // XXX need something more scalable; partition the name space?
int int
ns_allockey(struct ns *ns) ns_allockey(struct ns *ns)
...@@ -69,13 +160,13 @@ ns_allockey(struct ns *ns) ...@@ -69,13 +160,13 @@ ns_allockey(struct ns *ns)
} }
int int
ns_insert(struct ns *ns, uint key, void *val) ns_insert(struct ns *ns, struct nskey key, void *val)
{ {
struct elem *e = elemalloc(); struct elem *e = elemalloc(&key);
if (e) { if (e) {
e->key = key; setkey(e, &key);
e->val = val; e->val = val;
uint i = key % NHASH; uint i = h(&key);
rcu_begin_write(0); rcu_begin_write(0);
retry: retry:
...@@ -83,7 +174,7 @@ ns_insert(struct ns *ns, uint key, void *val) ...@@ -83,7 +174,7 @@ ns_insert(struct ns *ns, uint key, void *val)
struct elem *root = ns->table[i].chain; struct elem *root = ns->table[i].chain;
if (!ns->allowdup) { if (!ns->allowdup) {
for (struct elem *x = root; x; x = x->next) { for (struct elem *x = root; x; x = x->next) {
if (x->key == key) { if (cmpkey(x, &key)) {
rcu_end_write(0); rcu_end_write(0);
rcu_delayed(e, kmfree); rcu_delayed(e, kmfree);
return -1; return -1;
...@@ -102,15 +193,15 @@ ns_insert(struct ns *ns, uint key, void *val) ...@@ -102,15 +193,15 @@ ns_insert(struct ns *ns, uint key, void *val)
} }
void* void*
ns_lookup(struct ns *ns, uint key) ns_lookup(struct ns *ns, struct nskey key)
{ {
uint i = key % NHASH; uint i = h(&key);
rcu_begin_read(); rcu_begin_read();
struct elem *e = ns->table[i].chain; struct elem *e = ns->table[i].chain;
while (e != NULL) { while (e != NULL) {
if (e->key == key) { if (cmpkey(e, &key)) {
rcu_end_read(); rcu_end_read();
return e->val; return e->val;
} }
...@@ -122,9 +213,9 @@ ns_lookup(struct ns *ns, uint key) ...@@ -122,9 +213,9 @@ ns_lookup(struct ns *ns, uint key)
} }
int int
ns_remove(struct ns *ns, uint key, void *v) ns_remove(struct ns *ns, struct nskey key, void *v)
{ {
uint i = key % NHASH; uint i = h(&key);
rcu_begin_write(0); rcu_begin_write(0);
retry: retry:
...@@ -138,7 +229,7 @@ ns_remove(struct ns *ns, uint key, void *v) ...@@ -138,7 +229,7 @@ ns_remove(struct ns *ns, uint key, void *v)
if (!e) if (!e)
break; break;
if (e->key == key && (e->val == v || v == 0)) { if (cmpkey(e, &key) && (e->val == v || v == 0)) {
// XXX annotate as locks for mtrace // XXX annotate as locks for mtrace
if (!__sync_bool_compare_and_swap(&e->next_lock, 0, 1)) if (!__sync_bool_compare_and_swap(&e->next_lock, 0, 1))
goto retry; goto retry;
...@@ -166,13 +257,13 @@ ns_remove(struct ns *ns, uint key, void *v) ...@@ -166,13 +257,13 @@ ns_remove(struct ns *ns, uint key, void *v)
} }
void * void *
ns_enumerate(struct ns *ns, void *(*f)(uint, void *)) ns_enumerate(struct ns *ns, void *(*f)(void *, void *))
{ {
rcu_begin_read(); rcu_begin_read();
for (int i = 0; i < NHASH; i++) { for (int i = 0; i < NHASH; i++) {
struct elem *e = ns->table[i].chain; struct elem *e = ns->table[i].chain;
while (e != NULL) { while (e != NULL) {
void *r = (*f)(e->key, e->val); void *r = (*f)(&e->ikey, e->val);
if (r) { if (r) {
rcu_end_read(); rcu_end_read();
return r; return r;
...@@ -185,13 +276,13 @@ ns_enumerate(struct ns *ns, void *(*f)(uint, void *)) ...@@ -185,13 +276,13 @@ ns_enumerate(struct ns *ns, void *(*f)(uint, void *))
} }
void * void *
ns_enumerate_key(struct ns *ns, uint key, void *(*f)(void *)) ns_enumerate_key(struct ns *ns, struct nskey key, void *(*f)(void *))
{ {
uint i = key % NHASH; uint i = h(&key);
rcu_begin_read(); rcu_begin_read();
struct elem *e = ns->table[i].chain; struct elem *e = ns->table[i].chain;
while (e) { while (e) {
if (e->key == key) { if (cmpkey(e, &key)) {
void *r = (*f)(e->val); void *r = (*f)(e->val);
if (r) { if (r) {
rcu_end_read(); rcu_end_read();
......
...@@ -63,12 +63,12 @@ allocproc(void) ...@@ -63,12 +63,12 @@ allocproc(void)
initlock(&p->lock, p->lockname+3); initlock(&p->lock, p->lockname+3);
initcondvar(&p->cv, p->lockname); initcondvar(&p->cv, p->lockname);
if (ns_insert(nspid, p->pid, (void *) p) < 0) if (ns_insert(nspid, KI(p->pid), (void *) p) < 0)
panic("allocproc: ns_insert"); panic("allocproc: ns_insert");
// Allocate kernel stack if possible. // Allocate kernel stack if possible.
if((p->kstack = kalloc()) == 0){ if((p->kstack = kalloc()) == 0){
if (ns_remove(nspid, p->pid, p) < 0) if (ns_remove(nspid, KI(p->pid), p) < 0)
panic("allocproc: ns_remove"); panic("allocproc: ns_remove");
rcu_delayed(p, kmfree); rcu_delayed(p, kmfree);
return 0; return 0;
...@@ -109,7 +109,7 @@ addrun(struct proc *p) ...@@ -109,7 +109,7 @@ addrun(struct proc *p)
if (p->on_runq >= 0) if (p->on_runq >= 0)
panic("addrun on runq already"); panic("addrun on runq already");
ns_insert(nsrunq, p->cpuid, p); ns_insert(nsrunq, KI(p->cpuid), p);
p->on_runq = p->cpuid; p->on_runq = p->cpuid;
} }
...@@ -123,7 +123,7 @@ delrun(struct proc *p) ...@@ -123,7 +123,7 @@ delrun(struct proc *p)
if (p->on_runq < 0) if (p->on_runq < 0)
panic("delrun not on runq"); panic("delrun not on runq");
if (ns_remove(nsrunq, p->on_runq, p) < 0) if (ns_remove(nsrunq, KI(p->on_runq), p) < 0)
panic("delrun: ns_remove"); panic("delrun: ns_remove");
p->on_runq = -1; p->on_runq = -1;
} }
...@@ -269,7 +269,7 @@ fork(int flags) ...@@ -269,7 +269,7 @@ fork(int flags)
kfree(np->kstack); kfree(np->kstack);
np->kstack = 0; np->kstack = 0;
np->state = UNUSED; np->state = UNUSED;
if (ns_remove(nspid, np->pid, np) < 0) if (ns_remove(nspid, KI(np->pid), np) < 0)
panic("fork: ns_remove"); panic("fork: ns_remove");
rcu_delayed(np, kmfree); rcu_delayed(np, kmfree);
return -1; return -1;
...@@ -384,7 +384,7 @@ wait(void) ...@@ -384,7 +384,7 @@ wait(void)
p->kstack = 0; p->kstack = 0;
vmap_decref(p->vmap); vmap_decref(p->vmap);
p->state = UNUSED; p->state = UNUSED;
if (ns_remove(nspid, p->pid, p) < 0) if (ns_remove(nspid, KI(p->pid), p) < 0)
panic("wait: ns_remove"); panic("wait: ns_remove");
p->pid = 0; p->pid = 0;
p->parent = 0; p->parent = 0;
...@@ -445,7 +445,7 @@ migrate(struct proc *p) ...@@ -445,7 +445,7 @@ migrate(struct proc *p)
} }
static void * static void *
steal_cb(uint k, void *v) steal_cb(void *vk, void *v)
{ {
struct proc *p = v; struct proc *p = v;
...@@ -514,7 +514,7 @@ scheduler(void) ...@@ -514,7 +514,7 @@ scheduler(void)
// Enable interrupts on this processor. // Enable interrupts on this processor.
sti(); sti();
struct proc *p = ns_enumerate_key(nsrunq, cpu->id, choose_runnable); struct proc *p = ns_enumerate_key(nsrunq, KI(cpu->id), choose_runnable);
if (p) { if (p) {
acquire(&p->lock); acquire(&p->lock);
if (p->state != RUNNABLE) { if (p->state != RUNNABLE) {
...@@ -630,7 +630,7 @@ kill(int pid) ...@@ -630,7 +630,7 @@ kill(int pid)
{ {
struct proc *p; struct proc *p;
p = (struct proc *) ns_lookup(nspid, pid); p = (struct proc *) ns_lookup(nspid, KI(pid));
if (p == 0) { if (p == 0) {
panic("kill"); panic("kill");
return -1; return -1;
...@@ -653,7 +653,7 @@ kill(int pid) ...@@ -653,7 +653,7 @@ kill(int pid)
return 0; return 0;
} }
void *procdump(uint k, void *v) void *procdump(void *vk, void *v)
{ {
struct proc *p = (struct proc *) v; struct proc *p = (struct proc *) v;
......
...@@ -22,7 +22,7 @@ struct rcu { ...@@ -22,7 +22,7 @@ struct rcu {
int arg1; int arg1;
uint arg2; uint arg2;
} f2; } f2;
} u; };
int type; int type;
}; };
static struct { struct rcu *x __attribute__((aligned (CACHELINE))); } rcu_delayed_head[NCPU]; static struct { struct rcu *x __attribute__((aligned (CACHELINE))); } rcu_delayed_head[NCPU];
...@@ -48,7 +48,7 @@ rcu_alloc() ...@@ -48,7 +48,7 @@ rcu_alloc()
} }
void * void *
rcu_min(uint key, void *v){ rcu_min(void *vkey, void *v){
struct proc *p = (struct proc *) v; struct proc *p = (struct proc *) v;
if (min_epoch[cpu->id].x > p->epoch) { if (min_epoch[cpu->id].x > p->epoch) {
min_epoch[cpu->id].x = p->epoch; min_epoch[cpu->id].x = p->epoch;
...@@ -76,10 +76,10 @@ rcu_gc(void) ...@@ -76,10 +76,10 @@ rcu_gc(void)
// cprintf("free: %d (%x %x)\n", r->epoch, r->dofree, r->item); // cprintf("free: %d (%x %x)\n", r->epoch, r->dofree, r->item);
switch (r->type) { switch (r->type) {
case 1: case 1:
r->u.f1.dofree(r->u.f1.item); r->f1.dofree(r->f1.item);
break; break;
case 2: case 2:
r->u.f2.dofree(r->u.f2.arg1, r->u.f2.arg2); r->f2.dofree(r->f2.arg1, r->f2.arg2);
break; break;
default: default:
panic("rcu type"); panic("rcu type");
...@@ -93,8 +93,9 @@ rcu_gc(void) ...@@ -93,8 +93,9 @@ rcu_gc(void)
kmfree(r); kmfree(r);
} }
release(&rcu_lock[cpu->id].l); release(&rcu_lock[cpu->id].l);
// cprintf("rcu_gc: cpu %d n %d delayed_nfree=%d min_epoch=%d\n", if (rcu_debug)
// cpu->id, n, delayed_nfree[cpu->id], min_epoch[cpu->id]); 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(); popcli();
// global_epoch can be bumped anywhere; this seems as good a place as any // global_epoch can be bumped anywhere; this seems as good a place as any
...@@ -124,15 +125,15 @@ rcu_delayed(void *e, void (*dofree)(void *)) ...@@ -124,15 +125,15 @@ rcu_delayed(void *e, void (*dofree)(void *))
if (rcu_debug) { if (rcu_debug) {
cprintf("rcu_delayed: %x %x\n", dofree, e); cprintf("rcu_delayed: %x %x\n", dofree, e);
for (struct rcu *r = rcu_delayed_head[cpu->id].x; r; r = r->next) for (struct rcu *r = rcu_delayed_head[cpu->id].x; r; r = r->next)
if (r->u.f1.item == e && r->u.f1.dofree == dofree) if (r->f1.item == e && r->f1.dofree == dofree)
panic("rcu_delayed double free"); panic("rcu_delayed double free");
} }
struct rcu *r = rcu_alloc(); struct rcu *r = rcu_alloc();
if (r == 0) if (r == 0)
panic("rcu_delayed"); panic("rcu_delayed");
r->u.f1.dofree = dofree; r->f1.dofree = dofree;
r->u.f1.item = e; r->f1.item = e;
r->next = 0; r->next = 0;
r->epoch = global_epoch; r->epoch = global_epoch;
r->type = 1; r->type = 1;
...@@ -145,9 +146,9 @@ rcu_delayed2(int a1, uint a2, void (*dofree)(int,uint)) ...@@ -145,9 +146,9 @@ rcu_delayed2(int a1, uint a2, void (*dofree)(int,uint))
struct rcu *r = rcu_alloc(); struct rcu *r = rcu_alloc();
if (r == 0) if (r == 0)
panic("rcu_delayed"); panic("rcu_delayed");
r->u.f2.dofree = dofree; r->f2.dofree = dofree;
r->u.f2.arg1 = a1; r->f2.arg1 = a1;
r->u.f2.arg2 = a2; r->f2.arg2 = a2;
r->next = 0; r->next = 0;
r->epoch = global_epoch; r->epoch = global_epoch;
r->type = 2; r->type = 2;
......
...@@ -99,3 +99,11 @@ strlen(const char *s) ...@@ -99,3 +99,11 @@ strlen(const char *s)
return n; return n;
} }
int
strcmp(const char *p, const char *q)
{
while(*p && *p == *q)
p++, q++;
return (uchar)*p - (uchar)*q;
}
...@@ -135,6 +135,8 @@ sys_link(void) ...@@ -135,6 +135,8 @@ sys_link(void)
iunlockput(dp); iunlockput(dp);
goto bad; goto bad;
} }
nc_insert(dp, name, ip);
iunlockput(dp); iunlockput(dp);
iput(ip); iput(ip);
return 0; return 0;
...@@ -258,6 +260,7 @@ create(char *path, short type, short major, short minor) ...@@ -258,6 +260,7 @@ create(char *path, short type, short major, short minor)
if(dirlink(dp, name, ip->inum) < 0) if(dirlink(dp, name, ip->inum) < 0)
panic("create: dirlink"); panic("create: dirlink");
nc_insert(dp, name, ip);
iunlockput(dp); iunlockput(dp);
return ip; return ip;
} }
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论