Browse Source

Merge branch 'a2a' of tarfeef101/cs350 into master

Tareef Dedhar 6 years ago
parent
commit
9b74ba733d
53 changed files with 2022 additions and 234 deletions
  1. BIN
      build/install/hostbin/host-dumpsfs
  2. BIN
      build/install/hostbin/host-hash
  3. BIN
      build/install/hostbin/host-mksfs
  4. BIN
      build/install/hostbin/host-sfsck
  5. 0 0
      build/kern
  6. BIN
      build/user/sbin/dumpsfs/dumpsfs.ho
  7. BIN
      build/user/sbin/dumpsfs/host-dumpsfs
  8. BIN
      build/user/sbin/mksfs/host-mksfs
  9. BIN
      build/user/sbin/mksfs/mksfs.ho
  10. BIN
      build/user/sbin/sfsck/host-sfsck
  11. BIN
      build/user/sbin/sfsck/sfsck.ho
  12. BIN
      build/user/testbin/hash/hash.ho
  13. BIN
      build/user/testbin/hash/host-hash
  14. 9 0
      fastscript.sh
  15. 19 9
      kern/arch/mips/syscall/syscall.c
  16. 1 0
      kern/build
  17. 803 0
      kern/compile/ASST2/.depend
  18. 15 0
      kern/compile/ASST2/Makefile
  19. 410 0
      kern/compile/ASST2/autoconf.c
  20. 43 0
      kern/compile/ASST2/autoconf.h
  21. 114 0
      kern/compile/ASST2/files.mk
  22. 1 0
      kern/compile/ASST2/includelinks/kern/machine
  23. 1 0
      kern/compile/ASST2/includelinks/kern/mips
  24. 1 0
      kern/compile/ASST2/includelinks/machine
  25. 1 0
      kern/compile/ASST2/includelinks/mips
  26. 1 0
      kern/compile/ASST2/includelinks/platform
  27. 1 0
      kern/compile/ASST2/includelinks/sys161
  28. BIN
      kern/compile/ASST2/kernel
  29. 5 0
      kern/compile/ASST2/opt-A0.h
  30. 5 0
      kern/compile/ASST2/opt-A1.h
  31. 5 0
      kern/compile/ASST2/opt-A2.h
  32. 5 0
      kern/compile/ASST2/opt-A3.h
  33. 5 0
      kern/compile/ASST2/opt-A4.h
  34. 5 0
      kern/compile/ASST2/opt-A5.h
  35. 5 0
      kern/compile/ASST2/opt-dumbvm.h
  36. 5 0
      kern/compile/ASST2/opt-net.h
  37. 5 0
      kern/compile/ASST2/opt-netfs.h
  38. 5 0
      kern/compile/ASST2/opt-noasserts.h
  39. 5 0
      kern/compile/ASST2/opt-sfs.h
  40. 5 0
      kern/compile/ASST2/opt-synchprobs.h
  41. 3 0
      kern/compile/ASST2/vers.c
  42. 1 0
      kern/compile/ASST2/version
  43. 13 12
      kern/conf/conf.kern
  44. 7 6
      kern/include/addrspace.h
  45. 25 0
      kern/include/list.h
  46. 42 11
      kern/include/proc.h
  47. 6 5
      kern/include/syscall.h
  48. 10 8
      kern/include/thread.h
  49. 100 0
      kern/lib/list.c
  50. 175 73
      kern/proc/proc.c
  51. 100 56
      kern/syscall/proc_syscalls.c
  52. 55 54
      kern/thread/thread.c
  53. 5 0
      progress.txt

BIN
build/install/hostbin/host-dumpsfs


BIN
build/install/hostbin/host-hash


BIN
build/install/hostbin/host-mksfs


BIN
build/install/hostbin/host-sfsck


+ 0 - 0
build/kern


BIN
build/user/sbin/dumpsfs/dumpsfs.ho


BIN
build/user/sbin/dumpsfs/host-dumpsfs


BIN
build/user/sbin/mksfs/host-mksfs


BIN
build/user/sbin/mksfs/mksfs.ho


BIN
build/user/sbin/sfsck/host-sfsck


BIN
build/user/sbin/sfsck/sfsck.ho


BIN
build/user/testbin/hash/hash.ho


BIN
build/user/testbin/hash/host-hash


+ 9 - 0
fastscript.sh

@@ -0,0 +1,9 @@
+#!/bin/bash
+set -eu
+topdir=$(pwd)
+cd ./kern/compile/ASST$1
+bmake depend
+bmake
+bmake install
+echo "SUCCESS!!!!!!!!!!"
+echo ""

+ 19 - 9
kern/arch/mips/syscall/syscall.c

@@ -76,7 +76,7 @@
  * registerized values, with copyin().
  * registerized values, with copyin().
  */
  */
 void
 void
-syscall(struct trapframe *tf)
+syscall(struct trapframe * tf)
 {
 {
 	int callno;
 	int callno;
 	int32_t retval;
 	int32_t retval;
@@ -93,13 +93,14 @@ syscall(struct trapframe *tf)
 	 * really return a value, just 0 for success and -1 on
 	 * really return a value, just 0 for success and -1 on
 	 * error. Since retval is the value returned on success,
 	 * error. Since retval is the value returned on success,
 	 * initialize it to 0 by default; thus it's not necessary to
 	 * initialize it to 0 by default; thus it's not necessary to
-	 * deal with it except for calls that return other values, 
+	 * deal with it except for calls that return other values,
 	 * like write.
 	 * like write.
 	 */
 	 */
 
 
 	retval = 0;
 	retval = 0;
 
 
-	switch (callno) {
+	switch (callno)
+	{
 	    case SYS_reboot:
 	    case SYS_reboot:
 		err = sys_reboot(tf->tf_a0);
 		err = sys_reboot(tf->tf_a0);
 		break;
 		break;
@@ -131,7 +132,9 @@ syscall(struct trapframe *tf)
 	  break;
 	  break;
 #endif // UW
 #endif // UW
 
 
-	    /* Add stuff here */
+	 case SYS_fork:
+	  err = sys_fork(tf, (pid_t*)&retval);
+	  break;
  
  
 	default:
 	default:
 	  kprintf("Unknown syscall %d\n", callno);
 	  kprintf("Unknown syscall %d\n", callno);
@@ -140,7 +143,8 @@ syscall(struct trapframe *tf)
 	}
 	}
 
 
 
 
-	if (err) {
+	if (err)
+	{
 		/*
 		/*
 		 * Return the error code. This gets converted at
 		 * Return the error code. This gets converted at
 		 * userlevel to a return value of -1 and the error
 		 * userlevel to a return value of -1 and the error
@@ -149,7 +153,8 @@ syscall(struct trapframe *tf)
 		tf->tf_v0 = err;
 		tf->tf_v0 = err;
 		tf->tf_a3 = 1;      /* signal an error */
 		tf->tf_a3 = 1;      /* signal an error */
 	}
 	}
-	else {
+	else
+	{
 		/* Success. */
 		/* Success. */
 		tf->tf_v0 = retval;
 		tf->tf_v0 = retval;
 		tf->tf_a3 = 0;      /* signal no error */
 		tf->tf_a3 = 0;      /* signal no error */
@@ -176,8 +181,13 @@ syscall(struct trapframe *tf)
  *
  *
  * Thus, you can trash it and do things another way if you prefer.
  * Thus, you can trash it and do things another way if you prefer.
  */
  */
-void
-enter_forked_process(struct trapframe *tf)
+void enter_forked_process(void * trap, unsigned long x)
 {
 {
-	(void)tf;
+  (void)x;
+	struct trapframe * tf = (struct trapframe *)trap;
+	struct trapframe childframe = *tf;
+	childframe.tf_v0 = 0;
+	childframe.tf_epc += 4;
+	childframe.tf_a3 = 0;
+	mips_usermode(&childframe);
 }
 }

+ 1 - 0
kern/build

@@ -0,0 +1 @@
+../build/kern

+ 803 - 0
kern/compile/ASST2/.depend

@@ -0,0 +1,803 @@
+__printf.o: ../../../common/libc/printf/__printf.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/lib.h ../../include/cdefs.h \
+  opt-noasserts.h ../../include/stdarg.h
+snprintf.o: ../../../common/libc/printf/snprintf.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/lib.h ../../include/cdefs.h \
+  opt-noasserts.h ../../include/stdarg.h
+atoi.o: ../../../common/libc/stdlib/atoi.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/lib.h ../../include/cdefs.h \
+  opt-noasserts.h
+bzero.o: ../../../common/libc/string/bzero.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/lib.h ../../include/cdefs.h \
+  opt-noasserts.h
+memcpy.o: ../../../common/libc/string/memcpy.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/lib.h ../../include/cdefs.h \
+  opt-noasserts.h
+memmove.o: ../../../common/libc/string/memmove.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/lib.h ../../include/cdefs.h \
+  opt-noasserts.h
+strcat.o: ../../../common/libc/string/strcat.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/lib.h ../../include/cdefs.h \
+  opt-noasserts.h
+strchr.o: ../../../common/libc/string/strchr.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/lib.h ../../include/cdefs.h \
+  opt-noasserts.h
+strcmp.o: ../../../common/libc/string/strcmp.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/lib.h ../../include/cdefs.h \
+  opt-noasserts.h
+strcpy.o: ../../../common/libc/string/strcpy.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/lib.h ../../include/cdefs.h \
+  opt-noasserts.h
+strlen.o: ../../../common/libc/string/strlen.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/lib.h ../../include/cdefs.h \
+  opt-noasserts.h
+strrchr.o: ../../../common/libc/string/strrchr.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/lib.h ../../include/cdefs.h \
+  opt-noasserts.h
+strtok_r.o: ../../../common/libc/string/strtok_r.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/lib.h ../../include/cdefs.h \
+  opt-noasserts.h
+autoconf.o: ../../compile/ASST2/autoconf.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/lib.h ../../include/cdefs.h \
+  opt-noasserts.h ../../compile/ASST2/autoconf.h
+beep.o: ../../dev/generic/beep.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/kern/errno.h \
+  ../../include/lib.h ../../include/cdefs.h opt-noasserts.h \
+  ../../dev/generic/beep.h autoconf.h
+console.o: ../../dev/generic/console.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/kern/errno.h \
+  ../../include/lib.h ../../include/cdefs.h opt-noasserts.h \
+  ../../include/uio.h ../../include/kern/iovec.h ../../include/thread.h \
+  ../../include/array.h ../../include/spinlock.h \
+  includelinks/machine/spinlock.h ../../include/threadlist.h \
+  includelinks/machine/thread.h ../../include/setjmp.h \
+  includelinks/kern/machine/setjmp.h ../../include/current.h \
+  includelinks/machine/current.h ../../include/synch.h \
+  ../../dev/generic/console.h ../../include/vfs.h ../../include/device.h \
+  autoconf.h
+random.o: ../../dev/generic/random.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/kern/errno.h \
+  ../../include/kern/fcntl.h ../../include/lib.h ../../include/cdefs.h \
+  opt-noasserts.h ../../include/uio.h ../../include/kern/iovec.h \
+  ../../include/vfs.h ../../include/array.h ../../dev/generic/random.h \
+  ../../include/device.h autoconf.h
+rtclock.o: ../../dev/generic/rtclock.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/kern/errno.h \
+  ../../include/lib.h ../../include/cdefs.h opt-noasserts.h \
+  ../../include/clock.h opt-synchprobs.h ../../dev/generic/rtclock.h \
+  autoconf.h
+beep_ltimer.o: ../../dev/lamebus/beep_ltimer.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/lib.h ../../include/cdefs.h \
+  opt-noasserts.h ../../dev/generic/beep.h ../../dev/lamebus/ltimer.h \
+  autoconf.h
+con_lser.o: ../../dev/lamebus/con_lser.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/lib.h ../../include/cdefs.h \
+  opt-noasserts.h ../../dev/generic/console.h ../../dev/lamebus/lser.h \
+  ../../include/spinlock.h includelinks/machine/spinlock.h autoconf.h
+emu_att.o: ../../dev/lamebus/emu_att.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/lib.h ../../include/cdefs.h \
+  opt-noasserts.h ../../dev/lamebus/lamebus.h ../../include/cpu.h \
+  ../../include/spinlock.h includelinks/machine/spinlock.h \
+  ../../include/threadlist.h includelinks/machine/vm.h \
+  ../../dev/lamebus/emu.h autoconf.h
+emu.o: ../../dev/lamebus/emu.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/kern/errno.h \
+  ../../include/kern/fcntl.h ../../include/stat.h \
+  ../../include/kern/stat.h ../../include/kern/stattypes.h \
+  ../../include/lib.h ../../include/cdefs.h opt-noasserts.h \
+  ../../include/array.h ../../include/uio.h ../../include/kern/iovec.h \
+  ../../include/synch.h ../../include/spinlock.h \
+  includelinks/machine/spinlock.h ../../dev/lamebus/emu.h \
+  includelinks/platform/bus.h includelinks/machine/vm.h \
+  ../../dev/lamebus/lamebus.h ../../include/cpu.h \
+  ../../include/threadlist.h ../../include/vfs.h ../../include/emufs.h \
+  ../../include/fs.h ../../include/vnode.h autoconf.h
+lamebus.o: ../../dev/lamebus/lamebus.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/lib.h ../../include/cdefs.h \
+  opt-noasserts.h ../../include/cpu.h ../../include/spinlock.h \
+  includelinks/machine/spinlock.h ../../include/threadlist.h \
+  includelinks/machine/vm.h ../../include/current.h \
+  includelinks/machine/current.h ../../include/thread.h \
+  ../../include/array.h includelinks/machine/thread.h \
+  ../../include/setjmp.h includelinks/kern/machine/setjmp.h \
+  ../../dev/lamebus/lamebus.h
+lhd_att.o: ../../dev/lamebus/lhd_att.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/lib.h ../../include/cdefs.h \
+  opt-noasserts.h ../../dev/lamebus/lamebus.h ../../include/cpu.h \
+  ../../include/spinlock.h includelinks/machine/spinlock.h \
+  ../../include/threadlist.h includelinks/machine/vm.h \
+  ../../dev/lamebus/lhd.h ../../include/device.h autoconf.h
+lhd.o: ../../dev/lamebus/lhd.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/kern/errno.h \
+  ../../include/lib.h ../../include/cdefs.h opt-noasserts.h \
+  ../../include/uio.h ../../include/kern/iovec.h ../../include/synch.h \
+  ../../include/spinlock.h includelinks/machine/spinlock.h \
+  includelinks/platform/bus.h includelinks/machine/vm.h \
+  ../../dev/lamebus/lamebus.h ../../include/cpu.h \
+  ../../include/threadlist.h ../../include/vfs.h ../../include/array.h \
+  ../../dev/lamebus/lhd.h ../../include/device.h autoconf.h
+lrandom_att.o: ../../dev/lamebus/lrandom_att.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/lib.h ../../include/cdefs.h \
+  opt-noasserts.h ../../dev/lamebus/lamebus.h ../../include/cpu.h \
+  ../../include/spinlock.h includelinks/machine/spinlock.h \
+  ../../include/threadlist.h includelinks/machine/vm.h \
+  ../../dev/lamebus/lrandom.h autoconf.h
+lrandom.o: ../../dev/lamebus/lrandom.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/lib.h ../../include/cdefs.h \
+  opt-noasserts.h ../../include/uio.h ../../include/kern/iovec.h \
+  includelinks/platform/bus.h includelinks/machine/vm.h \
+  ../../dev/lamebus/lamebus.h ../../include/cpu.h \
+  ../../include/spinlock.h includelinks/machine/spinlock.h \
+  ../../include/threadlist.h ../../dev/lamebus/lrandom.h autoconf.h
+lser_att.o: ../../dev/lamebus/lser_att.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/lib.h ../../include/cdefs.h \
+  opt-noasserts.h ../../dev/lamebus/lamebus.h ../../include/cpu.h \
+  ../../include/spinlock.h includelinks/machine/spinlock.h \
+  ../../include/threadlist.h includelinks/machine/vm.h \
+  ../../dev/lamebus/lser.h autoconf.h
+lser.o: ../../dev/lamebus/lser.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/lib.h ../../include/cdefs.h \
+  opt-noasserts.h ../../include/spinlock.h \
+  includelinks/machine/spinlock.h includelinks/platform/bus.h \
+  includelinks/machine/vm.h ../../dev/lamebus/lamebus.h \
+  ../../include/cpu.h ../../include/threadlist.h ../../dev/lamebus/lser.h \
+  autoconf.h
+ltimer_att.o: ../../dev/lamebus/ltimer_att.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/lib.h ../../include/cdefs.h \
+  opt-noasserts.h ../../dev/lamebus/lamebus.h ../../include/cpu.h \
+  ../../include/spinlock.h includelinks/machine/spinlock.h \
+  ../../include/threadlist.h includelinks/machine/vm.h \
+  ../../dev/lamebus/ltimer.h autoconf.h
+ltimer.o: ../../dev/lamebus/ltimer.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/lib.h ../../include/cdefs.h \
+  opt-noasserts.h ../../include/spl.h ../../include/clock.h \
+  opt-synchprobs.h includelinks/platform/bus.h includelinks/machine/vm.h \
+  ../../dev/lamebus/lamebus.h ../../include/cpu.h \
+  ../../include/spinlock.h includelinks/machine/spinlock.h \
+  ../../include/threadlist.h ../../dev/lamebus/ltimer.h autoconf.h
+ltrace_att.o: ../../dev/lamebus/ltrace_att.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/lib.h ../../include/cdefs.h \
+  opt-noasserts.h ../../dev/lamebus/lamebus.h ../../include/cpu.h \
+  ../../include/spinlock.h includelinks/machine/spinlock.h \
+  ../../include/threadlist.h includelinks/machine/vm.h \
+  ../../dev/lamebus/ltrace.h autoconf.h
+ltrace.o: ../../dev/lamebus/ltrace.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/lib.h ../../include/cdefs.h \
+  opt-noasserts.h includelinks/platform/bus.h includelinks/machine/vm.h \
+  ../../dev/lamebus/lamebus.h ../../include/cpu.h \
+  ../../include/spinlock.h includelinks/machine/spinlock.h \
+  ../../include/threadlist.h ../../dev/lamebus/ltrace.h autoconf.h
+random_lrandom.o: ../../dev/lamebus/random_lrandom.c \
+  ../../include/types.h ../../include/kern/types.h \
+  includelinks/kern/machine/types.h includelinks/machine/types.h \
+  ../../include/lib.h ../../include/cdefs.h opt-noasserts.h \
+  ../../dev/generic/random.h ../../include/device.h \
+  ../../dev/lamebus/lrandom.h autoconf.h
+rtclock_ltimer.o: ../../dev/lamebus/rtclock_ltimer.c \
+  ../../include/types.h ../../include/kern/types.h \
+  includelinks/kern/machine/types.h includelinks/machine/types.h \
+  ../../include/lib.h ../../include/cdefs.h opt-noasserts.h \
+  ../../dev/generic/rtclock.h ../../dev/lamebus/ltimer.h autoconf.h
+sfs_fs.o: ../../fs/sfs/sfs_fs.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/kern/errno.h \
+  ../../include/lib.h ../../include/cdefs.h opt-noasserts.h \
+  ../../include/array.h ../../include/bitmap.h ../../include/uio.h \
+  ../../include/kern/iovec.h ../../include/vfs.h ../../include/device.h \
+  ../../include/sfs.h ../../include/fs.h ../../include/vnode.h \
+  ../../include/kern/sfs.h
+sfs_io.o: ../../fs/sfs/sfs_io.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/kern/errno.h \
+  ../../include/lib.h ../../include/cdefs.h opt-noasserts.h \
+  ../../include/uio.h ../../include/kern/iovec.h ../../include/vfs.h \
+  ../../include/array.h ../../include/device.h ../../include/sfs.h \
+  ../../include/fs.h ../../include/vnode.h ../../include/kern/sfs.h
+sfs_vnode.o: ../../fs/sfs/sfs_vnode.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/kern/errno.h \
+  ../../include/kern/fcntl.h ../../include/stat.h \
+  ../../include/kern/stat.h ../../include/kern/stattypes.h \
+  ../../include/lib.h ../../include/cdefs.h opt-noasserts.h \
+  ../../include/array.h ../../include/bitmap.h ../../include/uio.h \
+  ../../include/kern/iovec.h ../../include/synch.h \
+  ../../include/spinlock.h includelinks/machine/spinlock.h \
+  ../../include/vfs.h ../../include/device.h ../../include/sfs.h \
+  ../../include/fs.h ../../include/vnode.h ../../include/kern/sfs.h
+array.o: ../../lib/array.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/kern/errno.h \
+  ../../include/lib.h ../../include/cdefs.h opt-noasserts.h \
+  ../../include/array.h
+bitmap.o: ../../lib/bitmap.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/kern/errno.h \
+  ../../include/lib.h ../../include/cdefs.h opt-noasserts.h \
+  ../../include/bitmap.h
+bswap.o: ../../lib/bswap.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/endian.h \
+  ../../include/kern/endian.h includelinks/kern/machine/endian.h
+kgets.o: ../../lib/kgets.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/lib.h ../../include/cdefs.h \
+  opt-noasserts.h
+kprintf.o: ../../lib/kprintf.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/kern/unistd.h \
+  ../../include/stdarg.h ../../include/cdefs.h ../../include/lib.h \
+  opt-noasserts.h ../../include/spl.h ../../include/thread.h \
+  ../../include/array.h ../../include/spinlock.h \
+  includelinks/machine/spinlock.h ../../include/threadlist.h \
+  includelinks/machine/thread.h ../../include/setjmp.h \
+  includelinks/kern/machine/setjmp.h ../../include/current.h \
+  includelinks/machine/current.h ../../include/synch.h \
+  ../../include/mainbus.h ../../include/vfs.h
+list.o: ../../lib/list.c ../../include/types.h ../../include/kern/types.h \
+  includelinks/kern/machine/types.h includelinks/machine/types.h \
+  ../../include/kern/errno.h ../../include/lib.h ../../include/cdefs.h \
+  opt-noasserts.h ../../include/list.h
+misc.o: ../../lib/misc.c ../../include/types.h ../../include/kern/types.h \
+  includelinks/kern/machine/types.h includelinks/machine/types.h \
+  ../../include/kern/errmsg.h ../../include/lib.h ../../include/cdefs.h \
+  opt-noasserts.h
+queue.o: ../../lib/queue.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/kern/errno.h \
+  ../../include/lib.h ../../include/cdefs.h opt-noasserts.h \
+  ../../include/queue.h
+uio.o: ../../lib/uio.c ../../include/types.h ../../include/kern/types.h \
+  includelinks/kern/machine/types.h includelinks/machine/types.h \
+  ../../include/lib.h ../../include/cdefs.h opt-noasserts.h \
+  ../../include/uio.h ../../include/kern/iovec.h ../../include/proc.h \
+  ../../include/spinlock.h includelinks/machine/spinlock.h \
+  ../../include/thread.h ../../include/array.h ../../include/threadlist.h \
+  includelinks/machine/thread.h ../../include/setjmp.h \
+  includelinks/kern/machine/setjmp.h ../../include/limits.h \
+  ../../include/kern/limits.h ../../include/synch.h ../../include/list.h \
+  ../../include/current.h includelinks/machine/current.h \
+  ../../include/copyinout.h
+proc.o: ../../proc/proc.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/proc.h \
+  ../../include/spinlock.h ../../include/cdefs.h \
+  includelinks/machine/spinlock.h ../../include/thread.h \
+  ../../include/array.h ../../include/lib.h opt-noasserts.h \
+  ../../include/threadlist.h includelinks/machine/thread.h \
+  ../../include/setjmp.h includelinks/kern/machine/setjmp.h \
+  ../../include/limits.h ../../include/kern/limits.h \
+  ../../include/synch.h ../../include/list.h ../../include/current.h \
+  includelinks/machine/current.h ../../include/addrspace.h \
+  ../../include/vm.h includelinks/machine/vm.h ../../include/vnode.h \
+  ../../include/vfs.h ../../include/kern/fcntl.h \
+  ../../include/kern/errno.h
+main.o: ../../startup/main.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/kern/errno.h \
+  ../../include/kern/reboot.h ../../include/kern/unistd.h \
+  ../../include/lib.h ../../include/cdefs.h opt-noasserts.h \
+  ../../include/spl.h ../../include/clock.h opt-synchprobs.h \
+  ../../include/thread.h ../../include/array.h ../../include/spinlock.h \
+  includelinks/machine/spinlock.h ../../include/threadlist.h \
+  includelinks/machine/thread.h ../../include/setjmp.h \
+  includelinks/kern/machine/setjmp.h ../../include/proc.h \
+  ../../include/limits.h ../../include/kern/limits.h \
+  ../../include/synch.h ../../include/list.h ../../include/current.h \
+  includelinks/machine/current.h ../../include/vm.h \
+  includelinks/machine/vm.h ../../include/mainbus.h ../../include/vfs.h \
+  ../../include/device.h ../../include/syscall.h ../../include/test.h \
+  ../../include/version.h autoconf.h
+menu.o: ../../startup/menu.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/kern/errno.h \
+  ../../include/kern/reboot.h ../../include/kern/unistd.h \
+  ../../include/limits.h ../../include/kern/limits.h ../../include/lib.h \
+  ../../include/cdefs.h opt-noasserts.h ../../include/uio.h \
+  ../../include/kern/iovec.h ../../include/clock.h opt-synchprobs.h \
+  ../../include/thread.h ../../include/array.h ../../include/spinlock.h \
+  includelinks/machine/spinlock.h ../../include/threadlist.h \
+  includelinks/machine/thread.h ../../include/setjmp.h \
+  includelinks/kern/machine/setjmp.h ../../include/proc.h \
+  ../../include/synch.h ../../include/list.h ../../include/vfs.h \
+  ../../include/sfs.h ../../include/fs.h ../../include/vnode.h \
+  ../../include/kern/sfs.h ../../include/syscall.h ../../include/test.h \
+  opt-synchprobs.h opt-sfs.h opt-net.h
+file_syscalls.o: ../../syscall/file_syscalls.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/kern/errno.h \
+  ../../include/kern/unistd.h ../../include/lib.h ../../include/cdefs.h \
+  opt-noasserts.h ../../include/uio.h ../../include/kern/iovec.h \
+  ../../include/syscall.h ../../include/vnode.h ../../include/vfs.h \
+  ../../include/array.h ../../include/current.h \
+  includelinks/machine/current.h ../../include/thread.h \
+  ../../include/spinlock.h includelinks/machine/spinlock.h \
+  ../../include/threadlist.h includelinks/machine/thread.h \
+  ../../include/setjmp.h includelinks/kern/machine/setjmp.h \
+  ../../include/proc.h ../../include/limits.h ../../include/kern/limits.h \
+  ../../include/synch.h ../../include/list.h
+loadelf.o: ../../syscall/loadelf.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/kern/errno.h \
+  ../../include/lib.h ../../include/cdefs.h opt-noasserts.h \
+  ../../include/uio.h ../../include/kern/iovec.h ../../include/proc.h \
+  ../../include/spinlock.h includelinks/machine/spinlock.h \
+  ../../include/thread.h ../../include/array.h ../../include/threadlist.h \
+  includelinks/machine/thread.h ../../include/setjmp.h \
+  includelinks/kern/machine/setjmp.h ../../include/limits.h \
+  ../../include/kern/limits.h ../../include/synch.h ../../include/list.h \
+  ../../include/current.h includelinks/machine/current.h \
+  ../../include/addrspace.h ../../include/vm.h includelinks/machine/vm.h \
+  ../../include/vnode.h ../../include/elf.h includelinks/machine/elf.h
+proc_syscalls.o: ../../syscall/proc_syscalls.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/kern/errno.h \
+  ../../include/kern/unistd.h ../../include/kern/wait.h \
+  includelinks/mips/trapframe.h ../../include/lib.h ../../include/cdefs.h \
+  opt-noasserts.h ../../include/vfs.h ../../include/array.h \
+  ../../include/vnode.h ../../include/syscall.h ../../include/current.h \
+  includelinks/machine/current.h ../../include/thread.h \
+  ../../include/spinlock.h includelinks/machine/spinlock.h \
+  ../../include/threadlist.h includelinks/machine/thread.h \
+  ../../include/setjmp.h includelinks/kern/machine/setjmp.h \
+  ../../include/proc.h ../../include/limits.h ../../include/kern/limits.h \
+  ../../include/synch.h ../../include/list.h ../../include/addrspace.h \
+  ../../include/vm.h includelinks/machine/vm.h ../../include/copyinout.h
+runprogram.o: ../../syscall/runprogram.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/kern/errno.h \
+  ../../include/kern/fcntl.h ../../include/lib.h ../../include/cdefs.h \
+  opt-noasserts.h ../../include/proc.h ../../include/spinlock.h \
+  includelinks/machine/spinlock.h ../../include/thread.h \
+  ../../include/array.h ../../include/threadlist.h \
+  includelinks/machine/thread.h ../../include/setjmp.h \
+  includelinks/kern/machine/setjmp.h ../../include/limits.h \
+  ../../include/kern/limits.h ../../include/synch.h ../../include/list.h \
+  ../../include/current.h includelinks/machine/current.h \
+  ../../include/addrspace.h ../../include/vm.h includelinks/machine/vm.h \
+  ../../include/vfs.h ../../include/syscall.h ../../include/test.h
+time_syscalls.o: ../../syscall/time_syscalls.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/clock.h opt-synchprobs.h \
+  ../../include/copyinout.h ../../include/syscall.h
+arraytest.o: ../../test/arraytest.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/lib.h ../../include/cdefs.h \
+  opt-noasserts.h ../../include/array.h ../../include/test.h
+bitmaptest.o: ../../test/bitmaptest.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/lib.h ../../include/cdefs.h \
+  opt-noasserts.h ../../include/bitmap.h ../../include/test.h
+fstest.o: ../../test/fstest.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/kern/errno.h \
+  ../../include/kern/fcntl.h ../../include/lib.h ../../include/cdefs.h \
+  opt-noasserts.h ../../include/uio.h ../../include/kern/iovec.h \
+  ../../include/thread.h ../../include/array.h ../../include/spinlock.h \
+  includelinks/machine/spinlock.h ../../include/threadlist.h \
+  includelinks/machine/thread.h ../../include/setjmp.h \
+  includelinks/kern/machine/setjmp.h ../../include/synch.h \
+  ../../include/vfs.h ../../include/fs.h ../../include/vnode.h \
+  ../../include/test.h
+malloctest.o: ../../test/malloctest.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/lib.h ../../include/cdefs.h \
+  opt-noasserts.h ../../include/thread.h ../../include/array.h \
+  ../../include/spinlock.h includelinks/machine/spinlock.h \
+  ../../include/threadlist.h includelinks/machine/thread.h \
+  ../../include/setjmp.h includelinks/kern/machine/setjmp.h \
+  ../../include/synch.h ../../include/test.h
+synchtest.o: ../../test/synchtest.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/lib.h ../../include/cdefs.h \
+  opt-noasserts.h ../../include/clock.h opt-synchprobs.h \
+  ../../include/thread.h ../../include/array.h ../../include/spinlock.h \
+  includelinks/machine/spinlock.h ../../include/threadlist.h \
+  includelinks/machine/thread.h ../../include/setjmp.h \
+  includelinks/kern/machine/setjmp.h ../../include/synch.h \
+  ../../include/test.h
+threadtest.o: ../../test/threadtest.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/lib.h ../../include/cdefs.h \
+  opt-noasserts.h ../../include/thread.h ../../include/array.h \
+  ../../include/spinlock.h includelinks/machine/spinlock.h \
+  ../../include/threadlist.h includelinks/machine/thread.h \
+  ../../include/setjmp.h includelinks/kern/machine/setjmp.h \
+  ../../include/synch.h ../../include/test.h
+tt3.o: ../../test/tt3.c ../../include/types.h ../../include/kern/types.h \
+  includelinks/kern/machine/types.h includelinks/machine/types.h \
+  ../../include/lib.h ../../include/cdefs.h opt-noasserts.h \
+  ../../include/wchan.h ../../include/thread.h ../../include/array.h \
+  ../../include/spinlock.h includelinks/machine/spinlock.h \
+  ../../include/threadlist.h includelinks/machine/thread.h \
+  ../../include/setjmp.h includelinks/kern/machine/setjmp.h \
+  ../../include/synch.h ../../include/test.h opt-synchprobs.h
+uw-tests.o: ../../test/uw-tests.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/synch.h \
+  ../../include/spinlock.h ../../include/cdefs.h \
+  includelinks/machine/spinlock.h ../../include/thread.h \
+  ../../include/array.h ../../include/lib.h opt-noasserts.h \
+  ../../include/threadlist.h includelinks/machine/thread.h \
+  ../../include/setjmp.h includelinks/kern/machine/setjmp.h \
+  ../../include/test.h ../../include/uw-vmstats.h
+clock.o: ../../thread/clock.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/lib.h ../../include/cdefs.h \
+  opt-noasserts.h ../../include/cpu.h ../../include/spinlock.h \
+  includelinks/machine/spinlock.h ../../include/threadlist.h \
+  includelinks/machine/vm.h ../../include/wchan.h ../../include/clock.h \
+  opt-synchprobs.h ../../include/thread.h ../../include/array.h \
+  includelinks/machine/thread.h ../../include/setjmp.h \
+  includelinks/kern/machine/setjmp.h ../../dev/lamebus/ltimer.h \
+  ../../include/current.h includelinks/machine/current.h
+spinlock.o: ../../thread/spinlock.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/lib.h ../../include/cdefs.h \
+  opt-noasserts.h ../../include/cpu.h ../../include/spinlock.h \
+  includelinks/machine/spinlock.h ../../include/threadlist.h \
+  includelinks/machine/vm.h ../../include/spl.h ../../include/current.h \
+  includelinks/machine/current.h ../../include/thread.h \
+  ../../include/array.h includelinks/machine/thread.h \
+  ../../include/setjmp.h includelinks/kern/machine/setjmp.h
+spl.o: ../../thread/spl.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/lib.h ../../include/cdefs.h \
+  opt-noasserts.h ../../include/cpu.h ../../include/spinlock.h \
+  includelinks/machine/spinlock.h ../../include/threadlist.h \
+  includelinks/machine/vm.h ../../include/spl.h ../../include/thread.h \
+  ../../include/array.h includelinks/machine/thread.h \
+  ../../include/setjmp.h includelinks/kern/machine/setjmp.h \
+  ../../include/current.h includelinks/machine/current.h
+synch.o: ../../thread/synch.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/lib.h ../../include/cdefs.h \
+  opt-noasserts.h ../../include/spinlock.h \
+  includelinks/machine/spinlock.h ../../include/wchan.h \
+  ../../include/thread.h ../../include/array.h ../../include/threadlist.h \
+  includelinks/machine/thread.h ../../include/setjmp.h \
+  includelinks/kern/machine/setjmp.h ../../include/current.h \
+  includelinks/machine/current.h ../../include/synch.h
+thread.o: ../../thread/thread.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/kern/errno.h \
+  ../../include/lib.h ../../include/cdefs.h opt-noasserts.h \
+  ../../include/array.h ../../include/cpu.h ../../include/spinlock.h \
+  includelinks/machine/spinlock.h ../../include/threadlist.h \
+  includelinks/machine/vm.h ../../include/spl.h ../../include/wchan.h \
+  ../../include/thread.h includelinks/machine/thread.h \
+  ../../include/setjmp.h includelinks/kern/machine/setjmp.h \
+  ../../include/threadprivate.h ../../include/proc.h \
+  ../../include/limits.h ../../include/kern/limits.h \
+  ../../include/synch.h ../../include/list.h ../../include/current.h \
+  includelinks/machine/current.h ../../include/addrspace.h \
+  ../../include/vm.h ../../include/mainbus.h ../../include/vnode.h \
+  opt-synchprobs.h
+threadlist.o: ../../thread/threadlist.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/lib.h ../../include/cdefs.h \
+  opt-noasserts.h ../../include/thread.h ../../include/array.h \
+  ../../include/spinlock.h includelinks/machine/spinlock.h \
+  ../../include/threadlist.h includelinks/machine/thread.h \
+  ../../include/setjmp.h includelinks/kern/machine/setjmp.h
+device.o: ../../vfs/device.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/kern/errno.h \
+  ../../include/kern/fcntl.h ../../include/stat.h \
+  ../../include/kern/stat.h ../../include/kern/stattypes.h \
+  ../../include/lib.h ../../include/cdefs.h opt-noasserts.h \
+  ../../include/uio.h ../../include/kern/iovec.h ../../include/synch.h \
+  ../../include/spinlock.h includelinks/machine/spinlock.h \
+  ../../include/vnode.h ../../include/device.h
+devnull.o: ../../vfs/devnull.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/kern/errno.h \
+  ../../include/lib.h ../../include/cdefs.h opt-noasserts.h \
+  ../../include/uio.h ../../include/kern/iovec.h ../../include/vfs.h \
+  ../../include/array.h ../../include/device.h
+vfscwd.o: ../../vfs/vfscwd.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/kern/errno.h \
+  ../../include/stat.h ../../include/kern/stat.h \
+  ../../include/kern/stattypes.h ../../include/lib.h \
+  ../../include/cdefs.h opt-noasserts.h ../../include/uio.h \
+  ../../include/kern/iovec.h ../../include/proc.h \
+  ../../include/spinlock.h includelinks/machine/spinlock.h \
+  ../../include/thread.h ../../include/array.h ../../include/threadlist.h \
+  includelinks/machine/thread.h ../../include/setjmp.h \
+  includelinks/kern/machine/setjmp.h ../../include/limits.h \
+  ../../include/kern/limits.h ../../include/synch.h ../../include/list.h \
+  ../../include/current.h includelinks/machine/current.h \
+  ../../include/vfs.h ../../include/fs.h ../../include/vnode.h
+vfslist.o: ../../vfs/vfslist.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/kern/errno.h \
+  ../../include/lib.h ../../include/cdefs.h opt-noasserts.h \
+  ../../include/array.h ../../include/synch.h ../../include/spinlock.h \
+  includelinks/machine/spinlock.h ../../include/vfs.h ../../include/fs.h \
+  ../../include/vnode.h ../../include/device.h
+vfslookup.o: ../../vfs/vfslookup.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/kern/errno.h \
+  ../../include/limits.h ../../include/kern/limits.h ../../include/lib.h \
+  ../../include/cdefs.h opt-noasserts.h ../../include/synch.h \
+  ../../include/spinlock.h includelinks/machine/spinlock.h \
+  ../../include/vfs.h ../../include/array.h ../../include/fs.h \
+  ../../include/vnode.h
+vfspath.o: ../../vfs/vfspath.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/kern/errno.h \
+  ../../include/kern/fcntl.h ../../include/limits.h \
+  ../../include/kern/limits.h ../../include/lib.h ../../include/cdefs.h \
+  opt-noasserts.h ../../include/vfs.h ../../include/array.h \
+  ../../include/vnode.h
+vnode.o: ../../vfs/vnode.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/kern/errno.h \
+  ../../include/lib.h ../../include/cdefs.h opt-noasserts.h \
+  ../../include/synch.h ../../include/spinlock.h \
+  includelinks/machine/spinlock.h ../../include/vfs.h \
+  ../../include/array.h ../../include/vnode.h
+kmalloc.o: ../../vm/kmalloc.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/lib.h ../../include/cdefs.h \
+  opt-noasserts.h ../../include/spinlock.h \
+  includelinks/machine/spinlock.h ../../include/vm.h \
+  includelinks/machine/vm.h
+uw-vmstats.o: ../../vm/uw-vmstats.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/lib.h ../../include/cdefs.h \
+  opt-noasserts.h ../../include/synch.h ../../include/spinlock.h \
+  includelinks/machine/spinlock.h ../../include/spl.h \
+  ../../include/uw-vmstats.h
+trap.o: ../../arch/mips/locore/trap.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/signal.h \
+  includelinks/kern/machine/signal.h ../../include/kern/signal.h \
+  ../../include/lib.h ../../include/cdefs.h opt-noasserts.h \
+  includelinks/mips/specialreg.h includelinks/mips/trapframe.h \
+  ../../include/cpu.h ../../include/spinlock.h \
+  includelinks/machine/spinlock.h ../../include/threadlist.h \
+  includelinks/machine/vm.h ../../include/spl.h ../../include/thread.h \
+  ../../include/array.h includelinks/machine/thread.h \
+  ../../include/setjmp.h includelinks/kern/machine/setjmp.h \
+  ../../include/current.h includelinks/machine/current.h \
+  ../../include/vm.h ../../include/mainbus.h ../../include/syscall.h
+syscall.o: ../../arch/mips/syscall/syscall.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/kern/errno.h \
+  ../../include/kern/syscall.h ../../include/lib.h ../../include/cdefs.h \
+  opt-noasserts.h includelinks/mips/trapframe.h ../../include/thread.h \
+  ../../include/array.h ../../include/spinlock.h \
+  includelinks/machine/spinlock.h ../../include/threadlist.h \
+  includelinks/machine/thread.h ../../include/setjmp.h \
+  includelinks/kern/machine/setjmp.h ../../include/current.h \
+  includelinks/machine/current.h ../../include/syscall.h
+cpu.o: ../../arch/mips/thread/cpu.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/lib.h ../../include/cdefs.h \
+  opt-noasserts.h includelinks/mips/specialreg.h \
+  includelinks/mips/trapframe.h includelinks/platform/maxcpus.h \
+  ../../include/cpu.h ../../include/spinlock.h \
+  includelinks/machine/spinlock.h ../../include/threadlist.h \
+  includelinks/machine/vm.h ../../include/thread.h ../../include/array.h \
+  includelinks/machine/thread.h ../../include/setjmp.h \
+  includelinks/kern/machine/setjmp.h
+switchframe.o: ../../arch/mips/thread/switchframe.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/lib.h ../../include/cdefs.h \
+  opt-noasserts.h ../../include/thread.h ../../include/array.h \
+  ../../include/spinlock.h includelinks/machine/spinlock.h \
+  ../../include/threadlist.h includelinks/machine/thread.h \
+  ../../include/setjmp.h includelinks/kern/machine/setjmp.h \
+  ../../include/threadprivate.h ../../arch/mips/thread/switchframe.h
+switch.o: ../../arch/mips/thread/switch.S \
+  includelinks/kern/mips/regdefs.h
+thread_machdep.o: ../../arch/mips/thread/thread_machdep.c \
+  ../../include/types.h ../../include/kern/types.h \
+  includelinks/kern/machine/types.h includelinks/machine/types.h \
+  ../../include/lib.h ../../include/cdefs.h opt-noasserts.h \
+  ../../include/thread.h ../../include/array.h ../../include/spinlock.h \
+  includelinks/machine/spinlock.h ../../include/threadlist.h \
+  includelinks/machine/thread.h ../../include/setjmp.h \
+  includelinks/kern/machine/setjmp.h ../../include/threadprivate.h
+threadstart.o: ../../arch/mips/thread/threadstart.S \
+  includelinks/kern/mips/regdefs.h
+dumbvm.o: ../../arch/mips/vm/dumbvm.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/kern/errno.h \
+  ../../include/lib.h ../../include/cdefs.h opt-noasserts.h \
+  ../../include/spl.h ../../include/spinlock.h \
+  includelinks/machine/spinlock.h ../../include/proc.h \
+  ../../include/thread.h ../../include/array.h ../../include/threadlist.h \
+  includelinks/machine/thread.h ../../include/setjmp.h \
+  includelinks/kern/machine/setjmp.h ../../include/limits.h \
+  ../../include/kern/limits.h ../../include/synch.h ../../include/list.h \
+  ../../include/current.h includelinks/machine/current.h \
+  includelinks/mips/tlb.h ../../include/addrspace.h ../../include/vm.h \
+  includelinks/machine/vm.h
+ram.o: ../../arch/mips/vm/ram.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/lib.h ../../include/cdefs.h \
+  opt-noasserts.h ../../include/vm.h includelinks/machine/vm.h \
+  ../../include/mainbus.h
+adddi3.o: ../../../common/gcc-millicode/adddi3.c \
+  ../../../common/gcc-millicode/longlong.h ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/endian.h \
+  ../../include/kern/endian.h includelinks/kern/machine/endian.h \
+  ../../include/limits.h ../../include/kern/limits.h
+anddi3.o: ../../../common/gcc-millicode/anddi3.c \
+  ../../../common/gcc-millicode/longlong.h ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/endian.h \
+  ../../include/kern/endian.h includelinks/kern/machine/endian.h \
+  ../../include/limits.h ../../include/kern/limits.h
+ashldi3.o: ../../../common/gcc-millicode/ashldi3.c \
+  ../../../common/gcc-millicode/longlong.h ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/endian.h \
+  ../../include/kern/endian.h includelinks/kern/machine/endian.h \
+  ../../include/limits.h ../../include/kern/limits.h
+ashrdi3.o: ../../../common/gcc-millicode/ashrdi3.c \
+  ../../../common/gcc-millicode/longlong.h ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/endian.h \
+  ../../include/kern/endian.h includelinks/kern/machine/endian.h \
+  ../../include/limits.h ../../include/kern/limits.h
+cmpdi2.o: ../../../common/gcc-millicode/cmpdi2.c \
+  ../../../common/gcc-millicode/longlong.h ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/endian.h \
+  ../../include/kern/endian.h includelinks/kern/machine/endian.h \
+  ../../include/limits.h ../../include/kern/limits.h
+divdi3.o: ../../../common/gcc-millicode/divdi3.c \
+  ../../../common/gcc-millicode/longlong.h ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/endian.h \
+  ../../include/kern/endian.h includelinks/kern/machine/endian.h \
+  ../../include/limits.h ../../include/kern/limits.h
+iordi3.o: ../../../common/gcc-millicode/iordi3.c \
+  ../../../common/gcc-millicode/longlong.h ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/endian.h \
+  ../../include/kern/endian.h includelinks/kern/machine/endian.h \
+  ../../include/limits.h ../../include/kern/limits.h
+lshldi3.o: ../../../common/gcc-millicode/lshldi3.c \
+  ../../../common/gcc-millicode/longlong.h ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/endian.h \
+  ../../include/kern/endian.h includelinks/kern/machine/endian.h \
+  ../../include/limits.h ../../include/kern/limits.h
+lshrdi3.o: ../../../common/gcc-millicode/lshrdi3.c \
+  ../../../common/gcc-millicode/longlong.h ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/endian.h \
+  ../../include/kern/endian.h includelinks/kern/machine/endian.h \
+  ../../include/limits.h ../../include/kern/limits.h
+moddi3.o: ../../../common/gcc-millicode/moddi3.c \
+  ../../../common/gcc-millicode/longlong.h ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/endian.h \
+  ../../include/kern/endian.h includelinks/kern/machine/endian.h \
+  ../../include/limits.h ../../include/kern/limits.h
+muldi3.o: ../../../common/gcc-millicode/muldi3.c \
+  ../../../common/gcc-millicode/longlong.h ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/endian.h \
+  ../../include/kern/endian.h includelinks/kern/machine/endian.h \
+  ../../include/limits.h ../../include/kern/limits.h
+negdi2.o: ../../../common/gcc-millicode/negdi2.c \
+  ../../../common/gcc-millicode/longlong.h ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/endian.h \
+  ../../include/kern/endian.h includelinks/kern/machine/endian.h \
+  ../../include/limits.h ../../include/kern/limits.h
+notdi2.o: ../../../common/gcc-millicode/notdi2.c \
+  ../../../common/gcc-millicode/longlong.h ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/endian.h \
+  ../../include/kern/endian.h includelinks/kern/machine/endian.h \
+  ../../include/limits.h ../../include/kern/limits.h
+qdivrem.o: ../../../common/gcc-millicode/qdivrem.c \
+  ../../../common/gcc-millicode/longlong.h ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/endian.h \
+  ../../include/kern/endian.h includelinks/kern/machine/endian.h \
+  ../../include/limits.h ../../include/kern/limits.h
+subdi3.o: ../../../common/gcc-millicode/subdi3.c \
+  ../../../common/gcc-millicode/longlong.h ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/endian.h \
+  ../../include/kern/endian.h includelinks/kern/machine/endian.h \
+  ../../include/limits.h ../../include/kern/limits.h
+ucmpdi2.o: ../../../common/gcc-millicode/ucmpdi2.c \
+  ../../../common/gcc-millicode/longlong.h ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/endian.h \
+  ../../include/kern/endian.h includelinks/kern/machine/endian.h \
+  ../../include/limits.h ../../include/kern/limits.h
+udivdi3.o: ../../../common/gcc-millicode/udivdi3.c \
+  ../../../common/gcc-millicode/longlong.h ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/endian.h \
+  ../../include/kern/endian.h includelinks/kern/machine/endian.h \
+  ../../include/limits.h ../../include/kern/limits.h
+umoddi3.o: ../../../common/gcc-millicode/umoddi3.c \
+  ../../../common/gcc-millicode/longlong.h ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/endian.h \
+  ../../include/kern/endian.h includelinks/kern/machine/endian.h \
+  ../../include/limits.h ../../include/kern/limits.h
+xordi3.o: ../../../common/gcc-millicode/xordi3.c \
+  ../../../common/gcc-millicode/longlong.h ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/endian.h \
+  ../../include/kern/endian.h includelinks/kern/machine/endian.h \
+  ../../include/limits.h ../../include/kern/limits.h
+setjmp.o: ../../../common/libc/arch/mips/setjmp.S \
+  includelinks/kern/mips/regdefs.h
+copyinout.o: ../../vm/copyinout.c ../../include/types.h \
+  ../../include/kern/types.h includelinks/kern/machine/types.h \
+  includelinks/machine/types.h ../../include/kern/errno.h \
+  ../../include/lib.h ../../include/cdefs.h opt-noasserts.h \
+  ../../include/setjmp.h includelinks/kern/machine/setjmp.h \
+  ../../include/thread.h ../../include/array.h ../../include/spinlock.h \
+  includelinks/machine/spinlock.h ../../include/threadlist.h \
+  includelinks/machine/thread.h ../../include/current.h \
+  includelinks/machine/current.h ../../include/vm.h \
+  includelinks/machine/vm.h ../../include/copyinout.h
+cache-mips161.o: ../../arch/mips/locore/cache-mips161.S \
+  includelinks/kern/mips/regdefs.h
+exception-mips1.o: ../../arch/mips/locore/exception-mips1.S \
+  includelinks/kern/mips/regdefs.h includelinks/mips/specialreg.h
+tlb-mips1.o: ../../arch/mips/vm/tlb-mips1.S \
+  includelinks/kern/mips/regdefs.h includelinks/mips/specialreg.h
+lamebus_machdep.o: ../../arch/sys161/dev/lamebus_machdep.c \
+  ../../include/types.h ../../include/kern/types.h \
+  includelinks/kern/machine/types.h includelinks/machine/types.h \
+  ../../include/kern/unistd.h ../../include/lib.h ../../include/cdefs.h \
+  opt-noasserts.h includelinks/mips/trapframe.h ../../include/cpu.h \
+  ../../include/spinlock.h includelinks/machine/spinlock.h \
+  ../../include/threadlist.h includelinks/machine/vm.h \
+  ../../include/spl.h ../../include/clock.h opt-synchprobs.h \
+  ../../include/thread.h ../../include/array.h \
+  includelinks/machine/thread.h ../../include/setjmp.h \
+  includelinks/kern/machine/setjmp.h ../../include/current.h \
+  includelinks/machine/current.h ../../include/synch.h \
+  ../../include/mainbus.h includelinks/sys161/bus.h \
+  ../../dev/lamebus/lamebus.h autoconf.h
+start.o: ../../arch/sys161/startup/start.S \
+  includelinks/kern/mips/regdefs.h includelinks/mips/specialreg.h

+ 15 - 0
kern/compile/ASST2/Makefile

@@ -0,0 +1,15 @@
+# Automatically generated by config; do not edit.
+#
+
+# Top of the kernel tree
+KTOP=../..
+# Top of the whole tree
+TOP=$(KTOP)/..
+# Debug vs. optimize
+KDEBUG=-g
+# Name of the kernel config file
+CONFNAME=ASST2
+
+.include "$(TOP)/mk/os161.config.mk"
+.include "files.mk"
+.include "$(TOP)/mk/os161.kernel.mk"

+ 410 - 0
kern/compile/ASST2/autoconf.c

@@ -0,0 +1,410 @@
+/* Automatically generated; do not edit */
+#include <types.h>
+#include <lib.h>
+#include "autoconf.h"
+
+static void autoconf_beep(struct beep_softc *, int);
+static void autoconf_con(struct con_softc *, int);
+static void autoconf_emu(struct emu_softc *, int);
+static void autoconf_lhd(struct lhd_softc *, int);
+static void autoconf_lrandom(struct lrandom_softc *, int);
+static void autoconf_lser(struct lser_softc *, int);
+static void autoconf_ltimer(struct ltimer_softc *, int);
+static void autoconf_ltrace(struct ltrace_softc *, int);
+static void autoconf_random(struct random_softc *, int);
+static void autoconf_rtclock(struct rtclock_softc *, int);
+static int nextunit_beep;
+static int nextunit_con;
+static int nextunit_emu;
+static int nextunit_lhd;
+static int nextunit_lrandom;
+static int nextunit_lser;
+static int nextunit_ltimer;
+static int nextunit_ltrace;
+static int nextunit_random;
+static int nextunit_rtclock;
+
+static
+int
+tryattach_emu_to_lamebus(int devunit, struct lamebus_softc *bus, int busunit)
+{
+	struct emu_softc *dev;
+	int result;
+
+	dev = attach_emu_to_lamebus(devunit, bus);
+	if (dev==NULL) {
+		return -1;
+	}
+	kprintf("emu%d at lamebus%d", devunit, busunit);
+	result = config_emu(dev, devunit);
+	if (result != 0) {
+		kprintf(": %s\n", strerror(result));
+		/* should really clean up dev */
+		return result;
+	}
+	kprintf("\n");
+	nextunit_emu = devunit+1;
+	autoconf_emu(dev, devunit);
+	return 0;
+}
+
+static
+int
+tryattach_ltrace_to_lamebus(int devunit, struct lamebus_softc *bus, int busunit)
+{
+	struct ltrace_softc *dev;
+	int result;
+
+	dev = attach_ltrace_to_lamebus(devunit, bus);
+	if (dev==NULL) {
+		return -1;
+	}
+	kprintf("ltrace%d at lamebus%d", devunit, busunit);
+	result = config_ltrace(dev, devunit);
+	if (result != 0) {
+		kprintf(": %s\n", strerror(result));
+		/* should really clean up dev */
+		return result;
+	}
+	kprintf("\n");
+	nextunit_ltrace = devunit+1;
+	autoconf_ltrace(dev, devunit);
+	return 0;
+}
+
+static
+int
+tryattach_ltimer_to_lamebus(int devunit, struct lamebus_softc *bus, int busunit)
+{
+	struct ltimer_softc *dev;
+	int result;
+
+	dev = attach_ltimer_to_lamebus(devunit, bus);
+	if (dev==NULL) {
+		return -1;
+	}
+	kprintf("ltimer%d at lamebus%d", devunit, busunit);
+	result = config_ltimer(dev, devunit);
+	if (result != 0) {
+		kprintf(": %s\n", strerror(result));
+		/* should really clean up dev */
+		return result;
+	}
+	kprintf("\n");
+	nextunit_ltimer = devunit+1;
+	autoconf_ltimer(dev, devunit);
+	return 0;
+}
+
+static
+int
+tryattach_lrandom_to_lamebus(int devunit, struct lamebus_softc *bus, int busunit)
+{
+	struct lrandom_softc *dev;
+	int result;
+
+	dev = attach_lrandom_to_lamebus(devunit, bus);
+	if (dev==NULL) {
+		return -1;
+	}
+	kprintf("lrandom%d at lamebus%d", devunit, busunit);
+	result = config_lrandom(dev, devunit);
+	if (result != 0) {
+		kprintf(": %s\n", strerror(result));
+		/* should really clean up dev */
+		return result;
+	}
+	kprintf("\n");
+	nextunit_lrandom = devunit+1;
+	autoconf_lrandom(dev, devunit);
+	return 0;
+}
+
+static
+int
+tryattach_lhd_to_lamebus(int devunit, struct lamebus_softc *bus, int busunit)
+{
+	struct lhd_softc *dev;
+	int result;
+
+	dev = attach_lhd_to_lamebus(devunit, bus);
+	if (dev==NULL) {
+		return -1;
+	}
+	kprintf("lhd%d at lamebus%d", devunit, busunit);
+	result = config_lhd(dev, devunit);
+	if (result != 0) {
+		kprintf(": %s\n", strerror(result));
+		/* should really clean up dev */
+		return result;
+	}
+	kprintf("\n");
+	nextunit_lhd = devunit+1;
+	autoconf_lhd(dev, devunit);
+	return 0;
+}
+
+static
+int
+tryattach_lser_to_lamebus(int devunit, struct lamebus_softc *bus, int busunit)
+{
+	struct lser_softc *dev;
+	int result;
+
+	dev = attach_lser_to_lamebus(devunit, bus);
+	if (dev==NULL) {
+		return -1;
+	}
+	kprintf("lser%d at lamebus%d", devunit, busunit);
+	result = config_lser(dev, devunit);
+	if (result != 0) {
+		kprintf(": %s\n", strerror(result));
+		/* should really clean up dev */
+		return result;
+	}
+	kprintf("\n");
+	nextunit_lser = devunit+1;
+	autoconf_lser(dev, devunit);
+	return 0;
+}
+
+static
+int
+tryattach_beep_to_ltimer(int devunit, struct ltimer_softc *bus, int busunit)
+{
+	struct beep_softc *dev;
+	int result;
+
+	dev = attach_beep_to_ltimer(devunit, bus);
+	if (dev==NULL) {
+		return -1;
+	}
+	kprintf("beep%d at ltimer%d", devunit, busunit);
+	result = config_beep(dev, devunit);
+	if (result != 0) {
+		kprintf(": %s\n", strerror(result));
+		/* should really clean up dev */
+		return result;
+	}
+	kprintf("\n");
+	nextunit_beep = devunit+1;
+	autoconf_beep(dev, devunit);
+	return 0;
+}
+
+static
+int
+tryattach_con_to_lser(int devunit, struct lser_softc *bus, int busunit)
+{
+	struct con_softc *dev;
+	int result;
+
+	dev = attach_con_to_lser(devunit, bus);
+	if (dev==NULL) {
+		return -1;
+	}
+	kprintf("con%d at lser%d", devunit, busunit);
+	result = config_con(dev, devunit);
+	if (result != 0) {
+		kprintf(": %s\n", strerror(result));
+		/* should really clean up dev */
+		return result;
+	}
+	kprintf("\n");
+	nextunit_con = devunit+1;
+	autoconf_con(dev, devunit);
+	return 0;
+}
+
+static
+int
+tryattach_rtclock_to_ltimer(int devunit, struct ltimer_softc *bus, int busunit)
+{
+	struct rtclock_softc *dev;
+	int result;
+
+	dev = attach_rtclock_to_ltimer(devunit, bus);
+	if (dev==NULL) {
+		return -1;
+	}
+	kprintf("rtclock%d at ltimer%d", devunit, busunit);
+	result = config_rtclock(dev, devunit);
+	if (result != 0) {
+		kprintf(": %s\n", strerror(result));
+		/* should really clean up dev */
+		return result;
+	}
+	kprintf("\n");
+	nextunit_rtclock = devunit+1;
+	autoconf_rtclock(dev, devunit);
+	return 0;
+}
+
+static
+int
+tryattach_random_to_lrandom(int devunit, struct lrandom_softc *bus, int busunit)
+{
+	struct random_softc *dev;
+	int result;
+
+	dev = attach_random_to_lrandom(devunit, bus);
+	if (dev==NULL) {
+		return -1;
+	}
+	kprintf("random%d at lrandom%d", devunit, busunit);
+	result = config_random(dev, devunit);
+	if (result != 0) {
+		kprintf(": %s\n", strerror(result));
+		/* should really clean up dev */
+		return result;
+	}
+	kprintf("\n");
+	nextunit_random = devunit+1;
+	autoconf_random(dev, devunit);
+	return 0;
+}
+
+
+static
+void
+autoconf_con(struct con_softc *bus, int busunit)
+{
+	(void)bus; (void)busunit;
+}
+
+static
+void
+autoconf_lser(struct lser_softc *bus, int busunit)
+{
+	(void)bus; (void)busunit;
+	{
+		if (nextunit_con <= 0) {
+			tryattach_con_to_lser(0, bus, busunit);
+		}
+	}
+}
+
+static
+void
+autoconf_lhd(struct lhd_softc *bus, int busunit)
+{
+	(void)bus; (void)busunit;
+}
+
+static
+void
+autoconf_emu(struct emu_softc *bus, int busunit)
+{
+	(void)bus; (void)busunit;
+}
+
+static
+void
+autoconf_random(struct random_softc *bus, int busunit)
+{
+	(void)bus; (void)busunit;
+}
+
+static
+void
+autoconf_ltimer(struct ltimer_softc *bus, int busunit)
+{
+	(void)bus; (void)busunit;
+	{
+		if (nextunit_beep <= 0) {
+			tryattach_beep_to_ltimer(0, bus, busunit);
+		}
+	}
+	{
+		if (nextunit_rtclock <= 0) {
+			tryattach_rtclock_to_ltimer(0, bus, busunit);
+		}
+	}
+}
+
+void
+autoconf_lamebus(struct lamebus_softc *bus, int busunit)
+{
+	(void)bus; (void)busunit;
+	{
+		int result, devunit=nextunit_emu;
+		do {
+			result = tryattach_emu_to_lamebus(devunit, bus, busunit);
+			devunit++;
+		} while (result==0);
+	}
+	{
+		int result, devunit=nextunit_ltrace;
+		do {
+			result = tryattach_ltrace_to_lamebus(devunit, bus, busunit);
+			devunit++;
+		} while (result==0);
+	}
+	{
+		int result, devunit=nextunit_ltimer;
+		do {
+			result = tryattach_ltimer_to_lamebus(devunit, bus, busunit);
+			devunit++;
+		} while (result==0);
+	}
+	{
+		int result, devunit=nextunit_lrandom;
+		do {
+			result = tryattach_lrandom_to_lamebus(devunit, bus, busunit);
+			devunit++;
+		} while (result==0);
+	}
+	{
+		int result, devunit=nextunit_lhd;
+		do {
+			result = tryattach_lhd_to_lamebus(devunit, bus, busunit);
+			devunit++;
+		} while (result==0);
+	}
+	{
+		int result, devunit=nextunit_lser;
+		do {
+			result = tryattach_lser_to_lamebus(devunit, bus, busunit);
+			devunit++;
+		} while (result==0);
+	}
+}
+
+static
+void
+autoconf_beep(struct beep_softc *bus, int busunit)
+{
+	(void)bus; (void)busunit;
+}
+
+static
+void
+autoconf_lrandom(struct lrandom_softc *bus, int busunit)
+{
+	(void)bus; (void)busunit;
+	{
+		if (nextunit_random <= 0) {
+			tryattach_random_to_lrandom(0, bus, busunit);
+		}
+	}
+}
+
+static
+void
+autoconf_rtclock(struct rtclock_softc *bus, int busunit)
+{
+	(void)bus; (void)busunit;
+}
+
+static
+void
+autoconf_ltrace(struct ltrace_softc *bus, int busunit)
+{
+	(void)bus; (void)busunit;
+}
+
+void
+pseudoconfig(void)
+{
+}
+

+ 43 - 0
kern/compile/ASST2/autoconf.h

@@ -0,0 +1,43 @@
+/* Automatically generated; do not edit */
+#ifndef _AUTOCONF_H_
+#define _AUTOCONF_H_
+
+struct lamebus_softc;
+struct emu_softc;
+struct ltrace_softc;
+struct ltimer_softc;
+struct lrandom_softc;
+struct lhd_softc;
+struct lser_softc;
+struct beep_softc;
+struct con_softc;
+struct rtclock_softc;
+struct random_softc;
+
+void autoconf_lamebus(struct lamebus_softc *dev, int unit);
+
+struct emu_softc *attach_emu_to_lamebus(int devunit, struct lamebus_softc *bus);
+struct ltrace_softc *attach_ltrace_to_lamebus(int devunit, struct lamebus_softc *bus);
+struct ltimer_softc *attach_ltimer_to_lamebus(int devunit, struct lamebus_softc *bus);
+struct lrandom_softc *attach_lrandom_to_lamebus(int devunit, struct lamebus_softc *bus);
+struct lhd_softc *attach_lhd_to_lamebus(int devunit, struct lamebus_softc *bus);
+struct lser_softc *attach_lser_to_lamebus(int devunit, struct lamebus_softc *bus);
+struct beep_softc *attach_beep_to_ltimer(int devunit, struct ltimer_softc *bus);
+struct con_softc *attach_con_to_lser(int devunit, struct lser_softc *bus);
+struct rtclock_softc *attach_rtclock_to_ltimer(int devunit, struct ltimer_softc *bus);
+struct random_softc *attach_random_to_lrandom(int devunit, struct lrandom_softc *bus);
+
+int config_emu(struct emu_softc *dev, int unit);
+int config_ltrace(struct ltrace_softc *dev, int unit);
+int config_ltimer(struct ltimer_softc *dev, int unit);
+int config_lrandom(struct lrandom_softc *dev, int unit);
+int config_lhd(struct lhd_softc *dev, int unit);
+int config_lser(struct lser_softc *dev, int unit);
+int config_beep(struct beep_softc *dev, int unit);
+int config_con(struct con_softc *dev, int unit);
+int config_rtclock(struct rtclock_softc *dev, int unit);
+int config_random(struct random_softc *dev, int unit);
+
+void pseudoconfig(void);
+
+#endif /* _AUTOCONF_H_ */

+ 114 - 0
kern/compile/ASST2/files.mk

@@ -0,0 +1,114 @@
+# Automatically generated by config; do not edit
+SRCS+=$(TOP)/common/libc/printf/__printf.c
+SRCS+=$(TOP)/common/libc/printf/snprintf.c
+SRCS+=$(TOP)/common/libc/stdlib/atoi.c
+SRCS+=$(TOP)/common/libc/string/bzero.c
+SRCS+=$(TOP)/common/libc/string/memcpy.c
+SRCS+=$(TOP)/common/libc/string/memmove.c
+SRCS+=$(TOP)/common/libc/string/strcat.c
+SRCS+=$(TOP)/common/libc/string/strchr.c
+SRCS+=$(TOP)/common/libc/string/strcmp.c
+SRCS+=$(TOP)/common/libc/string/strcpy.c
+SRCS+=$(TOP)/common/libc/string/strlen.c
+SRCS+=$(TOP)/common/libc/string/strrchr.c
+SRCS+=$(TOP)/common/libc/string/strtok_r.c
+SRCS+=$(KTOP)/compile/ASST2/autoconf.c
+SRCS+=$(KTOP)/dev/generic/beep.c
+SRCS+=$(KTOP)/dev/generic/console.c
+SRCS+=$(KTOP)/dev/generic/random.c
+SRCS+=$(KTOP)/dev/generic/rtclock.c
+SRCS+=$(KTOP)/dev/lamebus/beep_ltimer.c
+SRCS+=$(KTOP)/dev/lamebus/con_lser.c
+SRCS+=$(KTOP)/dev/lamebus/emu_att.c
+SRCS+=$(KTOP)/dev/lamebus/emu.c
+SRCS+=$(KTOP)/dev/lamebus/lamebus.c
+SRCS+=$(KTOP)/dev/lamebus/lhd_att.c
+SRCS+=$(KTOP)/dev/lamebus/lhd.c
+SRCS+=$(KTOP)/dev/lamebus/lrandom_att.c
+SRCS+=$(KTOP)/dev/lamebus/lrandom.c
+SRCS+=$(KTOP)/dev/lamebus/lser_att.c
+SRCS+=$(KTOP)/dev/lamebus/lser.c
+SRCS+=$(KTOP)/dev/lamebus/ltimer_att.c
+SRCS+=$(KTOP)/dev/lamebus/ltimer.c
+SRCS+=$(KTOP)/dev/lamebus/ltrace_att.c
+SRCS+=$(KTOP)/dev/lamebus/ltrace.c
+SRCS+=$(KTOP)/dev/lamebus/random_lrandom.c
+SRCS+=$(KTOP)/dev/lamebus/rtclock_ltimer.c
+SRCS+=$(KTOP)/fs/sfs/sfs_fs.c
+SRCS+=$(KTOP)/fs/sfs/sfs_io.c
+SRCS+=$(KTOP)/fs/sfs/sfs_vnode.c
+SRCS+=$(KTOP)/lib/array.c
+SRCS+=$(KTOP)/lib/bitmap.c
+SRCS+=$(KTOP)/lib/bswap.c
+SRCS+=$(KTOP)/lib/kgets.c
+SRCS+=$(KTOP)/lib/kprintf.c
+SRCS+=$(KTOP)/lib/list.c
+SRCS+=$(KTOP)/lib/misc.c
+SRCS+=$(KTOP)/lib/queue.c
+SRCS+=$(KTOP)/lib/uio.c
+SRCS.MACHINE.mips+=$(KTOP)/arch/mips/locore/trap.c
+SRCS.MACHINE.mips+=$(KTOP)/arch/mips/syscall/syscall.c
+SRCS.MACHINE.mips+=$(KTOP)/arch/mips/thread/cpu.c
+SRCS.MACHINE.mips+=$(KTOP)/arch/mips/thread/switchframe.c
+SRCS.MACHINE.mips+=$(KTOP)/arch/mips/thread/switch.S
+SRCS.MACHINE.mips+=$(KTOP)/arch/mips/thread/thread_machdep.c
+SRCS.MACHINE.mips+=$(KTOP)/arch/mips/thread/threadstart.S
+SRCS.MACHINE.mips+=$(KTOP)/arch/mips/vm/dumbvm.c
+SRCS.MACHINE.mips+=$(KTOP)/arch/mips/vm/ram.c
+SRCS.MACHINE.mips+=$(TOP)/common/gcc-millicode/adddi3.c
+SRCS.MACHINE.mips+=$(TOP)/common/gcc-millicode/anddi3.c
+SRCS.MACHINE.mips+=$(TOP)/common/gcc-millicode/ashldi3.c
+SRCS.MACHINE.mips+=$(TOP)/common/gcc-millicode/ashrdi3.c
+SRCS.MACHINE.mips+=$(TOP)/common/gcc-millicode/cmpdi2.c
+SRCS.MACHINE.mips+=$(TOP)/common/gcc-millicode/divdi3.c
+SRCS.MACHINE.mips+=$(TOP)/common/gcc-millicode/iordi3.c
+SRCS.MACHINE.mips+=$(TOP)/common/gcc-millicode/lshldi3.c
+SRCS.MACHINE.mips+=$(TOP)/common/gcc-millicode/lshrdi3.c
+SRCS.MACHINE.mips+=$(TOP)/common/gcc-millicode/moddi3.c
+SRCS.MACHINE.mips+=$(TOP)/common/gcc-millicode/muldi3.c
+SRCS.MACHINE.mips+=$(TOP)/common/gcc-millicode/negdi2.c
+SRCS.MACHINE.mips+=$(TOP)/common/gcc-millicode/notdi2.c
+SRCS.MACHINE.mips+=$(TOP)/common/gcc-millicode/qdivrem.c
+SRCS.MACHINE.mips+=$(TOP)/common/gcc-millicode/subdi3.c
+SRCS.MACHINE.mips+=$(TOP)/common/gcc-millicode/ucmpdi2.c
+SRCS.MACHINE.mips+=$(TOP)/common/gcc-millicode/udivdi3.c
+SRCS.MACHINE.mips+=$(TOP)/common/gcc-millicode/umoddi3.c
+SRCS.MACHINE.mips+=$(TOP)/common/gcc-millicode/xordi3.c
+SRCS.MACHINE.mips+=$(TOP)/common/libc/arch/mips/setjmp.S
+SRCS.MACHINE.mips+=$(KTOP)/vm/copyinout.c
+SRCS+=$(KTOP)/proc/proc.c
+SRCS+=$(KTOP)/startup/main.c
+SRCS+=$(KTOP)/startup/menu.c
+SRCS.PLATFORM.sys161+=$(KTOP)/arch/mips/locore/cache-mips161.S
+SRCS.PLATFORM.sys161+=$(KTOP)/arch/mips/locore/exception-mips1.S
+SRCS.PLATFORM.sys161+=$(KTOP)/arch/mips/vm/tlb-mips1.S
+SRCS.PLATFORM.sys161+=$(KTOP)/arch/sys161/dev/lamebus_machdep.c
+SRCS.PLATFORM.sys161+=$(KTOP)/arch/sys161/startup/start.S
+SRCS+=$(KTOP)/syscall/file_syscalls.c
+SRCS+=$(KTOP)/syscall/loadelf.c
+SRCS+=$(KTOP)/syscall/proc_syscalls.c
+SRCS+=$(KTOP)/syscall/runprogram.c
+SRCS+=$(KTOP)/syscall/time_syscalls.c
+SRCS+=$(KTOP)/test/arraytest.c
+SRCS+=$(KTOP)/test/bitmaptest.c
+SRCS+=$(KTOP)/test/fstest.c
+SRCS+=$(KTOP)/test/malloctest.c
+SRCS+=$(KTOP)/test/synchtest.c
+SRCS+=$(KTOP)/test/threadtest.c
+SRCS+=$(KTOP)/test/tt3.c
+SRCS+=$(KTOP)/test/uw-tests.c
+SRCS+=$(KTOP)/thread/clock.c
+SRCS+=$(KTOP)/thread/spinlock.c
+SRCS+=$(KTOP)/thread/spl.c
+SRCS+=$(KTOP)/thread/synch.c
+SRCS+=$(KTOP)/thread/thread.c
+SRCS+=$(KTOP)/thread/threadlist.c
+SRCS+=$(KTOP)/vfs/device.c
+SRCS+=$(KTOP)/vfs/devnull.c
+SRCS+=$(KTOP)/vfs/vfscwd.c
+SRCS+=$(KTOP)/vfs/vfslist.c
+SRCS+=$(KTOP)/vfs/vfslookup.c
+SRCS+=$(KTOP)/vfs/vfspath.c
+SRCS+=$(KTOP)/vfs/vnode.c
+SRCS+=$(KTOP)/vm/kmalloc.c
+SRCS+=$(KTOP)/vm/uw-vmstats.c

+ 1 - 0
kern/compile/ASST2/includelinks/kern/machine

@@ -0,0 +1 @@
+mips

+ 1 - 0
kern/compile/ASST2/includelinks/kern/mips

@@ -0,0 +1 @@
+../../../../arch/mips/include/kern

+ 1 - 0
kern/compile/ASST2/includelinks/machine

@@ -0,0 +1 @@
+mips

+ 1 - 0
kern/compile/ASST2/includelinks/mips

@@ -0,0 +1 @@
+../../../arch/mips/include

+ 1 - 0
kern/compile/ASST2/includelinks/platform

@@ -0,0 +1 @@
+sys161

+ 1 - 0
kern/compile/ASST2/includelinks/sys161

@@ -0,0 +1 @@
+../../../arch/sys161/include

BIN
kern/compile/ASST2/kernel


+ 5 - 0
kern/compile/ASST2/opt-A0.h

@@ -0,0 +1,5 @@
+/* Automatically generated; do not edit */
+#ifndef _OPT_A0_H_
+#define _OPT_A0_H_
+#define OPT_A0 0
+#endif /* _OPT_A0_H_ */

+ 5 - 0
kern/compile/ASST2/opt-A1.h

@@ -0,0 +1,5 @@
+/* Automatically generated; do not edit */
+#ifndef _OPT_A1_H_
+#define _OPT_A1_H_
+#define OPT_A1 1
+#endif /* _OPT_A1_H_ */

+ 5 - 0
kern/compile/ASST2/opt-A2.h

@@ -0,0 +1,5 @@
+/* Automatically generated; do not edit */
+#ifndef _OPT_A2_H_
+#define _OPT_A2_H_
+#define OPT_A2 1
+#endif /* _OPT_A2_H_ */

+ 5 - 0
kern/compile/ASST2/opt-A3.h

@@ -0,0 +1,5 @@
+/* Automatically generated; do not edit */
+#ifndef _OPT_A3_H_
+#define _OPT_A3_H_
+#define OPT_A3 0
+#endif /* _OPT_A3_H_ */

+ 5 - 0
kern/compile/ASST2/opt-A4.h

@@ -0,0 +1,5 @@
+/* Automatically generated; do not edit */
+#ifndef _OPT_A4_H_
+#define _OPT_A4_H_
+#define OPT_A4 0
+#endif /* _OPT_A4_H_ */

+ 5 - 0
kern/compile/ASST2/opt-A5.h

@@ -0,0 +1,5 @@
+/* Automatically generated; do not edit */
+#ifndef _OPT_A5_H_
+#define _OPT_A5_H_
+#define OPT_A5 0
+#endif /* _OPT_A5_H_ */

+ 5 - 0
kern/compile/ASST2/opt-dumbvm.h

@@ -0,0 +1,5 @@
+/* Automatically generated; do not edit */
+#ifndef _OPT_DUMBVM_H_
+#define _OPT_DUMBVM_H_
+#define OPT_DUMBVM 1
+#endif /* _OPT_DUMBVM_H_ */

+ 5 - 0
kern/compile/ASST2/opt-net.h

@@ -0,0 +1,5 @@
+/* Automatically generated; do not edit */
+#ifndef _OPT_NET_H_
+#define _OPT_NET_H_
+#define OPT_NET 0
+#endif /* _OPT_NET_H_ */

+ 5 - 0
kern/compile/ASST2/opt-netfs.h

@@ -0,0 +1,5 @@
+/* Automatically generated; do not edit */
+#ifndef _OPT_NETFS_H_
+#define _OPT_NETFS_H_
+#define OPT_NETFS 0
+#endif /* _OPT_NETFS_H_ */

+ 5 - 0
kern/compile/ASST2/opt-noasserts.h

@@ -0,0 +1,5 @@
+/* Automatically generated; do not edit */
+#ifndef _OPT_NOASSERTS_H_
+#define _OPT_NOASSERTS_H_
+#define OPT_NOASSERTS 0
+#endif /* _OPT_NOASSERTS_H_ */

+ 5 - 0
kern/compile/ASST2/opt-sfs.h

@@ -0,0 +1,5 @@
+/* Automatically generated; do not edit */
+#ifndef _OPT_SFS_H_
+#define _OPT_SFS_H_
+#define OPT_SFS 1
+#endif /* _OPT_SFS_H_ */

+ 5 - 0
kern/compile/ASST2/opt-synchprobs.h

@@ -0,0 +1,5 @@
+/* Automatically generated; do not edit */
+#ifndef _OPT_SYNCHPROBS_H_
+#define _OPT_SYNCHPROBS_H_
+#define OPT_SYNCHPROBS 0
+#endif /* _OPT_SYNCHPROBS_H_ */

+ 3 - 0
kern/compile/ASST2/vers.c

@@ -0,0 +1,3 @@
+/* This file is automatically generated. Edits will be lost.*/
+const int buildversion = 123;
+const char buildconfig[] = "ASST2";

+ 1 - 0
kern/compile/ASST2/version

@@ -0,0 +1 @@
+123

+ 13 - 12
kern/conf/conf.kern

@@ -51,7 +51,7 @@
 #       where the % is either a number or a star, which is treated as
 #       where the % is either a number or a star, which is treated as
 #       a wildcard. The first line enables a device foo that is not
 #       a wildcard. The first line enables a device foo that is not
 #       supposed to be "attached" to anything. The second line enables
 #       supposed to be "attached" to anything. The second line enables
-#       a device foo that is attached to a device bar. For more 
+#       a device foo that is attached to a device bar. For more
 #       information about what this means, see below.
 #       information about what this means, see below.
 #
 #
 #
 #
@@ -61,7 +61,7 @@
 #
 #
 # Note: All source file names are relative to the top directory of the
 # Note: All source file names are relative to the top directory of the
 # kernel source, that is, src/kern.
 # kernel source, that is, src/kern.
-# 
+#
 # The syntax for adding a regular source file is:
 # The syntax for adding a regular source file is:
 #
 #
 #    [machine M | platform P] file sourcefile.c
 #    [machine M | platform P] file sourcefile.c
@@ -103,7 +103,7 @@
 #           option - if you don't, cpp will silently assume it is 0,
 #           option - if you don't, cpp will silently assume it is 0,
 #           which can be quite frustrating.
 #           which can be quite frustrating.
 #
 #
-#       The defoption must be seen before any optional file 
+#       The defoption must be seen before any optional file
 #       declarations that use it.
 #       declarations that use it.
 #
 #
 #
 #
@@ -144,12 +144,12 @@
 #
 #
 #       are called from autoconf.c to create instances as requested.
 #       are called from autoconf.c to create instances as requested.
 #       These calls are made from the function pseudoconfig(), which
 #       These calls are made from the function pseudoconfig(), which
-#       should be called from dev/init.c after hardware device 
+#       should be called from dev/init.c after hardware device
 #       initialization completes. The pseudoattach functions should
 #       initialization completes. The pseudoattach functions should
 #       perform all setup and initialization necessary. (No
 #       perform all setup and initialization necessary. (No
 #       config_devname function will be called.)
 #       config_devname function will be called.)
 #
 #
-#       Devices with attachments are automatically probed and 
+#       Devices with attachments are automatically probed and
 #       configured from code in autoconf.c. This file is generated
 #       configured from code in autoconf.c. This file is generated
 #       by the config script. It contains functions called
 #       by the config script. It contains functions called
 #       "autoconf_devname", for each device. These functions call
 #       "autoconf_devname", for each device. These functions call
@@ -207,8 +207,8 @@
 #       occur more or less in the order things appear in the config,
 #       occur more or less in the order things appear in the config,
 #       as constrained by the tree structure of the available devices.
 #       as constrained by the tree structure of the available devices.
 #
 #
-#       Note that OS/161 does not make extensive use of this 
-#       functionality, and the device driver architecture outlined 
+#       Note that OS/161 does not make extensive use of this
+#       functionality, and the device driver architecture outlined
 #       here is overkill for such a limited environment as System/161.
 #       here is overkill for such a limited environment as System/161.
 #       However, it's similar to the way real systems are organized.
 #       However, it's similar to the way real systems are organized.
 #
 #
@@ -239,7 +239,7 @@
 # These come before the archinclude so that the hardware device
 # These come before the archinclude so that the hardware device
 # definitions, which are included from there, can define attachments
 # definitions, which are included from there, can define attachments
 # for them.
 # for them.
-# 
+#
 
 
 defdevice       beep			dev/generic/beep.c
 defdevice       beep			dev/generic/beep.c
 defdevice	con			dev/generic/console.c
 defdevice	con			dev/generic/console.c
@@ -253,14 +253,14 @@ defdevice       random                  dev/generic/random.c
 ########################################
 ########################################
 
 
 #
 #
-# Get the definitions for each machine and platform supported. The 
+# Get the definitions for each machine and platform supported. The
 # ones used will be selected by make at compile time based on the
 # ones used will be selected by make at compile time based on the
 # contents of the top-level defs.mk file.
 # contents of the top-level defs.mk file.
 #
 #
 # This will declare a bunch of machine-dependent source files and also
 # This will declare a bunch of machine-dependent source files and also
 # declare all the hardware devices (since what sorts of hardware we
 # declare all the hardware devices (since what sorts of hardware we
 # expect to find is machine-dependent.)
 # expect to find is machine-dependent.)
-# 
+#
 
 
 include   arch/mips/conf/conf.arch
 include   arch/mips/conf/conf.arch
 include   arch/sys161/conf/conf.arch
 include   arch/sys161/conf/conf.arch
@@ -273,7 +273,7 @@ include   arch/sys161/conf/conf.arch
 
 
 #
 #
 # Kernel utility code
 # Kernel utility code
-# 
+#
 
 
 file      lib/array.c
 file      lib/array.c
 file      lib/bitmap.c
 file      lib/bitmap.c
@@ -284,13 +284,14 @@ file      lib/misc.c
 file      lib/uio.c
 file      lib/uio.c
 # UW Mod
 # UW Mod
 file      lib/queue.c
 file      lib/queue.c
+file      lib/list.c
 
 
 defoption noasserts
 defoption noasserts
 
 
 
 
 #
 #
 # Standard C functions
 # Standard C functions
-# 
+#
 # For most of these, we take the source files from our libc.  Note
 # For most of these, we take the source files from our libc.  Note
 # that those files have to have been hacked a bit to support this.
 # that those files have to have been hacked a bit to support this.
 #
 #

+ 7 - 6
kern/include/addrspace.h

@@ -40,14 +40,15 @@
 struct vnode;
 struct vnode;
 
 
 
 
-/* 
+/*
  * Address space - data structure associated with the virtual memory
  * Address space - data structure associated with the virtual memory
  * space of a process.
  * space of a process.
  *
  *
  * You write this.
  * You write this.
  */
  */
 
 
-struct addrspace {
+struct addrspace
+{
   vaddr_t as_vbase1;
   vaddr_t as_vbase1;
   paddr_t as_pbase1;
   paddr_t as_pbase1;
   size_t as_npages1;
   size_t as_npages1;
@@ -60,8 +61,8 @@ struct addrspace {
 /*
 /*
  * Functions in addrspace.c:
  * Functions in addrspace.c:
  *
  *
- *    as_create - create a new empty address space. You need to make 
- *                sure this gets called in all the right places. You
+ *    as_create - create a new empty address space. You need to make
+ *                sure this gets called in justify the means constructall the right places. You
  *                may find you want to change the argument list. May
  *                may find you want to change the argument list. May
  *                return NULL on out-of-memory error.
  *                return NULL on out-of-memory error.
  *
  *
@@ -99,9 +100,9 @@ void              as_activate(void);
 void              as_deactivate(void);
 void              as_deactivate(void);
 void              as_destroy(struct addrspace *);
 void              as_destroy(struct addrspace *);
 
 
-int               as_define_region(struct addrspace *as, 
+int               as_define_region(struct addrspace *as,
                                    vaddr_t vaddr, size_t sz,
                                    vaddr_t vaddr, size_t sz,
-                                   int readable, 
+                                   int readable,
                                    int writeable,
                                    int writeable,
                                    int executable);
                                    int executable);
 int               as_prepare_load(struct addrspace *as);
 int               as_prepare_load(struct addrspace *as);

+ 25 - 0
kern/include/list.h

@@ -0,0 +1,25 @@
+#ifndef _LIST_H_
+#define _LIST_H_
+
+#include <lib.h>
+
+struct node
+{
+  struct node * next;
+  int val;
+};
+
+struct list
+{
+  struct node * front;
+  int len;
+};
+
+struct list * newlist(void);
+int listsert(struct list * l, int x);
+void listemove(struct list * l, int x);
+void listelete(struct list * l);
+int listearch(struct list * l, int x);
+int listpop(struct list * l);
+
+#endif /* _LIST_H_ */

+ 42 - 11
kern/include/proc.h

@@ -38,6 +38,9 @@
 
 
 #include <spinlock.h>
 #include <spinlock.h>
 #include <thread.h> /* required for struct threadarray */
 #include <thread.h> /* required for struct threadarray */
+#include <limits.h> // using to restrict array size of procs
+#include <synch.h>
+#include <list.h>
 
 
 struct addrspace;
 struct addrspace;
 struct vnode;
 struct vnode;
@@ -48,16 +51,23 @@ struct semaphore;
 /*
 /*
  * Process structure.
  * Process structure.
  */
  */
-struct proc {
-	char *p_name;			/* Name of this process */
+struct proc
+{
+	char * p_name;			/* Name of this process */
+	int pid; // pretty self-explanatory
+	struct proc * parent; // again, pretty damn obvious
+	struct list * kids; // list of kid processes (by pid)
+	int exitcode; // exitcode if exited, -1 if running
+	struct cv * waiting; // parents can wait on this CV
+	struct lock * waitlock; // waitlock for the CV
 	struct spinlock p_lock;		/* Lock for this structure */
 	struct spinlock p_lock;		/* Lock for this structure */
 	struct threadarray p_threads;	/* Threads in this process */
 	struct threadarray p_threads;	/* Threads in this process */
 
 
 	/* VM */
 	/* VM */
-	struct addrspace *p_addrspace;	/* virtual address space */
+	struct addrspace * p_addrspace;	/* virtual address space */
 
 
 	/* VFS */
 	/* VFS */
-	struct vnode *p_cwd;		/* current working directory */
+	struct vnode * p_cwd;		/* current working directory */
 
 
 #ifdef UW
 #ifdef UW
   /* a vnode to refer to the console device */
   /* a vnode to refer to the console device */
@@ -65,34 +75,47 @@ struct proc {
   /* you will probably need to change this when implementing file-related
   /* you will probably need to change this when implementing file-related
      system calls, since each process will need to keep track of all files
      system calls, since each process will need to keep track of all files
      it has opened, not just the console. */
      it has opened, not just the console. */
-  struct vnode *console;                /* a vnode for the console device */
+  struct vnode * console;                /* a vnode for the console device */
 #endif
 #endif
 
 
 	/* add more material here as needed */
 	/* add more material here as needed */
 };
 };
 
 
+// struct that contains all the processes in the system
+struct procs
+{
+  struct proc  * pids[PID_MAX + 1]; // total # of valid PIDs
+  int lastpid; // last pid issued
+};
+
 /* This is the process structure for the kernel and for kernel-only threads. */
 /* This is the process structure for the kernel and for kernel-only threads. */
-extern struct proc *kproc;
+extern struct proc * kproc;
+
+// The process array
+extern struct procs * processes;
+
+// The lock for the above array
+extern struct lock * proclock;
 
 
 /* Semaphore used to signal when there are no more processes */
 /* Semaphore used to signal when there are no more processes */
 #ifdef UW
 #ifdef UW
-extern struct semaphore *no_proc_sem;
+extern struct semaphore * no_proc_sem;
 #endif // UW
 #endif // UW
 
 
 /* Call once during system startup to allocate data structures. */
 /* Call once during system startup to allocate data structures. */
 void proc_bootstrap(void);
 void proc_bootstrap(void);
 
 
 /* Create a fresh process for use by runprogram(). */
 /* Create a fresh process for use by runprogram(). */
-struct proc *proc_create_runprogram(const char *name);
+struct proc *proc_create_runprogram(const char * name);// get and return a pid for the process
 
 
 /* Destroy a process. */
 /* Destroy a process. */
-void proc_destroy(struct proc *proc);
+void proc_destroy(struct proc * proc);
 
 
 /* Attach a thread to a process. Must not already have a process. */
 /* Attach a thread to a process. Must not already have a process. */
-int proc_addthread(struct proc *proc, struct thread *t);
+int proc_addthread(struct proc * proc, struct thread * t);
 
 
 /* Detach a thread from its process. */
 /* Detach a thread from its process. */
-void proc_remthread(struct thread *t);
+void proc_remthread(struct thread * t);
 
 
 /* Fetch the address space of the current process. */
 /* Fetch the address space of the current process. */
 struct addrspace *curproc_getas(void);
 struct addrspace *curproc_getas(void);
@@ -100,5 +123,13 @@ struct addrspace *curproc_getas(void);
 /* Change the address space of the current process, and return the old one. */
 /* Change the address space of the current process, and return the old one. */
 struct addrspace *curproc_setas(struct addrspace *);
 struct addrspace *curproc_setas(struct addrspace *);
 
 
+// get and return a pid for the process
+int assignpid(struct proc * proc);
+
+// returns the child process if it is a child, otherwise null
+struct proc * getChild(struct proc * p, int pid);
+
+// adds child pid to parent's list
+void add_child(struct proc * parent, int pid);
 
 
 #endif /* _PROC_H_ */
 #endif /* _PROC_H_ */

+ 6 - 5
kern/include/syscall.h

@@ -37,14 +37,14 @@ struct trapframe; /* from <machine/trapframe.h> */
  * The system call dispatcher.
  * The system call dispatcher.
  */
  */
 
 
-void syscall(struct trapframe *tf);
+void syscall(struct trapframe * tf);
 
 
 /*
 /*
  * Support functions.
  * Support functions.
  */
  */
 
 
 /* Helper for fork(). You write this. */
 /* Helper for fork(). You write this. */
-void enter_forked_process(struct trapframe *tf);
+void enter_forked_process(void * trap, unsigned long x);
 
 
 /* Enter user mode. Does not return. */
 /* Enter user mode. Does not return. */
 void enter_new_process(int argc, userptr_t argv, vaddr_t stackptr,
 void enter_new_process(int argc, userptr_t argv, vaddr_t stackptr,
@@ -59,10 +59,11 @@ int sys_reboot(int code);
 int sys___time(userptr_t user_seconds, userptr_t user_nanoseconds);
 int sys___time(userptr_t user_seconds, userptr_t user_nanoseconds);
 
 
 #ifdef UW
 #ifdef UW
-int sys_write(int fdesc,userptr_t ubuf,unsigned int nbytes,int *retval);
+int sys_write(int fdesc,userptr_t ubuf,unsigned int nbytes,int * retval);
 void sys__exit(int exitcode);
 void sys__exit(int exitcode);
-int sys_getpid(pid_t *retval);
-int sys_waitpid(pid_t pid, userptr_t status, int options, pid_t *retval);
+int sys_getpid(pid_t *  retval);
+int sys_waitpid(pid_t pid, userptr_t status, int options, pid_t * retval);
+int sys_fork(struct trapframe * tf, int * retval);
 
 
 #endif // UW
 #endif // UW
 
 

+ 10 - 8
kern/include/thread.h

@@ -57,7 +57,8 @@ struct cpu;
 
 
 
 
 /* States a thread can be in. */
 /* States a thread can be in. */
-typedef enum {
+typedef enum
+{
 	S_RUN,		/* running */
 	S_RUN,		/* running */
 	S_READY,	/* ready to run */
 	S_READY,	/* ready to run */
 	S_SLEEP,	/* sleeping */
 	S_SLEEP,	/* sleeping */
@@ -65,13 +66,14 @@ typedef enum {
 } threadstate_t;
 } threadstate_t;
 
 
 /* Thread structure. */
 /* Thread structure. */
-struct thread {
+struct thread
+{
 	/*
 	/*
 	 * These go up front so they're easy to get to even if the
 	 * These go up front so they're easy to get to even if the
 	 * debugger is messed up.
 	 * debugger is messed up.
 	 */
 	 */
-	char *t_name;			/* Name of this thread */
-	const char *t_wchan_name;	/* Name of wait channel, if sleeping */
+	char * t_name;			/* Name of this thread */
+	const char * t_wchan_name;	/* Name of wait channel, if sleeping */
 	threadstate_t t_state;		/* State this thread is in */
 	threadstate_t t_state;		/* State this thread is in */
 
 
 	/*
 	/*
@@ -79,10 +81,10 @@ struct thread {
 	 */
 	 */
 	struct thread_machdep t_machdep; /* Any machine-dependent goo */
 	struct thread_machdep t_machdep; /* Any machine-dependent goo */
 	struct threadlistnode t_listnode; /* Link for run/sleep/zombie lists */
 	struct threadlistnode t_listnode; /* Link for run/sleep/zombie lists */
-	void *t_stack;			/* Kernel-level stack */
-	struct switchframe *t_context;	/* Saved register context (on stack) */
-	struct cpu *t_cpu;		/* CPU thread runs on */
-	struct proc *t_proc;		/* Process thread belongs to */
+	void * t_stack;			/* Kernel-level stack */
+	struct switchframe * t_context;	/* Saved register context (on stack) */
+	struct cpu * t_cpu;		/* CPU thread runs on */
+	struct proc * t_proc;		/* Process thread belongs to */
 
 
 	/*
 	/*
 	 * Interrupt state fields.
 	 * Interrupt state fields.

+ 100 - 0
kern/lib/list.c

@@ -0,0 +1,100 @@
+#include <types.h>
+#include <kern/errno.h>
+#include <lib.h>
+#include <list.h>
+
+typedef struct list list;
+typedef struct node node;
+list * newlist(void)
+{
+  list * ret = kmalloc(sizeof(list));
+  if (!(ret)) return NULL;
+  ret->front = NULL;
+  ret->len = 0;
+  return ret;
+}
+
+int listsert(list * l, int x)
+{
+  node * temp = l->front;
+  node * newnode = kmalloc(sizeof(node));
+  if (!(newnode)) return ENOMEM;
+  newnode->val = x;
+  newnode->next = temp;
+  l->front = newnode;
+  ++l->len;
+  return 0;
+}
+
+void listemove(list * l, int x)
+{
+  node * temp = l->front;
+  node * temp2 = NULL;
+  
+  while (temp)
+  {
+    if (temp->val == x)
+    {
+      if (!(temp2))
+      {
+        l->front = temp->next;
+      }
+      else
+      {
+        temp2->next = temp->next;
+      }
+      
+      --l->len;
+      break;
+    }
+    else
+    {
+      temp2 = temp;
+      temp = temp->next;
+    }
+  }
+}
+
+void listelete(list * l)
+{
+  node * temp = l->front;
+  node * temp2 = NULL;
+  
+  while (temp)
+  {
+    temp2 = temp->next;
+    kfree(temp);
+    temp = temp2;
+  }
+  
+  kfree(l);
+}
+
+int listearch(list * l, int x)
+{
+  node * temp = l->front;
+
+  while (temp)
+  {
+    if (temp->val == x) return 1;
+    temp = temp->next;
+  }
+  
+  return 0;
+}
+
+int listpop(list * l)
+{
+  node * temp = l->front;
+  
+  if (temp)
+  {
+    int x = temp->val;
+    l->front = temp->next;
+    --l->len;
+    kfree(temp);
+    return x;
+  }
+  
+  return 0;
+}

+ 175 - 73
kern/proc/proc.c

@@ -49,12 +49,22 @@
 #include <vnode.h>
 #include <vnode.h>
 #include <vfs.h>
 #include <vfs.h>
 #include <synch.h>
 #include <synch.h>
-#include <kern/fcntl.h>  
+#include <kern/fcntl.h>
+#include <list.h>
+#include <limits.h>
+#include <kern/errno.h>
 
 
-/*
- * The process for the kernel; this holds all the kernel-only threads.
- */
-struct proc *kproc;
+typedef struct list list;
+typedef struct procs procs;
+
+//The process for the kernel; this holds all the kernel-only threads.
+struct proc * kproc;
+
+// The process array
+procs * processes;
+
+// The lock for the above array
+struct lock * proclock;
 
 
 /*
 /*
  * Mechanism for making the kernel menu thread sleep while processes are running
  * Mechanism for making the kernel menu thread sleep while processes are running
@@ -63,10 +73,10 @@ struct proc *kproc;
 /* count of the number of processes, excluding kproc */
 /* count of the number of processes, excluding kproc */
 static volatile unsigned int proc_count;
 static volatile unsigned int proc_count;
 /* provides mutual exclusion for proc_count */
 /* provides mutual exclusion for proc_count */
-/* it would be better to use a lock here, but we use a semaphore because locks are not implemented in the base kernel */ 
-static struct semaphore *proc_count_mutex;
+/* it would be better to use a lock here, but we use a semaphore because locks are not implemented in the base kernel */
+static struct semaphore * proc_count_mutex;
 /* used to signal the kernel menu thread when there are no processes */
 /* used to signal the kernel menu thread when there are no processes */
-struct semaphore *no_proc_sem;   
+struct semaphore * no_proc_sem;
 #endif  // UW
 #endif  // UW
 
 
 
 
@@ -74,24 +84,34 @@ struct semaphore *no_proc_sem;
 /*
 /*
  * Create a proc structure.
  * Create a proc structure.
  */
  */
-static
-struct proc *
-proc_create(const char *name)
+static struct proc * proc_create(const char * name)
 {
 {
-	struct proc *proc;
+	struct proc * proc;
 
 
 	proc = kmalloc(sizeof(*proc));
 	proc = kmalloc(sizeof(*proc));
-	if (proc == NULL) {
+	if (proc == NULL)
+	{
 		return NULL;
 		return NULL;
 	}
 	}
+	
 	proc->p_name = kstrdup(name);
 	proc->p_name = kstrdup(name);
-	if (proc->p_name == NULL) {
+	if (proc->p_name == NULL)
+	{
 		kfree(proc);
 		kfree(proc);
 		return NULL;
 		return NULL;
 	}
 	}
+	
+	proc->kids = newlist();
+	if (!(proc->kids))
+	{
+	  kfree(proc);
+	  return NULL;
+	}
 
 
 	threadarray_init(&proc->p_threads);
 	threadarray_init(&proc->p_threads);
 	spinlock_init(&proc->p_lock);
 	spinlock_init(&proc->p_lock);
+	proc->waitlock = lock_create("threadlock");
+	proc->waiting = cv_create("threadcv");
 
 
 	/* VM fields */
 	/* VM fields */
 	proc->p_addrspace = NULL;
 	proc->p_addrspace = NULL;
@@ -103,24 +123,81 @@ proc_create(const char *name)
 	proc->console = NULL;
 	proc->console = NULL;
 #endif // UW
 #endif // UW
 
 
+  // My additions
+  proc->pid = 0;
+  proc->parent = NULL;
+  proc->exitcode = -1;
+
 	return proc;
 	return proc;
 }
 }
 
 
+static procs * create_procs(void)
+{
+  procs * temp = kmalloc(sizeof(procs));
+  if (!(temp)) panic("Could not create process list!\n");
+  temp->lastpid = PID_MIN - 1;
+  return temp;
+}
+
+struct proc * getChild(struct proc * p, int pid)
+{
+  lock_acquire(proclock);
+  int result = listearch(p->kids, pid);
+  lock_release(proclock);
+
+  if (!(result)) return NULL;
+  return processes->pids[pid];
+}
+
+int assignpid(struct proc * proc)
+{
+  lock_acquire(proclock);
+  
+  for (int i = processes->lastpid + 1; i <= PID_MAX; i++)
+  {
+    if (processes->pids[i] == 0)
+    {
+      proc->pid = i;
+      processes->lastpid = i;
+      processes->pids[i] = proc;
+      lock_release(proclock);
+      return i;
+    }
+    
+    if (i == PID_MAX)
+    {
+      i = PID_MIN - 1;
+      continue;
+    }
+    
+    if (i == processes->lastpid)
+    {
+      lock_release(proclock);
+      return 0;
+    }
+  }
+  
+  lock_release(proclock);
+  return 0;
+}
+
+void add_child(struct proc * parent, int pid)
+{
+  listsert(parent->kids, pid);
+}
+
+/*
+static void delete_procs()
+{
+  kfree(processes->pids);
+  lock_destroy(proclock);
+}*/
+
 /*
 /*
  * Destroy a proc structure.
  * Destroy a proc structure.
  */
  */
-void
-proc_destroy(struct proc *proc)
+void proc_destroy(struct proc * proc)
 {
 {
-	/*
-         * note: some parts of the process structure, such as the address space,
-         *  are destroyed in sys_exit, before we get here
-         *
-         * note: depending on where this function is called from, curproc may not
-         * be defined because the calling thread may have already detached itself
-         * from the process.
-	 */
-
 	KASSERT(proc != NULL);
 	KASSERT(proc != NULL);
 	KASSERT(proc != kproc);
 	KASSERT(proc != kproc);
 
 
@@ -129,16 +206,16 @@ proc_destroy(struct proc *proc)
 	 * reference to this structure. (Otherwise it would be
 	 * reference to this structure. (Otherwise it would be
 	 * incorrect to destroy it.)
 	 * incorrect to destroy it.)
 	 */
 	 */
-
 	/* VFS fields */
 	/* VFS fields */
-	if (proc->p_cwd) {
+	if (proc->p_cwd)
+	{
 		VOP_DECREF(proc->p_cwd);
 		VOP_DECREF(proc->p_cwd);
 		proc->p_cwd = NULL;
 		proc->p_cwd = NULL;
 	}
 	}
 
 
-
 #ifndef UW  // in the UW version, space destruction occurs in sys_exit, not here
 #ifndef UW  // in the UW version, space destruction occurs in sys_exit, not here
-	if (proc->p_addrspace) {
+	if (proc->p_addrspace)
+	{
 		/*
 		/*
 		 * In case p is the currently running process (which
 		 * In case p is the currently running process (which
 		 * it might be in some circumstances, or if this code
 		 * it might be in some circumstances, or if this code
@@ -149,65 +226,81 @@ proc_destroy(struct proc *proc)
 		 * half-destroyed address space. This tends to be
 		 * half-destroyed address space. This tends to be
 		 * messily fatal.
 		 * messily fatal.
 		 */
 		 */
-		struct addrspace *as;
+		struct addrspace * as;
 
 
 		as_deactivate();
 		as_deactivate();
 		as = curproc_setas(NULL);
 		as = curproc_setas(NULL);
 		as_destroy(as);
 		as_destroy(as);
 	}
 	}
 #endif // UW
 #endif // UW
-
+/*
 #ifdef UW
 #ifdef UW
-	if (proc->console) {
+	if (proc->console)
+	{
 	  vfs_close(proc->console);
 	  vfs_close(proc->console);
 	}
 	}
-#endif // UW
-
-	threadarray_cleanup(&proc->p_threads);
-	spinlock_cleanup(&proc->p_lock);
-
+#endif // UW */
+
+	//threadarray_cleanup(&proc->p_threads);
+  lock_acquire(proclock);
+  processes->pids[proc->pid] = NULL; // update available PIDs
+  lock_release(proclock);
+  lock_destroy(proc->waitlock);
+  cv_destroy(proc->waiting);
 	kfree(proc->p_name);
 	kfree(proc->p_name);
 	kfree(proc);
 	kfree(proc);
 
 
 #ifdef UW
 #ifdef UW
 	/* decrement the process count */
 	/* decrement the process count */
-        /* note: kproc is not included in the process count, but proc_destroy
+        /* note: kproc is not included as_copy in the process count, but proc_destroy
 	   is never called on kproc (see KASSERT above), so we're OK to decrement
 	   is never called on kproc (see KASSERT above), so we're OK to decrement
 	   the proc_count unconditionally here */
 	   the proc_count unconditionally here */
-	P(proc_count_mutex); 
+	P(proc_count_mutex);
 	KASSERT(proc_count > 0);
 	KASSERT(proc_count > 0);
 	proc_count--;
 	proc_count--;
+
 	/* signal the kernel menu thread if the process count has reached zero */
 	/* signal the kernel menu thread if the process count has reached zero */
-	if (proc_count == 0) {
+	if (proc_count == 0)
+	{
 	  V(no_proc_sem);
 	  V(no_proc_sem);
 	}
 	}
 	V(proc_count_mutex);
 	V(proc_count_mutex);
 #endif // UW
 #endif // UW
-	
-
 }
 }
 
 
 /*
 /*
  * Create the process structure for the kernel.
  * Create the process structure for the kernel.
  */
  */
-void
-proc_bootstrap(void)
+void proc_bootstrap(void)
 {
 {
+  processes = create_procs();
   kproc = proc_create("[kernel]");
   kproc = proc_create("[kernel]");
-  if (kproc == NULL) {
+  if (kproc == NULL)
+  {
     panic("proc_create for kproc failed\n");
     panic("proc_create for kproc failed\n");
   }
   }
 #ifdef UW
 #ifdef UW
   proc_count = 0;
   proc_count = 0;
   proc_count_mutex = sem_create("proc_count_mutex",1);
   proc_count_mutex = sem_create("proc_count_mutex",1);
-  if (proc_count_mutex == NULL) {
+  if (proc_count_mutex == NULL)
+  {
     panic("could not create proc_count_mutex semaphore\n");
     panic("could not create proc_count_mutex semaphore\n");
   }
   }
   no_proc_sem = sem_create("no_proc_sem",0);
   no_proc_sem = sem_create("no_proc_sem",0);
-  if (no_proc_sem == NULL) {
+  if (no_proc_sem == NULL)
+  {
     panic("could not create no_proc_sem semaphore\n");
     panic("could not create no_proc_sem semaphore\n");
   }
   }
-#endif // UW 
+#endif // UW
+  
+  int processesLen = PID_MAX;
+  for (int i = 0; i <= processesLen; i++)
+  {
+    processes->pids[i] = NULL;
+  }
+
+  proclock = lock_create("proclock");
+  if (!(proclock)) panic("Process manager lock could not be created!\n");
 }
 }
 
 
 /*
 /*
@@ -216,24 +309,26 @@ proc_bootstrap(void)
  * It will have no address space and will inherit the current
  * It will have no address space and will inherit the current
  * process's (that is, the kernel menu's) current directory.
  * process's (that is, the kernel menu's) current directory.
  */
  */
-struct proc *
-proc_create_runprogram(const char *name)
+struct proc * proc_create_runprogram(const char * name)
 {
 {
-	struct proc *proc;
-	char *console_path;
+	struct proc * proc;
+	char * console_path;
 
 
 	proc = proc_create(name);
 	proc = proc_create(name);
-	if (proc == NULL) {
+	if (proc == NULL)
+	{
 		return NULL;
 		return NULL;
 	}
 	}
 
 
 #ifdef UW
 #ifdef UW
 	/* open the console - this should always succeed */
 	/* open the console - this should always succeed */
 	console_path = kstrdup("con:");
 	console_path = kstrdup("con:");
-	if (console_path == NULL) {
+	if (console_path == NULL)
+	{
 	  panic("unable to copy console path name during process creation\n");
 	  panic("unable to copy console path name during process creation\n");
 	}
 	}
-	if (vfs_open(console_path,O_WRONLY,0,&(proc->console))) {
+	if (vfs_open(console_path,O_WRONLY,0,&(proc->console)))
+	{
 	  panic("unable to open the console during process creation\n");
 	  panic("unable to open the console during process creation\n");
 	}
 	}
 	kfree(console_path);
 	kfree(console_path);
@@ -249,13 +344,15 @@ proc_create_runprogram(const char *name)
 	/* we do not need to acquire the p_lock here, the running thread should
 	/* we do not need to acquire the p_lock here, the running thread should
            have the only reference to this process */
            have the only reference to this process */
         /* also, acquiring the p_lock is problematic because VOP_INCREF may block */
         /* also, acquiring the p_lock is problematic because VOP_INCREF may block */
-	if (curproc->p_cwd != NULL) {
+	if (curproc->p_cwd != NULL)
+	{
 		VOP_INCREF(curproc->p_cwd);
 		VOP_INCREF(curproc->p_cwd);
 		proc->p_cwd = curproc->p_cwd;
 		proc->p_cwd = curproc->p_cwd;
 	}
 	}
 #else // UW
 #else // UW
 	spinlock_acquire(&curproc->p_lock);
 	spinlock_acquire(&curproc->p_lock);
-	if (curproc->p_cwd != NULL) {
+	if (curproc->p_cwd != NULL)
+	{
 		VOP_INCREF(curproc->p_cwd);
 		VOP_INCREF(curproc->p_cwd);
 		proc->p_cwd = curproc->p_cwd;
 		proc->p_cwd = curproc->p_cwd;
 	}
 	}
@@ -266,8 +363,13 @@ proc_create_runprogram(const char *name)
 	/* increment the count of processes */
 	/* increment the count of processes */
         /* we are assuming that all procs, including those created by fork(),
         /* we are assuming that all procs, including those created by fork(),
            are created using a call to proc_create_runprogram  */
            are created using a call to proc_create_runprogram  */
-	P(proc_count_mutex); 
+	P(proc_count_mutex);
 	proc_count++;
 	proc_count++;
+	if (!(assignpid(proc)))
+	{
+	  kfree(proc);
+	  return NULL;
+	}
 	V(proc_count_mutex);
 	V(proc_count_mutex);
 #endif // UW
 #endif // UW
 
 
@@ -278,8 +380,7 @@ proc_create_runprogram(const char *name)
  * Add a thread to a process. Either the thread or the process might
  * Add a thread to a process. Either the thread or the process might
  * or might not be current.
  * or might not be current.
  */
  */
-int
-proc_addthread(struct proc *proc, struct thread *t)
+int proc_addthread(struct proc * proc, struct thread * t)
 {
 {
 	int result;
 	int result;
 
 
@@ -288,7 +389,8 @@ proc_addthread(struct proc *proc, struct thread *t)
 	spinlock_acquire(&proc->p_lock);
 	spinlock_acquire(&proc->p_lock);
 	result = threadarray_add(&proc->p_threads, t, NULL);
 	result = threadarray_add(&proc->p_threads, t, NULL);
 	spinlock_release(&proc->p_lock);
 	spinlock_release(&proc->p_lock);
-	if (result) {
+	if (result)
+	{
 		return result;
 		return result;
 	}
 	}
 	t->t_proc = proc;
 	t->t_proc = proc;
@@ -299,8 +401,7 @@ proc_addthread(struct proc *proc, struct thread *t)
  * Remove a thread from its process. Either the thread or the process
  * Remove a thread from its process. Either the thread or the process
  * might or might not be current.
  * might or might not be current.
  */
  */
-void
-proc_remthread(struct thread *t)
+void proc_remthread(struct thread * t)
 {
 {
 	struct proc *proc;
 	struct proc *proc;
 	unsigned i, num;
 	unsigned i, num;
@@ -311,8 +412,10 @@ proc_remthread(struct thread *t)
 	spinlock_acquire(&proc->p_lock);
 	spinlock_acquire(&proc->p_lock);
 	/* ugh: find the thread in the array */
 	/* ugh: find the thread in the array */
 	num = threadarray_num(&proc->p_threads);
 	num = threadarray_num(&proc->p_threads);
-	for (i=0; i<num; i++) {
-		if (threadarray_get(&proc->p_threads, i) == t) {
+	for (i=0; i<num; i++)
+	{
+		if (threadarray_get(&proc->p_threads, i) == t)
+		{
 			threadarray_remove(&proc->p_threads, i);
 			threadarray_remove(&proc->p_threads, i);
 			spinlock_release(&proc->p_lock);
 			spinlock_release(&proc->p_lock);
 			t->t_proc = NULL;
 			t->t_proc = NULL;
@@ -329,15 +432,15 @@ proc_remthread(struct thread *t)
  * refcounted. If you implement multithreaded processes, make sure to
  * refcounted. If you implement multithreaded processes, make sure to
  * set up a refcount scheme or some other method to make this safe.
  * set up a refcount scheme or some other method to make this safe.
  */
  */
-struct addrspace *
-curproc_getas(void)
+struct addrspace * curproc_getas(void)
 {
 {
 	struct addrspace *as;
 	struct addrspace *as;
 #ifdef UW
 #ifdef UW
-        /* Until user processes are created, threads used in testing 
+        /* Until user processes are created, threads used in testing
          * (i.e., kernel threads) have no process or address space.
          * (i.e., kernel threads) have no process or address space.
          */
          */
-	if (curproc == NULL) {
+	if (curproc == NULL)
+  {
 		return NULL;
 		return NULL;
 	}
 	}
 #endif
 #endif
@@ -352,11 +455,10 @@ curproc_getas(void)
  * Change the address space of the current process, and return the old
  * Change the address space of the current process, and return the old
  * one.
  * one.
  */
  */
-struct addrspace *
-curproc_setas(struct addrspace *newas)
+struct addrspace * curproc_setas(struct addrspace * newas)
 {
 {
-	struct addrspace *oldas;
-	struct proc *proc = curproc;
+	struct addrspace * oldas;
+	struct proc * proc = curproc;
 
 
 	spinlock_acquire(&proc->p_lock);
 	spinlock_acquire(&proc->p_lock);
 	oldas = proc->p_addrspace;
 	oldas = proc->p_addrspace;

+ 100 - 56
kern/syscall/proc_syscalls.c

@@ -2,36 +2,53 @@
 #include <kern/errno.h>
 #include <kern/errno.h>
 #include <kern/unistd.h>
 #include <kern/unistd.h>
 #include <kern/wait.h>
 #include <kern/wait.h>
+#include <mips/trapframe.h>
 #include <lib.h>
 #include <lib.h>
+#include <vfs.h>
+#include <vnode.h>
 #include <syscall.h>
 #include <syscall.h>
 #include <current.h>
 #include <current.h>
 #include <proc.h>
 #include <proc.h>
 #include <thread.h>
 #include <thread.h>
 #include <addrspace.h>
 #include <addrspace.h>
 #include <copyinout.h>
 #include <copyinout.h>
+#include <synch.h>
 
 
-  /* this implementation of sys__exit does not do anything with the exit code */
-  /* this needs to be fixed to get exit() and waitpid() working properly */
-
-void sys__exit(int exitcode) {
-
-  struct addrspace *as;
-  struct proc *p = curproc;
-  /* for now, just include this to keep the compiler from complaining about
-     an unused variable */
-  (void)exitcode;
-
+void sys__exit(int exitcode)
+{
+  struct addrspace * as;
+  struct proc * p = curproc;
+  p->exitcode = exitcode;
   DEBUG(DB_SYSCALL,"Syscall: _exit(%d)\n",exitcode);
   DEBUG(DB_SYSCALL,"Syscall: _exit(%d)\n",exitcode);
-
   KASSERT(curproc->p_addrspace != NULL);
   KASSERT(curproc->p_addrspace != NULL);
+  
+  lock_acquire(proclock);
+  int x = listpop(p->kids);
+  while (x)
+  {
+    if(processes->pids[x])
+    {
+      processes->pids[x]->parent = NULL;
+      if (processes->pids[x]->exitcode >= 0)
+      {
+        lock_release(proclock);
+        proc_destroy(processes->pids[x]);
+        lock_acquire(proclock);
+      }
+    }
+    x = listpop(p->kids);
+  }
+  lock_release(proclock);
+  listelete(p->kids);
+  
+  // VFS fields
+	if (p->p_cwd)
+	{
+		VOP_DECREF(p->p_cwd);
+		p->p_cwd = NULL;
+	}
+  
   as_deactivate();
   as_deactivate();
-  /*
-   * clear p_addrspace before calling as_destroy. Otherwise if
-   * as_destroy sleeps (which is quite possible) when we
-   * come back we'll be calling as_activate on a
-   * half-destroyed address space. This tends to be
-   * messily fatal.
-   */
   as = curproc_setas(NULL);
   as = curproc_setas(NULL);
   as_destroy(as);
   as_destroy(as);
 
 
@@ -39,56 +56,83 @@ void sys__exit(int exitcode) {
   /* note: curproc cannot be used after this call */
   /* note: curproc cannot be used after this call */
   proc_remthread(curthread);
   proc_remthread(curthread);
 
 
-  /* if this is the last user process in the system, proc_destroy()
-     will wake up the kernel menu thread */
-  proc_destroy(p);
+  threadarray_cleanup(&p->p_threads);
+	spinlock_cleanup(&p->p_lock);
+
+  lock_acquire(p->waitlock);
+  cv_broadcast(p->waiting, p->waitlock);
+  lock_release(p->waitlock);
+
+  if (!(p->parent) || p->parent->exitcode >= 0 || p->parent == kproc) proc_destroy(p);
   
   
   thread_exit();
   thread_exit();
   /* thread_exit() does not return, so we should never get here */
   /* thread_exit() does not return, so we should never get here */
   panic("return from thread_exit in sys_exit\n");
   panic("return from thread_exit in sys_exit\n");
 }
 }
 
 
-
-/* stub handler for getpid() system call                */
-int
-sys_getpid(pid_t *retval)
+// basically, return an error code, and put the actual result in retval
+int sys_getpid(pid_t * retval)
 {
 {
-  /* for now, this is just a stub that always returns a PID of 1 */
-  /* you need to fix this to make it work properly */
-  *retval = 1;
+  if (!(curproc)) return 1;
+  *retval = curproc->pid;
   return(0);
   return(0);
 }
 }
 
 
-/* stub handler for waitpid() system call                */
-
-int
-sys_waitpid(pid_t pid,
-	    userptr_t status,
-	    int options,
-	    pid_t *retval)
+int sys_waitpid(pid_t pid, userptr_t status, int options, pid_t * retval)
 {
 {
-  int exitstatus;
-  int result;
-
-  /* this is just a stub implementation that always reports an
-     exit status of 0, regardless of the actual exit status of
-     the specified process.   
-     In fact, this will return 0 even if the specified process
-     is still running, and even if it never existed in the first place.
-
-     Fix this!
-  */
-
-  if (options != 0) {
+  (void)status;
+  if (options != 0)
+  {
     return(EINVAL);
     return(EINVAL);
   }
   }
-  /* for now, just pretend the exitstatus is 0 */
-  exitstatus = 0;
-  result = copyout((void *)&exitstatus,status,sizeof(int));
-  if (result) {
-    return(result);
+  
+  if (pid < PID_MIN || pid > PID_MAX) return ESRCH;
+  struct proc * target = getChild(curproc, pid);
+  
+  if (!(target)) return ECHILD;
+  if (target->exitcode >= 0)
+  {
+    *retval = target->exitcode;
+    return 0;
   }
   }
-  *retval = pid;
-  return(0);
+  
+  lock_acquire(target->waitlock);
+  cv_wait(target->waiting, target->waitlock);
+  lock_release(target->waitlock);
+  *retval = target->exitcode;
+  proc_destroy(target);
+  return 0;
 }
 }
 
 
+int sys_fork(struct trapframe * tf, int * retval)
+{
+  // create new process' memory space
+  struct proc * child = proc_create_runprogram("childproc");
+  if ((!child)) return ENOMEM;
+  
+  struct trapframe * new_tf = kmalloc(sizeof(*tf));
+  struct addrspace * new_as;
+  as_copy(curproc_getas(), &new_as);
+  
+  if (!(new_as) || !(new_tf))
+  {
+    proc_destroy(child);
+    kfree(new_as);
+    kfree(new_tf);
+    return ENOMEM;
+  }
+  
+  // set PIDs, etc. copy data in to the new space
+  child->p_addrspace = new_as;
+  child->parent = curproc;
+  add_child(curproc, child->pid);
+  *new_tf = *tf;
+  
+    // start new thread
+  thread_fork("childproc", child, enter_forked_process, new_tf, 0);
+  
+  // return correct values
+  if (curproc->pid == child->pid) *retval = 0;
+  else *retval = child->pid;
+  return 0;
+}

+ 55 - 54
kern/thread/thread.c

@@ -58,8 +58,9 @@
 #define THREAD_STACK_MAGIC 0xbaadf00d
 #define THREAD_STACK_MAGIC 0xbaadf00d
 
 
 /* Wait channel. */
 /* Wait channel. */
-struct wchan {
-	const char *wc_name;		/* name for this channel */
+struct wchan
+{
+	const char * wc_name;		/* name for this channel */
 	struct threadlist wc_threads;	/* list of waiting threads */
 	struct threadlist wc_threads;	/* list of waiting threads */
 	struct spinlock wc_lock;	/* lock for mutual exclusion */
 	struct spinlock wc_lock;	/* lock for mutual exclusion */
 };
 };
@@ -81,7 +82,7 @@ static struct semaphore *cpu_startup_sem;
  */
  */
 static
 static
 void
 void
-thread_checkstack_init(struct thread *thread)
+thread_checkstack_init(struct thread * thread)
 {
 {
 	((uint32_t *)thread->t_stack)[0] = THREAD_STACK_MAGIC;
 	((uint32_t *)thread->t_stack)[0] = THREAD_STACK_MAGIC;
 	((uint32_t *)thread->t_stack)[1] = THREAD_STACK_MAGIC;
 	((uint32_t *)thread->t_stack)[1] = THREAD_STACK_MAGIC;
@@ -99,9 +100,7 @@ thread_checkstack_init(struct thread *thread)
  * cannot be freed (which in turn is the case if the stack is the boot
  * cannot be freed (which in turn is the case if the stack is the boot
  * stack, and the thread is the boot thread) this doesn't do anything.
  * stack, and the thread is the boot thread) this doesn't do anything.
  */
  */
-static
-void
-thread_checkstack(struct thread *thread)
+static void thread_checkstack(struct thread * thread)
 {
 {
 	if (thread->t_stack != NULL) {
 	if (thread->t_stack != NULL) {
 		KASSERT(((uint32_t*)thread->t_stack)[0] == THREAD_STACK_MAGIC);
 		KASSERT(((uint32_t*)thread->t_stack)[0] == THREAD_STACK_MAGIC);
@@ -115,21 +114,21 @@ thread_checkstack(struct thread *thread)
  * Create a thread. This is used both to create a first thread
  * Create a thread. This is used both to create a first thread
  * for each CPU and to create subsequent forked threads.
  * for each CPU and to create subsequent forked threads.
  */
  */
-static
-struct thread *
-thread_create(const char *name)
+static struct thread * thread_create(const char * name)
 {
 {
-	struct thread *thread;
+	struct thread * thread;
 
 
 	DEBUGASSERT(name != NULL);
 	DEBUGASSERT(name != NULL);
 
 
 	thread = kmalloc(sizeof(*thread));
 	thread = kmalloc(sizeof(*thread));
-	if (thread == NULL) {
+	if (thread == NULL)
+	{
 		return NULL;
 		return NULL;
 	}
 	}
 
 
 	thread->t_name = kstrdup(name);
 	thread->t_name = kstrdup(name);
-	if (thread->t_name == NULL) {
+	if (thread->t_name == NULL)
+	{
 		kfree(thread);
 		kfree(thread);
 		return NULL;
 		return NULL;
 	}
 	}
@@ -162,15 +161,15 @@ thread_create(const char *name)
  * board config or whatnot) is tracked separately because it is not
  * board config or whatnot) is tracked separately because it is not
  * necessarily anything sane or meaningful.
  * necessarily anything sane or meaningful.
  */
  */
-struct cpu *
-cpu_create(unsigned hardware_number)
+struct cpu * cpu_create(unsigned hardware_number)
 {
 {
-	struct cpu *c;
+	struct cpu * c;
 	int result;
 	int result;
 	char namebuf[16];
 	char namebuf[16];
 
 
 	c = kmalloc(sizeof(*c));
 	c = kmalloc(sizeof(*c));
-	if (c == NULL) {
+	if (c == NULL)
+	{
 		panic("cpu_create: Out of memory\n");
 		panic("cpu_create: Out of memory\n");
 	}
 	}
 	
 	
@@ -190,21 +189,25 @@ cpu_create(unsigned hardware_number)
 	spinlock_init(&c->c_ipi_lock);
 	spinlock_init(&c->c_ipi_lock);
 
 
 	result = cpuarray_add(&allcpus, c, &c->c_number);
 	result = cpuarray_add(&allcpus, c, &c->c_number);
-	if (result != 0) {
+	if (result != 0)
+	{
 		panic("cpu_create: array_add: %s\n", strerror(result));
 		panic("cpu_create: array_add: %s\n", strerror(result));
 	}
 	}
 
 
 	snprintf(namebuf, sizeof(namebuf), "<boot #%d>", c->c_number);
 	snprintf(namebuf, sizeof(namebuf), "<boot #%d>", c->c_number);
 	c->c_curthread = thread_create(namebuf);
 	c->c_curthread = thread_create(namebuf);
-	if (c->c_curthread == NULL) {
+	if (c->c_curthread == NULL)
+	{
 		panic("cpu_create: thread_create failed\n");
 		panic("cpu_create: thread_create failed\n");
 	}
 	}
 	result = proc_addthread(kproc, c->c_curthread);
 	result = proc_addthread(kproc, c->c_curthread);
-	if (result) {
+	if (result)
+	{
 		panic("cpu_create: proc_addthread:: %s\n", strerror(result));
 		panic("cpu_create: proc_addthread:: %s\n", strerror(result));
 	}
 	}
 
 
-	if (c->c_number == 0) {
+	if (c->c_number == 0)
+	{
 		/*
 		/*
 		 * Leave c->c_curthread->t_stack NULL for the boot
 		 * Leave c->c_curthread->t_stack NULL for the boot
 		 * cpu. This means we're using the boot stack, which
 		 * cpu. This means we're using the boot stack, which
@@ -213,9 +216,11 @@ cpu_create(unsigned hardware_number)
 		 */
 		 */
 		/*c->c_curthread->t_stack = ... */
 		/*c->c_curthread->t_stack = ... */
 	}
 	}
-	else {
+	else
+	{
 		c->c_curthread->t_stack = kmalloc(STACK_SIZE);
 		c->c_curthread->t_stack = kmalloc(STACK_SIZE);
-		if (c->c_curthread->t_stack == NULL) {
+		if (c->c_curthread->t_stack == NULL)
+		{
 			panic("cpu_create: couldn't allocate stack");
 			panic("cpu_create: couldn't allocate stack");
 		}
 		}
 		thread_checkstack_init(c->c_curthread);
 		thread_checkstack_init(c->c_curthread);
@@ -235,9 +240,7 @@ cpu_create(unsigned hardware_number)
  *
  *
  * (Freeing the stack you're actually using to run is ... inadvisable.)
  * (Freeing the stack you're actually using to run is ... inadvisable.)
  */
  */
-static
-void
-thread_destroy(struct thread *thread)
+static void thread_destroy(struct thread * thread)
 {
 {
 	KASSERT(thread != curthread);
 	KASSERT(thread != curthread);
 	KASSERT(thread->t_state != S_RUN);
 	KASSERT(thread->t_state != S_RUN);
@@ -249,7 +252,8 @@ thread_destroy(struct thread *thread)
 
 
 	/* Thread subsystem fields */
 	/* Thread subsystem fields */
 	KASSERT(thread->t_proc == NULL);
 	KASSERT(thread->t_proc == NULL);
-	if (thread->t_stack != NULL) {
+	if (thread->t_stack != NULL)
+	{
 		kfree(thread->t_stack);
 		kfree(thread->t_stack);
 	}
 	}
 	threadlistnode_cleanup(&thread->t_listnode);
 	threadlistnode_cleanup(&thread->t_listnode);
@@ -268,13 +272,12 @@ thread_destroy(struct thread *thread)
  *
  *
  * The list of zombies is per-cpu.
  * The list of zombies is per-cpu.
  */
  */
-static
-void
-exorcise(void)
+static void exorcise(void)
 {
 {
-	struct thread *z;
+	struct thread * z;
 
 
-	while ((z = threadlist_remhead(&curcpu->c_zombies)) != NULL) {
+	while ((z = threadlist_remhead(&curcpu->c_zombies)) != NULL)
+	{
 		KASSERT(z != curthread);
 		KASSERT(z != curthread);
 		KASSERT(z->t_state == S_ZOMBIE);
 		KASSERT(z->t_state == S_ZOMBIE);
 		thread_destroy(z);
 		thread_destroy(z);
@@ -286,8 +289,7 @@ exorcise(void)
  * possible) to make sure we don't end up letting any other threads
  * possible) to make sure we don't end up letting any other threads
  * run.
  * run.
  */
  */
-void
-thread_panic(void)
+void thread_panic(void)
 {
 {
 	/*
 	/*
 	 * Kill off other CPUs.
 	 * Kill off other CPUs.
@@ -328,8 +330,7 @@ thread_panic(void)
 /*
 /*
  * At system shutdown, ask the other CPUs to switch off.
  * At system shutdown, ask the other CPUs to switch off.
  */
  */
-void
-thread_shutdown(void)
+void thread_shutdown(void)
 {
 {
 	/*
 	/*
 	 * Stop the other CPUs.
 	 * Stop the other CPUs.
@@ -343,11 +344,10 @@ thread_shutdown(void)
 /*
 /*
  * Thread system initialization.
  * Thread system initialization.
  */
  */
-void
-thread_bootstrap(void)
+void thread_bootstrap(void)
 {
 {
-	struct cpu *bootcpu;
-	struct thread *bootthread;
+	struct cpu * bootcpu;
+	struct thread * bootthread;
 
 
 	cpuarray_init(&allcpus);
 	cpuarray_init(&allcpus);
 
 
@@ -391,8 +391,7 @@ thread_bootstrap(void)
  * to do anything. The startup thread can just exit; we only need it
  * to do anything. The startup thread can just exit; we only need it
  * to be able to get into thread_switch() properly.
  * to be able to get into thread_switch() properly.
  */
  */
-void
-cpu_hatch(unsigned software_number)
+void cpu_hatch(unsigned software_number)
 {
 {
 	KASSERT(curcpu != NULL);
 	KASSERT(curcpu != NULL);
 	KASSERT(curthread != NULL);
 	KASSERT(curthread != NULL);
@@ -409,8 +408,7 @@ cpu_hatch(unsigned software_number)
 /*
 /*
  * Start up secondary cpus. Called from boot().
  * Start up secondary cpus. Called from boot().
  */
  */
-void
-thread_start_cpus(void)
+void thread_start_cpus(void)
 {
 {
 	unsigned i;
 	unsigned i;
 
 
@@ -419,7 +417,8 @@ thread_start_cpus(void)
 	cpu_startup_sem = sem_create("cpu_hatch", 0);
 	cpu_startup_sem = sem_create("cpu_hatch", 0);
 	mainbus_start_cpus();
 	mainbus_start_cpus();
 	
 	
-	for (i=0; i<cpuarray_num(&allcpus) - 1; i++) {
+	for (i=0; i<cpuarray_num(&allcpus) - 1; i++)
+	{
 		P(cpu_startup_sem);
 		P(cpu_startup_sem);
 	}
 	}
 	sem_destroy(cpu_startup_sem);
 	sem_destroy(cpu_startup_sem);
@@ -429,29 +428,30 @@ thread_start_cpus(void)
 /*
 /*
  * Make a thread runnable.
  * Make a thread runnable.
  *
  *
- * targetcpu might be curcpu; it might not be, too. 
+ * targetcpu might be curcpu; it might not be, too.
  */
  */
-static
-void
-thread_make_runnable(struct thread *target, bool already_have_lock)
+static void thread_make_runnable(struct thread * target, bool already_have_lock)
 {
 {
-	struct cpu *targetcpu;
+	struct cpu * targetcpu;
 	bool isidle;
 	bool isidle;
 
 
 	/* Lock the run queue of the target thread's cpu. */
 	/* Lock the run queue of the target thread's cpu. */
 	targetcpu = target->t_cpu;
 	targetcpu = target->t_cpu;
 
 
-	if (already_have_lock) {
+	if (already_have_lock)
+	{
 		/* The target thread's cpu should be already locked. */
 		/* The target thread's cpu should be already locked. */
 		KASSERT(spinlock_do_i_hold(&targetcpu->c_runqueue_lock));
 		KASSERT(spinlock_do_i_hold(&targetcpu->c_runqueue_lock));
 	}
 	}
-	else {
+	else
+	{
 		spinlock_acquire(&targetcpu->c_runqueue_lock);
 		spinlock_acquire(&targetcpu->c_runqueue_lock);
 	}
 	}
 
 
 	isidle = targetcpu->c_isidle;
 	isidle = targetcpu->c_isidle;
 	threadlist_addtail(&targetcpu->c_runqueue, target);
 	threadlist_addtail(&targetcpu->c_runqueue, target);
-	if (isidle) {
+	if (isidle)
+	{
 		/*
 		/*
 		 * Other processor is idle; send interrupt to make
 		 * Other processor is idle; send interrupt to make
 		 * sure it unidles.
 		 * sure it unidles.
@@ -459,7 +459,8 @@ thread_make_runnable(struct thread *target, bool already_have_lock)
 		ipi_send(targetcpu, IPI_UNIDLE);
 		ipi_send(targetcpu, IPI_UNIDLE);
 	}
 	}
 
 
-	if (!already_have_lock) {
+	if (!already_have_lock)
+	{
 		spinlock_release(&targetcpu->c_runqueue_lock);
 		spinlock_release(&targetcpu->c_runqueue_lock);
 	}
 	}
 }
 }
@@ -787,7 +788,7 @@ thread_exit(void)
 #ifdef UW
 #ifdef UW
 	/* threads for user processes should have detached from their process
 	/* threads for user processes should have detached from their process
 	   in sys__exit */
 	   in sys__exit */
-	KASSERT(curproc == kproc || curproc == NULL);	
+	KASSERT(curproc == kproc || curproc == NULL || curproc->exitcode != -1);
 	/* kernel threads don't go through sys__exit, so we detach them from kproc here */
 	/* kernel threads don't go through sys__exit, so we detach them from kproc here */
 	if (curproc == kproc) {
 	if (curproc == kproc) {
 	  proc_remthread(cur);
 	  proc_remthread(cur);

+ 5 - 0
progress.txt

@@ -0,0 +1,5 @@
+modified files:
+proc.h
+proc.c
+list.h
+list.c