summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrtm <rtm>2006-07-12 15:35:33 +0000
committerrtm <rtm>2006-07-12 15:35:33 +0000
commit6eb6f10c5668bc2bdf5e561e0060e7e917ed55c1 (patch)
tree8245cefe266e75ca9836cbde2f86114cb6222fe4
parent8148b6ee535b85e97f3b5f3a850b70fdfbbcaf2d (diff)
downloadxv6-labs-6eb6f10c5668bc2bdf5e561e0060e7e917ed55c1.tar.gz
xv6-labs-6eb6f10c5668bc2bdf5e561e0060e7e917ed55c1.tar.bz2
xv6-labs-6eb6f10c5668bc2bdf5e561e0060e7e917ed55c1.zip
passes both usertests
exit had acquire where I meant release swtch now checks that you hold no locks
-rw-r--r--Notes23
-rw-r--r--proc.c18
-rw-r--r--proc.h1
-rw-r--r--spinlock.c15
-rw-r--r--trap.c4
-rw-r--r--usertests.c4
6 files changed, 34 insertions, 31 deletions
diff --git a/Notes b/Notes
index 8fab37d..b5f4035 100644
--- a/Notes
+++ b/Notes
@@ -114,26 +114,15 @@ wakeup needs proc_table_lock
so we need recursive locks?
or you must hold the lock to call wakeup?
-if locks contain proc *, they can't be used at interrupt time
- only proc_table_lock will be used at interrupt time?
- maybe it doesn't matter if we use curproc?
-
in general, the table locks protect both free-ness and
public variables of table elements
in many cases you can use table elements w/o a lock
e.g. if you are the process, or you are using an fd
-why can't i get a lock in console code?
- always triple fault
- because release turns on interrupts!
- a bad idea very early in main()
- but mp_init() calls cprintf
-
lock code shouldn't call cprintf...
-ide_init doesn't work now?
-and IOAPIC: read from unsupported address
- when running pre-empt user test
- so maybe something wrong with clock interrupts
- no! if one cpu holds lock w/ curproc0=,
- then another cpu can take it, it looks like
- a recursive acquire()
+
+nasty hack to allow locks before first process,
+ and to allow them in interrupts when curproc may be zero
+
+race between release and sleep in sys_wait()
+race between sys_exit waking up parent and setting state=ZOMBIE
diff --git a/proc.c b/proc.c
index 53469a1..0e35540 100644
--- a/proc.c
+++ b/proc.c
@@ -181,7 +181,9 @@ swtch(int newstate)
{
struct proc *p = curproc[cpu()];
if(p == 0)
- panic("swtch");
+ panic("swtch no proc");
+ if(p->locks != 0)
+ panic("swtch w/ locks");
p->newstate = newstate; // basically an argument to scheduler()
if(setjmp(&p->jmpbuf) == 0)
longjmp(&cpus[cpu()].jmpbuf);
@@ -203,9 +205,11 @@ wakeup(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;
+ }
+ }
release(&proc_table_lock);
}
@@ -225,7 +229,7 @@ proc_exit()
struct proc *cp = curproc[cpu()];
int fd;
- cprintf("exit %x\n", cp);
+ cprintf("exit %x pid %d ppid %d\n", cp, cp->pid, cp->ppid);
for(fd = 0; fd < NOFILE; fd++){
if(cp->fds[fd]){
@@ -246,7 +250,7 @@ proc_exit()
if(p->ppid == cp->pid)
p->pid = 1;
- acquire(&proc_table_lock);
+ release(&proc_table_lock);
// switch into scheduler
swtch(ZOMBIE);
@@ -265,10 +269,8 @@ cli(void)
void
sti(void)
{
- if(cpus[cpu()].clis < 1){
- cprintf("cpu %d clis %d\n", cpu(), cpus[cpu()].clis);
+ if(cpus[cpu()].clis < 1)
panic("sti");
- }
cpus[cpu()].clis -= 1;
if(cpus[cpu()].clis < 1)
__asm __volatile("sti");
diff --git a/proc.h b/proc.h
index 4c5807b..e13df41 100644
--- a/proc.h
+++ b/proc.h
@@ -45,6 +45,7 @@ struct proc{
int ppid;
void *chan; // sleep
int killed;
+ int locks; // # of locks currently held
struct fd *fds[NOFILE];
struct Taskstate ts; // only to give cpu address of kernel stack
diff --git a/spinlock.c b/spinlock.c
index bd6bff5..507e74b 100644
--- a/spinlock.c
+++ b/spinlock.c
@@ -17,10 +17,11 @@ int getcallerpc(void *v) {
void
acquire(struct spinlock * lock)
{
+ struct proc *cp = curproc[cpu()];
unsigned who;
- if(curproc[cpu()])
- who = (unsigned) curproc[cpu()];
+ if(cp)
+ who = (unsigned) cp;
else
who = cpu() + 1;
@@ -38,16 +39,20 @@ acquire(struct spinlock * lock)
lock->who = who;
}
+ if(cp)
+ cp->locks += 1;
+
if(DEBUG) cprintf("cpu%d: acquired at %x\n", cpu(), getcallerpc(&lock));
}
void
release(struct spinlock * lock)
{
+ struct proc *cp = curproc[cpu()];
unsigned who;
- if(curproc[cpu()])
- who = (unsigned) curproc[cpu()];
+ if(cp)
+ who = (unsigned) cp;
else
who = cpu() + 1;
@@ -57,6 +62,8 @@ release(struct spinlock * lock)
panic("release");
lock->count -= 1;
+ if(cp)
+ cp->locks -= 1;
if(lock->count < 1){
lock->who = 0;
cmpxchg(1, 0, &lock->locked);
diff --git a/trap.c b/trap.c
index 862225b..6f5409b 100644
--- a/trap.c
+++ b/trap.c
@@ -62,6 +62,9 @@ trap(struct Trapframe *tf)
struct proc *cp = curproc[cpu()];
lapic_timerintr();
if(cp){
+ if(cpus[cpu()].clis != 0)
+ panic("trap clis > 0");
+ cpus[cpu()].clis += 1;
sti();
if(cp->killed)
proc_exit();
@@ -69,6 +72,7 @@ trap(struct Trapframe *tf)
}
return;
}
+
if(v == (IRQ_OFFSET + IRQ_IDE)){
ide_intr();
return;
diff --git a/usertests.c b/usertests.c
index fa1b210..2f688ca 100644
--- a/usertests.c
+++ b/usertests.c
@@ -93,8 +93,8 @@ preempt()
main()
{
puts("usertests starting\n");
- //pipe1();
- preempt();
+ pipe1();
+ //preempt();
while(1)
;