Skip to content
Snippets Groups Projects
Commit efc12b8e authored by rsc's avatar rsc
Browse files

Replace yield system call with sleep.

parent e1872bb1
Branches
No related tags found
No related merge requests found
......@@ -139,7 +139,9 @@ void syscall(void);
// trap.c
void idtinit(void);
extern int ticks;
void tvinit(void);
extern struct spinlock tickslock;
// number of elements in fixed-size array
#define NELEM(x) (sizeof(x)/sizeof((x)[0]))
......
......@@ -102,10 +102,10 @@ extern int sys_open(void);
extern int sys_pipe(void);
extern int sys_read(void);
extern int sys_sbrk(void);
extern int sys_sleep(void);
extern int sys_unlink(void);
extern int sys_wait(void);
extern int sys_write(void);
extern int sys_yield(void);
static int (*syscalls[])(void) = {
[SYS_chdir] sys_chdir,
......@@ -124,10 +124,10 @@ static int (*syscalls[])(void) = {
[SYS_pipe] sys_pipe,
[SYS_read] sys_read,
[SYS_sbrk] sys_sbrk,
[SYS_sleep] sys_sleep,
[SYS_unlink] sys_unlink,
[SYS_wait] sys_wait,
[SYS_write] sys_write,
[SYS_yield] sys_yield,
};
void
......
......@@ -18,4 +18,4 @@
#define SYS_dup 17
#define SYS_getpid 18
#define SYS_sbrk 19
#define SYS_yield 20
#define SYS_sleep 20
......@@ -70,8 +70,21 @@ sys_sbrk(void)
}
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;
}
......@@ -6,10 +6,13 @@
#include "x86.h"
#include "traps.h"
#include "syscall.h"
#include "spinlock.h"
// Interrupt descriptor table (shared by all CPUs).
struct gatedesc idt[256];
extern uint vectors[]; // in vectors.S: array of 256 entry pointers
struct spinlock tickslock;
int ticks;
void
tvinit(void)
......@@ -19,6 +22,8 @@ tvinit(void)
for(i = 0; i < 256; i++)
SETGATE(idt[i], 0, SEG_KCODE<<3, vectors[i], 0);
SETGATE(idt[T_SYSCALL], 0, SEG_KCODE<<3, vectors[T_SYSCALL], DPL_USER);
initlock(&tickslock, "time");
}
void
......@@ -47,21 +52,14 @@ trap(struct trapframe *tf)
// PAGEBREAK: 10
switch(tf->trapno){
case IRQ_OFFSET + IRQ_TIMER:
lapic_timerintr();
cpus[cpu()].nlock--;
if(cp){
// 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();
if(cpu() == 0){
acquire(&tickslock);
ticks++;
wakeup(&ticks);
release(&tickslock);
}
return;
lapic_eoi();
break;
case IRQ_OFFSET + IRQ_IDE:
ide_intr();
......@@ -75,6 +73,7 @@ trap(struct trapframe *tf)
case IRQ_OFFSET + IRQ_SPURIOUS:
cprintf("spurious interrupt from cpu %d eip %x\n", cpu(), tf->eip);
lapic_eoi();
break;
default:
......@@ -84,12 +83,23 @@ trap(struct trapframe *tf)
cp->pid, cp->name, tf->trapno, tf->err, cpu(), tf->eip);
proc_exit();
}
// Otherwise it's our mistake.
cprintf("unexpected trap %d from cpu %d eip %x\n",
tf->trapno, cpu(), tf->eip);
panic("trap");
}
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 @@
.globl trapret1
.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.
alltraps:
......
......@@ -18,6 +18,7 @@ int chdir(char*);
int dup(int);
int getpid();
char* sbrk(int);
int sleep(int);
// ulib.c
int stat(char*, struct stat*);
......
......@@ -27,4 +27,4 @@ STUB(chdir)
STUB(dup)
STUB(getpid)
STUB(sbrk)
STUB(yield)
STUB(sleep)
// Create a zombie process.
// Create a zombie process that
// must be reparented at exit.
#include "types.h"
#include "stat.h"
......@@ -10,7 +11,6 @@ main(void)
int i;
if(fork() > 0)
for(i=0; i<10; i++)
yield();
sleep(5); // Let child exit before parent.
exit();
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment