提交 efc12b8e 创建 作者: rsc's avatar rsc

Replace yield system call with sleep.

上级 e1872bb1
...@@ -139,7 +139,9 @@ void syscall(void); ...@@ -139,7 +139,9 @@ void syscall(void);
// trap.c // trap.c
void idtinit(void); void idtinit(void);
extern int ticks;
void tvinit(void); void tvinit(void);
extern struct spinlock tickslock;
// number of elements in fixed-size array // number of elements in fixed-size array
#define NELEM(x) (sizeof(x)/sizeof((x)[0])) #define NELEM(x) (sizeof(x)/sizeof((x)[0]))
......
...@@ -102,10 +102,10 @@ extern int sys_open(void); ...@@ -102,10 +102,10 @@ extern int sys_open(void);
extern int sys_pipe(void); extern int sys_pipe(void);
extern int sys_read(void); extern int sys_read(void);
extern int sys_sbrk(void); extern int sys_sbrk(void);
extern int sys_sleep(void);
extern int sys_unlink(void); extern int sys_unlink(void);
extern int sys_wait(void); extern int sys_wait(void);
extern int sys_write(void); extern int sys_write(void);
extern int sys_yield(void);
static int (*syscalls[])(void) = { static int (*syscalls[])(void) = {
[SYS_chdir] sys_chdir, [SYS_chdir] sys_chdir,
...@@ -124,10 +124,10 @@ static int (*syscalls[])(void) = { ...@@ -124,10 +124,10 @@ static int (*syscalls[])(void) = {
[SYS_pipe] sys_pipe, [SYS_pipe] sys_pipe,
[SYS_read] sys_read, [SYS_read] sys_read,
[SYS_sbrk] sys_sbrk, [SYS_sbrk] sys_sbrk,
[SYS_sleep] sys_sleep,
[SYS_unlink] sys_unlink, [SYS_unlink] sys_unlink,
[SYS_wait] sys_wait, [SYS_wait] sys_wait,
[SYS_write] sys_write, [SYS_write] sys_write,
[SYS_yield] sys_yield,
}; };
void void
......
...@@ -18,4 +18,4 @@ ...@@ -18,4 +18,4 @@
#define SYS_dup 17 #define SYS_dup 17
#define SYS_getpid 18 #define SYS_getpid 18
#define SYS_sbrk 19 #define SYS_sbrk 19
#define SYS_yield 20 #define SYS_sleep 20
...@@ -70,8 +70,21 @@ sys_sbrk(void) ...@@ -70,8 +70,21 @@ sys_sbrk(void)
} }
int int
sys_yield(void) sys_sleep(void)
{ {
yield(); int n, ticks0;
if(argint(0, &n) < 0)
return -1;
acquire(&tickslock);
ticks0 = ticks;
while(ticks - ticks0 < n){
if(cp->killed){
release(&tickslock);
return -1;
}
sleep(&ticks, &tickslock);
}
release(&tickslock);
return 0; return 0;
} }
...@@ -6,10 +6,13 @@ ...@@ -6,10 +6,13 @@
#include "x86.h" #include "x86.h"
#include "traps.h" #include "traps.h"
#include "syscall.h" #include "syscall.h"
#include "spinlock.h"
// Interrupt descriptor table (shared by all CPUs). // Interrupt descriptor table (shared by all CPUs).
struct gatedesc idt[256]; struct gatedesc idt[256];
extern uint vectors[]; // in vectors.S: array of 256 entry pointers extern uint vectors[]; // in vectors.S: array of 256 entry pointers
struct spinlock tickslock;
int ticks;
void void
tvinit(void) tvinit(void)
...@@ -19,6 +22,8 @@ tvinit(void) ...@@ -19,6 +22,8 @@ tvinit(void)
for(i = 0; i < 256; i++) for(i = 0; i < 256; i++)
SETGATE(idt[i], 0, SEG_KCODE<<3, vectors[i], 0); SETGATE(idt[i], 0, SEG_KCODE<<3, vectors[i], 0);
SETGATE(idt[T_SYSCALL], 0, SEG_KCODE<<3, vectors[T_SYSCALL], DPL_USER); SETGATE(idt[T_SYSCALL], 0, SEG_KCODE<<3, vectors[T_SYSCALL], DPL_USER);
initlock(&tickslock, "time");
} }
void void
...@@ -47,21 +52,14 @@ trap(struct trapframe *tf) ...@@ -47,21 +52,14 @@ trap(struct trapframe *tf)
// PAGEBREAK: 10 // PAGEBREAK: 10
switch(tf->trapno){ switch(tf->trapno){
case IRQ_OFFSET + IRQ_TIMER: case IRQ_OFFSET + IRQ_TIMER:
lapic_timerintr(); if(cpu() == 0){
cpus[cpu()].nlock--; acquire(&tickslock);
if(cp){ ticks++;
// Force process exit if it has been killed and is in user space. wakeup(&ticks);
// (If it is still executing in the kernel, let it keep running release(&tickslock);
// until it gets to the regular system call return.)
if((tf->cs&3) == DPL_USER && cp->killed)
proc_exit();
// Force process to give up CPU and let others run.
// If locks were held with interrupts on, would need to check nlock.
if(cp->state == RUNNING)
yield();
} }
return; lapic_eoi();
break;
case IRQ_OFFSET + IRQ_IDE: case IRQ_OFFSET + IRQ_IDE:
ide_intr(); ide_intr();
...@@ -75,6 +73,7 @@ trap(struct trapframe *tf) ...@@ -75,6 +73,7 @@ trap(struct trapframe *tf)
case IRQ_OFFSET + IRQ_SPURIOUS: case IRQ_OFFSET + IRQ_SPURIOUS:
cprintf("spurious interrupt from cpu %d eip %x\n", cpu(), tf->eip); cprintf("spurious interrupt from cpu %d eip %x\n", cpu(), tf->eip);
lapic_eoi();
break; break;
default: default:
...@@ -84,12 +83,23 @@ trap(struct trapframe *tf) ...@@ -84,12 +83,23 @@ trap(struct trapframe *tf)
cp->pid, cp->name, tf->trapno, tf->err, cpu(), tf->eip); cp->pid, cp->name, tf->trapno, tf->err, cpu(), tf->eip);
proc_exit(); proc_exit();
} }
// Otherwise it's our mistake. // Otherwise it's our mistake.
cprintf("unexpected trap %d from cpu %d eip %x\n", cprintf("unexpected trap %d from cpu %d eip %x\n",
tf->trapno, cpu(), tf->eip); tf->trapno, cpu(), tf->eip);
panic("trap"); panic("trap");
} }
cpus[cpu()].nlock--; cpus[cpu()].nlock--;
if(tf->trapno == IRQ_OFFSET + IRQ_TIMER && cp != 0){
// Force process exit if it has been killed and is in user space.
// (If it is still executing in the kernel, let it keep running
// until it gets to the regular system call return.)
if((tf->cs&3) == DPL_USER && cp->killed)
proc_exit();
// Force process to give up CPU and let others run.
// If locks were held with interrupts on, would need to check nlock.
if(cp->state == RUNNING)
yield();
}
} }
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
.globl trapret1 .globl trapret1
.globl alltraps .globl alltraps
.set SEG_KDATA_SEL 0x10 # selector for SEG_KDATA .set SEG_KDATA_SEL, 0x10 # selector for SEG_KDATA
# vectors.S sends all traps here. # vectors.S sends all traps here.
alltraps: alltraps:
......
...@@ -18,6 +18,7 @@ int chdir(char*); ...@@ -18,6 +18,7 @@ int chdir(char*);
int dup(int); int dup(int);
int getpid(); int getpid();
char* sbrk(int); char* sbrk(int);
int sleep(int);
// ulib.c // ulib.c
int stat(char*, struct stat*); int stat(char*, struct stat*);
......
...@@ -27,4 +27,4 @@ STUB(chdir) ...@@ -27,4 +27,4 @@ STUB(chdir)
STUB(dup) STUB(dup)
STUB(getpid) STUB(getpid)
STUB(sbrk) STUB(sbrk)
STUB(yield) STUB(sleep)
// Create a zombie process. // Create a zombie process that
// must be reparented at exit.
#include "types.h" #include "types.h"
#include "stat.h" #include "stat.h"
...@@ -10,7 +11,6 @@ main(void) ...@@ -10,7 +11,6 @@ main(void)
int i; int i;
if(fork() > 0) if(fork() > 0)
for(i=0; i<10; i++) sleep(5); // Let child exit before parent.
yield();
exit(); exit();
} }
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论