add ide_lock for sleep
This commit is contained in:
parent
b5f17007f4
commit
0dd4253747
6 changed files with 41 additions and 8 deletions
7
defs.h
7
defs.h
|
@ -61,10 +61,9 @@ int cpu(void);
|
||||||
|
|
||||||
// spinlock.c
|
// spinlock.c
|
||||||
struct spinlock;
|
struct spinlock;
|
||||||
void acquire(struct spinlock * lock);
|
void acquire(struct spinlock*);
|
||||||
void release(struct spinlock * lock);
|
void release(struct spinlock*);
|
||||||
void acquire1(struct spinlock * lock, struct proc *);
|
int holding(struct spinlock*);
|
||||||
void release1(struct spinlock * lock, struct proc *);
|
|
||||||
|
|
||||||
// main.c
|
// main.c
|
||||||
void load_icode(struct proc *p, uint8_t *binary, uint size);
|
void load_icode(struct proc *p, uint8_t *binary, uint size);
|
||||||
|
|
8
ide.c
8
ide.c
|
@ -10,6 +10,7 @@
|
||||||
#include "proc.h"
|
#include "proc.h"
|
||||||
#include "defs.h"
|
#include "defs.h"
|
||||||
#include "x86.h"
|
#include "x86.h"
|
||||||
|
#include "spinlock.h"
|
||||||
|
|
||||||
#define IDE_BSY 0x80
|
#define IDE_BSY 0x80
|
||||||
#define IDE_DRDY 0x40
|
#define IDE_DRDY 0x40
|
||||||
|
@ -23,6 +24,7 @@ struct ide_request {
|
||||||
};
|
};
|
||||||
struct ide_request request[NREQUEST];
|
struct ide_request request[NREQUEST];
|
||||||
int head, tail;
|
int head, tail;
|
||||||
|
struct spinlock ide_lock;
|
||||||
|
|
||||||
static int diskno = 0;
|
static int diskno = 0;
|
||||||
int disk_channel;
|
int disk_channel;
|
||||||
|
@ -107,12 +109,14 @@ void *
|
||||||
ide_start_read(uint32_t secno, void *dst, uint nsecs)
|
ide_start_read(uint32_t secno, void *dst, uint nsecs)
|
||||||
{
|
{
|
||||||
struct ide_request *r;
|
struct ide_request *r;
|
||||||
|
if(!holding(&ide_lock))
|
||||||
|
panic("ide_start_read: not holding ide_lock");
|
||||||
|
|
||||||
if(nsecs > 256)
|
if(nsecs > 256)
|
||||||
panic("ide_start_read: nsecs too large");
|
panic("ide_start_read: nsecs too large");
|
||||||
|
|
||||||
while ((head + 1) % NREQUEST == tail)
|
while ((head + 1) % NREQUEST == tail)
|
||||||
sleep (&disk_channel, 0);
|
sleep (&disk_channel, &ide_lock);
|
||||||
|
|
||||||
r = &request[head];
|
r = &request[head];
|
||||||
r->secno = secno;
|
r->secno = secno;
|
||||||
|
@ -132,6 +136,8 @@ ide_finish_read(void *c)
|
||||||
int r = 0;
|
int r = 0;
|
||||||
struct ide_request *req = (struct ide_request *) c;
|
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) {
|
for (; req->nsecs > 0; req->nsecs--, req->dst += 512) {
|
||||||
if ((r = ide_wait_ready(1)) < 0)
|
if ((r = ide_wait_ready(1)) < 0)
|
||||||
break;
|
break;
|
||||||
|
|
12
proc.c
12
proc.c
|
@ -176,6 +176,15 @@ scheduler(void)
|
||||||
if(p->state == RUNNING)
|
if(p->state == RUNNING)
|
||||||
panic("swtch to scheduler with 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.
|
// XXX if not holding proc_table_lock panic.
|
||||||
}
|
}
|
||||||
release(&proc_table_lock);
|
release(&proc_table_lock);
|
||||||
|
@ -236,6 +245,9 @@ sleep(void *chan, struct spinlock *lk)
|
||||||
if(p == 0)
|
if(p == 0)
|
||||||
panic("sleep");
|
panic("sleep");
|
||||||
|
|
||||||
|
if(lk == 0)
|
||||||
|
panic("sleep without lk");
|
||||||
|
|
||||||
// Must acquire proc_table_lock in order to
|
// Must acquire proc_table_lock in order to
|
||||||
// change p->state and then call sched.
|
// change p->state and then call sched.
|
||||||
// Once we hold proc_table_lock, we can be
|
// Once we hold proc_table_lock, we can be
|
||||||
|
|
14
spinlock.c
14
spinlock.c
|
@ -21,20 +21,32 @@ getcallerpc(void *v)
|
||||||
void
|
void
|
||||||
acquire(struct spinlock * lock)
|
acquire(struct spinlock * lock)
|
||||||
{
|
{
|
||||||
|
if(holding(lock))
|
||||||
|
panic("acquire");
|
||||||
|
|
||||||
if(cpus[cpu()].nlock++ == 0)
|
if(cpus[cpu()].nlock++ == 0)
|
||||||
cli();
|
cli();
|
||||||
while(cmpxchg(0, 1, &lock->locked) == 1)
|
while(cmpxchg(0, 1, &lock->locked) == 1)
|
||||||
;
|
;
|
||||||
cpuid(0, 0, 0, 0, 0); // memory barrier
|
cpuid(0, 0, 0, 0, 0); // memory barrier
|
||||||
lock->locker_pc = getcallerpc(&lock);
|
lock->pc = getcallerpc(&lock);
|
||||||
|
lock->cpu = cpu();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
release(struct spinlock * lock)
|
release(struct spinlock * lock)
|
||||||
{
|
{
|
||||||
|
if(!holding(lock))
|
||||||
|
panic("release");
|
||||||
|
|
||||||
cpuid(0, 0, 0, 0, 0); // memory barrier
|
cpuid(0, 0, 0, 0, 0); // memory barrier
|
||||||
lock->locked = 0;
|
lock->locked = 0;
|
||||||
if(--cpus[cpu()].nlock == 0)
|
if(--cpus[cpu()].nlock == 0)
|
||||||
sti();
|
sti();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
holding(struct spinlock *lock)
|
||||||
|
{
|
||||||
|
return lock->locked && lock->cpu == cpu();
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
struct spinlock {
|
struct spinlock {
|
||||||
uint locked;
|
uint locked;
|
||||||
uint locker_pc;
|
uint32_t pc;
|
||||||
|
int cpu;
|
||||||
};
|
};
|
||||||
|
|
|
@ -228,17 +228,20 @@ sys_block(void)
|
||||||
char buf[512];
|
char buf[512];
|
||||||
int i, j;
|
int i, j;
|
||||||
void *c;
|
void *c;
|
||||||
|
extern struct spinlock ide_lock;
|
||||||
|
|
||||||
cprintf("%d: call sys_block\n", cpu());
|
cprintf("%d: call sys_block\n", cpu());
|
||||||
for (i = 0; i < 100; i++) {
|
for (i = 0; i < 100; i++) {
|
||||||
|
acquire(&ide_lock);
|
||||||
if ((c = ide_start_read(i, buf, 1)) == 0) {
|
if ((c = ide_start_read(i, buf, 1)) == 0) {
|
||||||
panic("couldn't start read\n");
|
panic("couldn't start read\n");
|
||||||
}
|
}
|
||||||
cprintf("call sleep\n");
|
cprintf("call sleep\n");
|
||||||
sleep (c, 0);
|
sleep (c, &ide_lock);
|
||||||
if (ide_finish_read(c)) {
|
if (ide_finish_read(c)) {
|
||||||
panic("couldn't do read\n");
|
panic("couldn't do read\n");
|
||||||
}
|
}
|
||||||
|
release(&ide_lock);
|
||||||
cprintf("sector %d: ", i);
|
cprintf("sector %d: ", i);
|
||||||
for (j = 0; j < 2; j++)
|
for (j = 0; j < 2; j++)
|
||||||
cprintf("%x ", buf[j] & 0xff);
|
cprintf("%x ", buf[j] & 0xff);
|
||||||
|
|
Loading…
Reference in a new issue