Make it easy to reproduce the race

上级 2f894520
...@@ -44,6 +44,8 @@ typedef enum procstate { ...@@ -44,6 +44,8 @@ typedef enum procstate {
ZOMBIE ZOMBIE
} procstate_t;; } procstate_t;;
#define PROC_MAGIC 0xfeedfacedeadd00dULL
// Per-process state // Per-process state
struct proc : public rcu_freed, public sched_link { struct proc : public rcu_freed, public sched_link {
struct vmap *vmap; // va -> vma struct vmap *vmap; // va -> vma
...@@ -85,6 +87,7 @@ struct proc : public rcu_freed, public sched_link { ...@@ -85,6 +87,7 @@ struct proc : public rcu_freed, public sched_link {
std::atomic<int> exception_inuse; std::atomic<int> exception_inuse;
u8 exception_buf[256]; u8 exception_buf[256];
u64 magic;
static proc* alloc(); static proc* alloc();
void set_state(procstate_t s); void set_state(procstate_t s);
......
...@@ -136,6 +136,9 @@ gc_delayfreelist(void) ...@@ -136,6 +136,9 @@ gc_delayfreelist(void)
xnspid->enumerate([&min](u32, proc *p)->bool{ xnspid->enumerate([&min](u32, proc *p)->bool{
// Some threads may never call begin/end_epoch(), and never update // Some threads may never call begin/end_epoch(), and never update
// p->epoch, so gc_thread does it for them. // p->epoch, so gc_thread does it for them.
if (p->magic != PROC_MAGIC)
panic("gc_delayfreelist: no magic %lx\n", p->magic);
u64 x = p->epoch.load(); u64 x = p->epoch.load();
if (!(x & 0xff)) { if (!(x & 0xff)) {
cmpxch(&p->epoch, x, global_epoch.load() << 8); cmpxch(&p->epoch, x, global_epoch.load() << 8);
......
...@@ -42,7 +42,7 @@ proc::proc(int npid) : ...@@ -42,7 +42,7 @@ proc::proc(int npid) :
ftable(0), cwd(0), tsc(0), curcycles(0), cpuid(0), epoch(0), ftable(0), cwd(0), tsc(0), curcycles(0), cpuid(0), epoch(0),
cpu_pin(0), oncv(0), cv_wakeup(0), cpu_pin(0), oncv(0), cv_wakeup(0),
user_fs_(0), unmap_tlbreq_(0), in_exec_(0), uaccess_(0), user_fs_(0), unmap_tlbreq_(0), in_exec_(0), uaccess_(0),
exception_inuse(0), state_(EMBRYO) exception_inuse(0), magic(PROC_MAGIC), state_(EMBRYO)
{ {
snprintf(lockname, sizeof(lockname), "cv:proc:%d", pid); snprintf(lockname, sizeof(lockname), "cv:proc:%d", pid);
initlock(&lock, lockname+3, LOCKSTAT_PROC); initlock(&lock, lockname+3, LOCKSTAT_PROC);
...@@ -57,6 +57,7 @@ proc::proc(int npid) : ...@@ -57,6 +57,7 @@ proc::proc(int npid) :
proc::~proc(void) proc::~proc(void)
{ {
magic = 0;
if (kstack) if (kstack)
ksfree(slab_stack, kstack); ksfree(slab_stack, kstack);
destroylock(&lock); destroylock(&lock);
...@@ -410,6 +411,9 @@ finishproc(struct proc *p) ...@@ -410,6 +411,9 @@ finishproc(struct proc *p)
p->name[0] = 0; p->name[0] = 0;
p->killed = 0; p->killed = 0;
freeproc(p); freeproc(p);
#if DEBUG
gc_wakeup();
#endif
} }
// Wait for a child process to exit and return its pid. // Wait for a child process to exit and return its pid.
...@@ -433,15 +437,15 @@ wait(void) ...@@ -433,15 +437,15 @@ wait(void)
SLIST_REMOVE(&myproc()->childq, p, proc, child_next); SLIST_REMOVE(&myproc()->childq, p, proc, child_next);
release(&myproc()->lock); release(&myproc()->lock);
if (!xnspid->remove(pid, &p))
panic("wait: ns_remove");
cwork *w = new cwork(); cwork *w = new cwork();
assert(w); assert(w);
w->rip = (void*) finishproc; w->rip = (void*) finishproc;
w->arg0 = p; w->arg0 = p;
assert(wqcrit_push(w, p->run_cpuid_) >= 0); assert(wqcrit_push(w, p->run_cpuid_) >= 0);
if (!xnspid->remove(pid, &p))
panic("wait: ns_remove");
return pid; return pid;
} }
release(&p->lock); release(&p->lock);
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论