diff options
| author | rtm <rtm> | 2006-06-15 19:58:01 +0000 | 
|---|---|---|
| committer | rtm <rtm> | 2006-06-15 19:58:01 +0000 | 
| commit | be0a7eacdab4443199ed0ed4379a84edc7c98fd6 (patch) | |
| tree | 5528a9d64865c1f29ded1f179ebf408e50df3d50 | |
| parent | a4c03dea09b7b5f2463147e979d20b035b81de96 (diff) | |
| download | xv6-labs-be0a7eacdab4443199ed0ed4379a84edc7c98fd6.tar.gz xv6-labs-be0a7eacdab4443199ed0ed4379a84edc7c98fd6.tar.bz2 xv6-labs-be0a7eacdab4443199ed0ed4379a84edc7c98fd6.zip | |
sleep, wakeup, wait, exit
| -rw-r--r-- | Makefile | 6 | ||||
| -rw-r--r-- | defs.h | 2 | ||||
| -rw-r--r-- | main.c | 9 | ||||
| -rw-r--r-- | proc.c | 28 | ||||
| -rw-r--r-- | proc.h | 5 | ||||
| -rw-r--r-- | syscall.c | 48 | ||||
| -rw-r--r-- | syscall.h | 1 | 
7 files changed, 93 insertions, 6 deletions
| @@ -5,7 +5,7 @@ CC = i386-jos-elf-gcc  LD = i386-jos-elf-ld  OBJCOPY = i386-jos-elf-objcopy  OBJDUMP = i386-jos-elf-objdump -CFLAGS = -nostdinc -I. -O -Wall +CFLAGS = -nostdinc -I. -O -Wall -MD  xv6.img : bootblock kernel  	dd if=/dev/zero of=xv6.img count=10000 @@ -27,5 +27,7 @@ kernel : $(OBJS)  vectors.S : vectors.pl  	perl vectors.pl > vectors.S +-include *.d +  clean :  -	rm -f *.o bootblock kernel kernel.asm xv6.img +	rm -f *.o bootblock kernel kernel.asm xv6.img *.d @@ -12,6 +12,8 @@ struct proc;  void setupsegs(struct proc *);  struct proc * newproc(void);  void swtch(void); +void sleep(void *); +void wakeup(void *);  // trap.c  void tinit(void); @@ -42,6 +42,8 @@ main()    p->tf->tf_es = p->tf->tf_ds = p->tf->tf_ss = (SEG_UDATA << 3) | 3;    p->tf->tf_cs = (SEG_UCODE << 3) | 3;    p->tf->tf_eflags = FL_IF; +  p->pid = 0; +  p->ppid = 0;    setupsegs(p);    p = newproc(); @@ -56,6 +58,13 @@ main()    p->mem[i++] = 0xcd; // int    p->mem[i++] = T_SYSCALL;    p->mem[i++] = 0xb8; // mov ..., %eax +  p->mem[i++] = SYS_wait; +  p->mem[i++] = 0; +  p->mem[i++] = 0; +  p->mem[i++] = 0; +  p->mem[i++] = 0xcd; // int +  p->mem[i++] = T_SYSCALL; +  p->mem[i++] = 0xb8; // mov ..., %eax    p->mem[i++] = SYS_exit;    p->mem[i++] = 0;    p->mem[i++] = 0; @@ -7,6 +7,7 @@  struct proc proc[NPROC];  struct proc *curproc; +int next_pid = 1;  /*   * set up a process's task state and segment descriptors @@ -54,6 +55,8 @@ newproc()    if(np >= &proc[NPROC])      return 0; +  np->pid = next_pid++; +  np->ppid = curproc->pid;    np->sz = curproc->sz;    np->mem = kalloc(curproc->sz);    if(np->mem == 0) @@ -111,7 +114,12 @@ swtch()    // XXX callee-saved registers? -  // XXX probably ought to lgdt on trap return too +  // h/w sets busy bit in TSS descriptor sometimes, and faults +  // if it's set in LTR. so clear tss descriptor busy bit. +  curproc->gdt[SEG_TSS].sd_type = STS_T32A; + +  // XXX probably ought to lgdt on trap return too, in case +  // a system call has moved a program or changed its size.    asm volatile("lgdt %0" : : "g" (np->gdt_pd.pd_lim));    ltr(SEG_TSS << 3); @@ -122,3 +130,21 @@ swtch()    asm volatile("movl %0, %%esp" : : "g" (np->esp));    asm volatile("movl %0, %%ebp" : : "g" (np->ebp));  } + +void +sleep(void *chan) +{ +  curproc->chan = chan; +  curproc->state = WAITING; +  swtch(); +} + +void +wakeup(void *chan) +{ +  struct proc *p; + +  for(p = proc; p < &proc[NPROC]; p++) +    if(p->state == WAITING && p->chan == chan) +      p->state = RUNNABLE; +} @@ -20,7 +20,10 @@ struct proc{    char *mem; // start of process's physical memory    unsigned sz; // total size of mem, including kernel stack    char *kstack; // kernel stack, separate from mem so it doesn't move -  enum { UNUSED, RUNNABLE, WAITING } state; +  enum { UNUSED, RUNNABLE, WAITING, ZOMBIE } state; +  int pid; +  int ppid; +  void *chan; // sleep    struct Taskstate ts;  // only to give cpu address of kernel stack    struct Segdesc gdt[NSEGS]; @@ -24,12 +24,53 @@ sys_fork()  void  sys_exit()  { -  curproc->state = UNUSED; -  // XXX free resources. notify parent. abandon children. +  struct proc *p; + +  curproc->state = ZOMBIE; + +  // wake up parent +  for(p = proc; p < &proc[NPROC]; p++) +    if(p->pid == curproc->ppid) +      wakeup(p); + +  // abandon children +  for(p = proc; p < &proc[NPROC]; p++) +    if(p->ppid == curproc->pid) +      p->pid = 1; +    swtch();  }  void +sys_wait() +{ +  struct proc *p; +  int any; + +  cprintf("waid pid %d ppid %d\n", curproc->pid, curproc->ppid); + +  while(1){ +    any = 0; +    for(p = proc; p < &proc[NPROC]; p++){ +      if(p->state == ZOMBIE && p->ppid == curproc->pid){ +        kfree(p->mem, p->sz); +        kfree(p->kstack, KSTACKSIZE); +        p->state = UNUSED; +        cprintf("%x collected %x\n", curproc, p); +        return; +      } +      if(p->state != UNUSED && p->ppid == curproc->pid) +        any = 1; +    } +    if(any == 0){ +      cprintf("%x nothing to wait for\n", curproc); +      return; +    } +    sleep(curproc); +  } +} + +void  syscall()  {    int num = curproc->tf->tf_regs.reg_eax; @@ -42,6 +83,9 @@ syscall()    case SYS_exit:      sys_exit();      break; +  case SYS_wait: +    sys_wait(); +    break;    default:      cprintf("unknown sys call %d\n", num);      // XXX fault @@ -1,2 +1,3 @@  #define SYS_fork 1  #define SYS_exit 2 +#define SYS_wait 3 | 
