diff options
| author | rsc <rsc> | 2006-07-17 05:00:25 +0000 | 
|---|---|---|
| committer | rsc <rsc> | 2006-07-17 05:00:25 +0000 | 
| commit | 0dd4253747eef56d0f1539fac7d62234f6af5f51 (patch) | |
| tree | 1c28a6d0ce4cef90f85fd5f8b0106d431bfeffda | |
| parent | b5f17007f41770fee97fa850635976ceb7aa7492 (diff) | |
| download | xv6-labs-0dd4253747eef56d0f1539fac7d62234f6af5f51.tar.gz xv6-labs-0dd4253747eef56d0f1539fac7d62234f6af5f51.tar.bz2 xv6-labs-0dd4253747eef56d0f1539fac7d62234f6af5f51.zip  | |
add ide_lock for sleep
| -rw-r--r-- | defs.h | 7 | ||||
| -rw-r--r-- | ide.c | 8 | ||||
| -rw-r--r-- | proc.c | 12 | ||||
| -rw-r--r-- | spinlock.c | 14 | ||||
| -rw-r--r-- | spinlock.h | 3 | ||||
| -rw-r--r-- | syscall.c | 5 | 
6 files changed, 41 insertions, 8 deletions
@@ -61,10 +61,9 @@ int cpu(void);  // spinlock.c  struct spinlock; -void acquire(struct spinlock * lock); -void release(struct spinlock * lock); -void acquire1(struct spinlock * lock, struct proc *); -void release1(struct spinlock * lock, struct proc *); +void acquire(struct spinlock*); +void release(struct spinlock*); +int holding(struct spinlock*);  // main.c  void load_icode(struct proc *p, uint8_t *binary, uint size); @@ -10,6 +10,7 @@  #include "proc.h"  #include "defs.h"  #include "x86.h" +#include "spinlock.h"  #define IDE_BSY		0x80  #define IDE_DRDY	0x40 @@ -23,6 +24,7 @@ struct ide_request {  };  struct ide_request request[NREQUEST];  int head, tail; +struct spinlock ide_lock;  static int diskno = 0;  int disk_channel; @@ -107,12 +109,14 @@ void *  ide_start_read(uint32_t secno, void *dst, uint nsecs)  {    struct ide_request *r; +  if(!holding(&ide_lock)) +    panic("ide_start_read: not holding ide_lock");    if(nsecs > 256)      panic("ide_start_read: nsecs too large");    while ((head + 1) % NREQUEST == tail) -    sleep (&disk_channel, 0); +    sleep (&disk_channel, &ide_lock);    r = &request[head];    r->secno = secno; @@ -132,6 +136,8 @@ ide_finish_read(void *c)    int r = 0;    struct ide_request *req = (struct ide_request *) c; +  if(!holding(&ide_lock)) +    panic("ide_start_read: not holding ide_lock");    for (; req->nsecs > 0; req->nsecs--, req->dst += 512) {      if ((r = ide_wait_ready(1)) < 0)        break; @@ -176,6 +176,15 @@ scheduler(void)        if(p->state == RUNNING)          panic("swtch to scheduler with state=RUNNING"); +      if(!holding(&proc_table_lock)){ +        cprintf("back to scheduler without proc_table_lock (pid=%d state=%d)", p->pid, p->state); +        panic("scheduler lock"); +      } +      if(cpus[cpu()].nlock != 1){ +        cprintf("holding %d locks in scheduler (pid=%d state=%d)\n", cpus[cpu()].nlock, p->pid, p->state); +        panic("scheduler lock"); +      } +        // XXX if not holding proc_table_lock panic.      }      release(&proc_table_lock); @@ -236,6 +245,9 @@ sleep(void *chan, struct spinlock *lk)    if(p == 0)      panic("sleep"); +  if(lk == 0) +    panic("sleep without lk"); +    // Must acquire proc_table_lock in order to     // change p->state and then call sched.    // Once we hold proc_table_lock, we can be  @@ -21,20 +21,32 @@ getcallerpc(void *v)  void  acquire(struct spinlock * lock)  { +	if(holding(lock)) +		panic("acquire"); +  	if(cpus[cpu()].nlock++ == 0)  		cli();  	while(cmpxchg(0, 1, &lock->locked) == 1)  		;  	cpuid(0, 0, 0, 0, 0);	// memory barrier -	lock->locker_pc = getcallerpc(&lock); +	lock->pc = getcallerpc(&lock); +	lock->cpu = cpu();  }  void  release(struct spinlock * lock)  { +	if(!holding(lock)) +		panic("release"); +  	cpuid(0, 0, 0, 0, 0);	// memory barrier  	lock->locked = 0;  	if(--cpus[cpu()].nlock == 0)  		sti();  } +int +holding(struct spinlock *lock) +{ +	return lock->locked && lock->cpu == cpu(); +} @@ -1,4 +1,5 @@  struct spinlock {    uint locked; -  uint locker_pc; +  uint32_t pc; +  int cpu;  }; @@ -228,17 +228,20 @@ sys_block(void)    char buf[512];    int i, j;    void *c; +  extern struct spinlock ide_lock;    cprintf("%d: call sys_block\n", cpu());    for (i = 0; i < 100; i++) { +    acquire(&ide_lock);      if ((c = ide_start_read(i, buf, 1)) == 0) {        panic("couldn't start read\n");      }      cprintf("call sleep\n"); -    sleep (c, 0); +    sleep (c, &ide_lock);      if (ide_finish_read(c)) {        panic("couldn't do read\n");      } +    release(&ide_lock);      cprintf("sector %d: ", i);      for (j = 0; j < 2; j++)        cprintf("%x ", buf[j] & 0xff);  | 
