Replace yield system call with sleep.
This commit is contained in:
parent
e1872bb130
commit
efc12b8e61
9 changed files with 52 additions and 26 deletions
2
defs.h
2
defs.h
|
@ -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);
|
||||||
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) = {
|
||||||
[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 @@
|
||||||
#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
|
||||||
|
|
17
sysproc.c
17
sysproc.c
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
42
trap.c
42
trap.c
|
@ -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)
|
||||||
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)
|
||||||
// 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)
|
||||||
|
|
||||||
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)
|
||||||
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 @@
|
||||||
.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:
|
||||||
|
|
1
user.h
1
user.h
|
@ -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*);
|
||||||
|
|
2
usys.S
2
usys.S
|
@ -27,4 +27,4 @@ STUB(chdir)
|
||||||
STUB(dup)
|
STUB(dup)
|
||||||
STUB(getpid)
|
STUB(getpid)
|
||||||
STUB(sbrk)
|
STUB(sbrk)
|
||||||
STUB(yield)
|
STUB(sleep)
|
||||||
|
|
6
zombie.c
6
zombie.c
|
@ -1,4 +1,5 @@
|
||||||
// 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)
|
||||||
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();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue