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

use a namespace for pids

very primitive and unscalable
上级 31066c21
...@@ -27,6 +27,7 @@ OBJS = \ ...@@ -27,6 +27,7 @@ OBJS = \
uart.o\ uart.o\
vectors.o\ vectors.o\
vm.o\ vm.o\
ns.o
# Cross-compiling (e.g., on Mac OS X) # Cross-compiling (e.g., on Mac OS X)
TOOLPREFIX = x86_64-jos-elf- TOOLPREFIX = x86_64-jos-elf-
......
...@@ -8,6 +8,7 @@ struct spinlock; ...@@ -8,6 +8,7 @@ struct spinlock;
struct condvar; struct condvar;
struct stat; struct stat;
struct vmnode; struct vmnode;
struct ns;
// bio.c // bio.c
void binit(void); void binit(void);
...@@ -93,6 +94,14 @@ int mpbcpu(void); ...@@ -93,6 +94,14 @@ int mpbcpu(void);
void mpinit(void); void mpinit(void);
void mpstartthem(void); void mpstartthem(void);
// ns.c
void nsinit(void);
struct ns* nsalloc(void);
int ns_allockey(struct ns*);
int ns_insert(struct ns*, int key, void*);
void* ns_lookup(struct ns*, int);
int ns_remove(struct ns *ns, int key);
// picirq.c // picirq.c
void picenable(int); void picenable(int);
void picinit(void); void picinit(void);
......
...@@ -50,6 +50,7 @@ mainc(void) ...@@ -50,6 +50,7 @@ mainc(void)
consoleinit(); // I/O devices & their interrupts consoleinit(); // I/O devices & their interrupts
uartinit(); // serial port uartinit(); // serial port
kvmalloc(); // initialize the kernel page table kvmalloc(); // initialize the kernel page table
nsinit(); // initialize name space module
pinit(); // process table pinit(); // process table
tvinit(); // trap vectors tvinit(); // trap vectors
binit(); // buffer cache binit(); // buffer cache
......
#include "types.h"
#include "defs.h"
#include "spinlock.h"
#include "queue.h"
// name spaces
#define NHASH 100
// XXX cache align
struct elem {
int key;
void *val;
TAILQ_ENTRY(elem) chain;
};
struct bucket {
TAILQ_HEAD(elist, elem) chain;
};
struct ns {
int used;
int nextkey;
struct bucket table[NHASH];
struct spinlock lock;
};
struct spinlock ns_lock;
void
nsinit(void)
{
initlock(&ns_lock, "nstable");
}
// XXX should be using our missing scalable allocator module
struct ns*
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));
for (int i = 0; i < NHASH; i++) {
TAILQ_INIT(&ns->table[i].chain);
}
release(&ns_lock);
return ns;
}
static struct elem *
elemalloc(void)
{
struct elem *e = 0;
e = kmalloc(sizeof(struct elem));
if (e == 0)
return 0;
memset(e, 0, sizeof(struct elem));
return e;
}
// XXX need something more scalable; partition the name space?
int
ns_allockey(struct ns *ns)
{
int n = __sync_fetch_and_add(&ns->nextkey, 1);
return n;
}
int
ns_insert(struct ns *ns, int key, void *val)
{
int r = -1;
acquire(&ns->lock);
struct elem *e = elemalloc();
if (e) {
e->key = key;
e->val = val;
uint i = key % NHASH;
TAILQ_INSERT_TAIL(&(ns->table[i].chain), e, chain);
r = 0;
}
release(&ns->lock);
return r;
}
static struct elem*
ns_dolookup(struct ns *ns, int key)
{
struct elem *e = TAILQ_FIRST(&(ns->table[key % NHASH].chain));
while (e != NULL) {
if (e->key == key) {
return e;
}
e = TAILQ_NEXT(e, chain);
}
return 0;
}
void*
ns_lookup(struct ns *ns, int key)
{
acquire(&ns->lock);
struct elem *e = ns_dolookup(ns, key);
release(&ns->lock);
return (e == 0)? 0 : e->val;
}
int
ns_remove(struct ns *ns, int key)
{
int r = -1;
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);
return r;
}
...@@ -13,6 +13,7 @@ struct ptable ptables[NCPU]; ...@@ -13,6 +13,7 @@ struct ptable ptables[NCPU];
struct runq runqs[NCPU]; struct runq runqs[NCPU];
int idle[NCPU]; int idle[NCPU];
static struct proc *initproc; static struct proc *initproc;
static struct ns *nspid;
extern void forkret(void); extern void forkret(void);
extern void trapret(void); extern void trapret(void);
...@@ -22,6 +23,10 @@ pinit(void) ...@@ -22,6 +23,10 @@ pinit(void)
{ {
int c; int c;
nspid = nsalloc();
if (nspid == 0)
panic("pinit");
for (c = 0; c < NCPU; c++) { for (c = 0; c < NCPU; c++) {
idle[c] = 1; idle[c] = 1;
...@@ -56,7 +61,10 @@ allocproc(void) ...@@ -56,7 +61,10 @@ allocproc(void)
initcondvar(&p->cv, "proc"); initcondvar(&p->cv, "proc");
p->state = EMBRYO; p->state = EMBRYO;
p->pid = ptable->nextpid++; // p->pid = ptable->nextpid++;
p->pid = ns_allockey(nspid);
if (ns_insert(nspid, p->pid, (void *) p) < 0)
panic("allocproc: ns_insert");
p->cpuid = cpu->id; p->cpuid = cpu->id;
// Allocate kernel stack if possible. // Allocate kernel stack if possible.
...@@ -373,6 +381,8 @@ wait(void) ...@@ -373,6 +381,8 @@ 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) < 0)
panic("wait: ns_remove");
p->pid = 0; p->pid = 0;
p->parent = 0; p->parent = 0;
p->name[0] = 0; p->name[0] = 0;
...@@ -573,38 +583,29 @@ forkret(void) ...@@ -573,38 +583,29 @@ forkret(void)
int int
kill(int pid) kill(int pid)
{ {
// struct proc *p; struct proc *p;
int c;
for (c = 0; c < NCPU; c++) { p = (struct proc *) ns_lookup(nspid, pid);
acquire(&ptables[c].lock); if (p == 0) {
#if 0 panic("kill");
for(p = ptables[c].proc; p < &ptables[c].proc[NPROC]; p++){ return -1;
acquire(&p->lock); }
if(p->pid == pid){ acquire(&p->lock);
p->killed = 1; p->killed = 1;
if(p->state == SLEEPING){ if(p->state == SLEEPING){
// XXX // XXX
// we need to wake p up if it is cv_sleep()ing. // we need to wake p up if it is cv_sleep()ing.
// can't change p from SLEEPING to RUNNABLE since that // can't change p from SLEEPING to RUNNABLE since that
// would make some condvar->waiters a dangling reference, // would make some condvar->waiters a dangling reference,
// and the non-zero p->cv_next will cause a future panic. // and the non-zero p->cv_next will cause a future panic.
// can't call cv_wakeup(p->oncv) since that results in // can't call cv_wakeup(p->oncv) since that results in
// deadlock (addrun() acquires p->lock). // deadlock (addrun() acquires p->lock).
// can't release p->lock then call cv_wakeup() since the // can't release p->lock then call cv_wakeup() since the
// cv might be deallocated while we're using it // cv might be deallocated while we're using it
// (pipes dynamically allocate condvars). // (pipes dynamically allocate condvars).
}
release(&p->lock);
release(&ptables[c].lock);
return 0;
}
release(&p->lock);
}
#endif
release(&ptables[c].lock);
} }
return -1; release(&p->lock);
return 0;
} }
//PAGEBREAK: 36 //PAGEBREAK: 36
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论