diff options
| -rw-r--r-- | defs.h | 2 | ||||
| -rw-r--r-- | syscall.c | 4 | ||||
| -rw-r--r-- | syscall.h | 2 | ||||
| -rw-r--r-- | sysproc.c | 17 | ||||
| -rw-r--r-- | trap.c | 42 | ||||
| -rw-r--r-- | trapasm.S | 2 | ||||
| -rw-r--r-- | user.h | 1 | ||||
| -rw-r--r-- | usys.S | 2 | ||||
| -rw-r--r-- | zombie.c | 6 | 
9 files changed, 52 insertions, 26 deletions
@@ -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) @@ -1,4 +1,5 @@ -// 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();  }  | 
