summaryrefslogtreecommitdiff
path: root/proc.c
diff options
context:
space:
mode:
authorrtm <rtm>2006-07-15 12:03:57 +0000
committerrtm <rtm>2006-07-15 12:03:57 +0000
commit46bbd72f3eeaff9386b2a90af88f3d46b458a0e8 (patch)
tree31ca93c160a10c50948329b30d27475aa6b38313 /proc.c
parentd9872ffa951291fcc3f7a92c0d235b86435c5714 (diff)
downloadxv6-labs-46bbd72f3eeaff9386b2a90af88f3d46b458a0e8.tar.gz
xv6-labs-46bbd72f3eeaff9386b2a90af88f3d46b458a0e8.tar.bz2
xv6-labs-46bbd72f3eeaff9386b2a90af88f3d46b458a0e8.zip
no more recursive locks
wakeup1() assumes you hold proc_table_lock sleep(chan, lock) provides atomic sleep-and-release to wait for condition ugly code in swtch/scheduler to implement new sleep fix lots of bugs in pipes, wait, and exit fix bugs if timer interrupt goes off in schedule() console locks per line, not per byte
Diffstat (limited to 'proc.c')
-rw-r--r--proc.c75
1 files changed, 52 insertions, 23 deletions
diff --git a/proc.c b/proc.c
index 0e35540..e69f1d1 100644
--- a/proc.c
+++ b/proc.c
@@ -95,7 +95,6 @@ newproc()
np->tf = (struct Trapframe *) (np->kstack + KSTACKSIZE - sizeof(struct Trapframe));
*(np->tf) = *(op->tf);
np->tf->tf_regs.reg_eax = 0; // so fork() returns 0 in child
- cprintf("newproc pid=%d return to %x:%x tf-%p\n", np->pid, np->tf->tf_cs, np->tf->tf_eip, np->tf);
// set up new jmpbuf to start executing at trapret with esp pointing at tf
memset(&np->jmpbuf, 0, sizeof np->jmpbuf);
@@ -109,8 +108,6 @@ newproc()
fd_reference(np->fds[fd]);
}
- cprintf("newproc %x\n", np);
-
return np;
}
@@ -126,18 +123,27 @@ scheduler(void)
setjmp(&cpus[cpu()].jmpbuf);
op = curproc[cpu()];
+
+ if(op == 0 || op->mtx != &proc_table_lock)
+ acquire1(&proc_table_lock, op);
+
if(op){
if(op->newstate <= 0 || op->newstate > ZOMBIE)
panic("scheduler");
op->state = op->newstate;
op->newstate = -1;
+ if(op->mtx){
+ struct spinlock *mtx = op->mtx;
+ op->mtx = 0;
+ if(mtx != &proc_table_lock)
+ release1(mtx, op);
+ }
}
// find a runnable process and switch to it
curproc[cpu()] = 0;
np = cpus[cpu()].lastproc + 1;
while(1){
- acquire(&proc_table_lock);
for(i = 0; i < NPROC; i++){
if(np >= &proc[NPROC])
np = &proc[0];
@@ -148,11 +154,13 @@ scheduler(void)
if(i < NPROC){
np->state = RUNNING;
- release(&proc_table_lock);
+ release1(&proc_table_lock, op);
break;
}
- release(&proc_table_lock);
+ release1(&proc_table_lock, op);
+ op = 0;
+ acquire(&proc_table_lock);
np = &proc[0];
}
@@ -180,36 +188,56 @@ void
swtch(int newstate)
{
struct proc *p = curproc[cpu()];
+
if(p == 0)
panic("swtch no proc");
- if(p->locks != 0)
+ if(p->mtx == 0 && p->locks != 0)
panic("swtch w/ locks");
+ if(p->mtx && p->locks != 1)
+ panic("swtch w/ locks 1");
+ if(p->mtx && p->mtx->locked == 0)
+ panic("switch w/ lock but not held");
+ if(p->locks && (read_eflags() & FL_IF))
+ panic("swtch w/ lock but FL_IF");
+
p->newstate = newstate; // basically an argument to scheduler()
if(setjmp(&p->jmpbuf) == 0)
longjmp(&cpus[cpu()].jmpbuf);
}
void
-sleep(void *chan)
+sleep(void *chan, struct spinlock *mtx)
{
struct proc *p = curproc[cpu()];
+
if(p == 0)
panic("sleep");
+
p->chan = chan;
+ p->mtx = mtx; // scheduler will release it
+
swtch(WAITING);
+
+ if(mtx)
+ acquire(mtx);
+ p->chan = 0;
}
void
-wakeup(void *chan)
+wakeup1(void *chan)
{
struct proc *p;
- acquire(&proc_table_lock);
- for(p = proc; p < &proc[NPROC]; p++){
- if(p->state == WAITING && p->chan == chan){
+ for(p = proc; p < &proc[NPROC]; p++)
+ if(p->state == WAITING && p->chan == chan)
p->state = RUNNABLE;
- }
- }
+}
+
+void
+wakeup(void *chan)
+{
+ acquire(&proc_table_lock);
+ wakeup1(chan);
release(&proc_table_lock);
}
@@ -229,8 +257,6 @@ proc_exit()
struct proc *cp = curproc[cpu()];
int fd;
- cprintf("exit %x pid %d ppid %d\n", cp, cp->pid, cp->ppid);
-
for(fd = 0; fd < NOFILE; fd++){
if(cp->fds[fd]){
fd_close(cp->fds[fd]);
@@ -243,32 +269,35 @@ proc_exit()
// wake up parent
for(p = proc; p < &proc[NPROC]; p++)
if(p->pid == cp->ppid)
- wakeup(p);
+ wakeup1(p);
// abandon children
for(p = proc; p < &proc[NPROC]; p++)
if(p->ppid == cp->pid)
p->pid = 1;
-
- release(&proc_table_lock);
-
- // switch into scheduler
+
+ cp->mtx = &proc_table_lock;
swtch(ZOMBIE);
+ panic("a zombie revived");
}
// disable interrupts
void
cli(void)
{
- cpus[cpu()].clis += 1;
- if(cpus[cpu()].clis == 1)
+ if(cpus[cpu()].clis == 0)
__asm __volatile("cli");
+ cpus[cpu()].clis += 1;
+ if((read_eflags() & FL_IF) != 0)
+ panic("cli but enabled");
}
// enable interrupts
void
sti(void)
{
+ if((read_eflags() & FL_IF) != 0)
+ panic("sti but enabled");
if(cpus[cpu()].clis < 1)
panic("sti");
cpus[cpu()].clis -= 1;