Skip to content
Snippets Groups Projects
Commit 020c8e23 authored by Robert Morris's avatar Robert Morris
Browse files

use acquire/release to force order for pid=np->pid;np->state=RUNNING

for bug reported by symingz@gmail.com and cs1100254@cse.iitd.ernet.in
parent 86188d9d
No related branches found
No related tags found
No related merge requests found
......@@ -116,21 +116,25 @@ processors will need it.
---
The code in fork needs to read np->pid before
setting np->state to RUNNABLE.
setting np->state to RUNNABLE. The following
is not a correct way to do this:
int
fork(void)
{
...
pid = np->pid;
np->state = RUNNABLE;
return pid;
return np->pid; // oops
}
After setting np->state to RUNNABLE, some other CPU
might run the process, it might exit, and then it might
get reused for a different process (with a new pid), all
before the return statement. So it's not safe to just do
"return np->pid;".
This works because proc.h marks the pid as volatile.
before the return statement. So it's not safe to just
"return np->pid". Even saving a copy of np->pid before
setting np->state isn't safe, since the compiler is
allowed to re-order statements.
The real code saves a copy of np->pid, then acquires a lock
around the write to np->state. The acquire() prevents the
compiler from re-ordering.
......@@ -153,10 +153,16 @@ fork(void)
if(proc->ofile[i])
np->ofile[i] = filedup(proc->ofile[i]);
np->cwd = idup(proc->cwd);
safestrcpy(np->name, proc->name, sizeof(proc->name));
pid = np->pid;
// lock to force the compiler to emit the np->state write last.
acquire(&ptable.lock);
np->state = RUNNABLE;
safestrcpy(np->name, proc->name, sizeof(proc->name));
release(&ptable.lock);
return pid;
}
......@@ -455,5 +461,3 @@ procdump(void)
cprintf("\n");
}
}
......@@ -57,7 +57,7 @@ struct proc {
pde_t* pgdir; // Page table
char *kstack; // Bottom of kernel stack for this process
enum procstate state; // Process state
volatile int pid; // Process ID
int pid; // Process ID
struct proc *parent; // Parent process
struct trapframe *tf; // Trap frame for current syscall
struct context *context; // swtch() here to run process
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment