Revise makefile structure.
authorBen Pfaff <blp@cs.stanford.edu>
Mon, 20 Sep 2004 03:01:41 +0000 (03:01 +0000)
committerBen Pfaff <blp@cs.stanford.edu>
Mon, 20 Sep 2004 03:01:41 +0000 (03:01 +0000)
Add user tests.

32 files changed:
src/Make.config [new file with mode: 0644]
src/Makefile
src/Makefile.build
src/Makefile.kernel
src/TODO
src/filesys/Make.vars [new file with mode: 0644]
src/filesys/Makefile
src/filesys/Makefile.vars [deleted file]
src/lib/stdio.h
src/lib/syscall-nr.h
src/lib/user/console.c
src/lib/user/syscall.c
src/lib/user/syscall.h
src/lib/user/user.c [deleted file]
src/lib/user/user.h [deleted file]
src/tests/Makefile [new file with mode: 0644]
src/tests/userprog/Makefile [new file with mode: 0644]
src/tests/userprog/bubsort.c [new file with mode: 0644]
src/tests/userprog/echo.c [new file with mode: 0644]
src/tests/userprog/elf.x [new file with mode: 0644]
src/tests/userprog/halt.c [new file with mode: 0644]
src/tests/userprog/insult.c [new file with mode: 0644]
src/tests/userprog/lineup.c [new file with mode: 0644]
src/tests/userprog/matmult.c [new file with mode: 0644]
src/tests/userprog/recursor.c [new file with mode: 0644]
src/tests/userprog/shell.c [new file with mode: 0644]
src/threads/Make.vars [new file with mode: 0644]
src/threads/Makefile
src/threads/Makefile.vars [deleted file]
src/userprog/Make.vars [new file with mode: 0644]
src/userprog/Makefile
src/userprog/Makefile.vars [deleted file]

diff --git a/src/Make.config b/src/Make.config
new file mode 100644 (file)
index 0000000..d4143b8
--- /dev/null
@@ -0,0 +1,33 @@
+# -*- makefile -*-
+
+SHELL = /bin/sh
+
+# Binary utilities.
+# If the host appears to be x86, use the normal tools.
+# Otherwise assume cross-tools are installed as i386-elf-*.
+X86 = i.86\|pentium.*\|[pk][56]\|nexgen\|viac3\|6x86\|athlon.*
+ifneq (0, $(shell expr `uname -m` : '$(X86)'))
+CC = gcc
+LD = ld
+OBJCOPY = objcopy
+else
+CC = i386-elf-gcc
+LD = i386-elf-ld
+OBJCOPY = i386-elf-objcopy
+endif
+
+# Other utilities.
+DD = dd
+RM = rm
+CAT = cat
+
+# Compiler and assembler invocation.
+WARNINGS = -Wall -W -Wstrict-prototypes -Wmissing-prototypes
+CFLAGS = -g -O3 -MMD -msoft-float 
+ASFLAGS = -Wa,--gstabs -MMD
+
+%.o: %.c
+       $(CC) -c $< -o $@ $(CFLAGS) $(CPPFLAGS) $(WARNINGS) $(DEFINES)
+
+%.o: %.S
+       $(CC) -c $< -o $@ $(ASFLAGS) $(CPPFLAGS) $(DEFINES)
index d6d325516d88f40805af8eb05aa190e4b194d62e..90c36af421eaa8af9e1ba016920c02552dfcca4a 100644 (file)
@@ -5,15 +5,14 @@ all::
        @echo "This top-level make has only 'clean' targets."
 
 clean::
-       for d in $(SUBDIRS); do $(MAKE) -C $$d $@; done
+       for d in $(SUBDIRS) tests; do $(MAKE) -C $$d $@; done
 
-distclean::
-       $(MAKE) clean
+distclean:: clean
        find . -name '*~' -exec rm '{}' \;
 
 TAGS::
-       etags --members `find . -name \*.[chS]`
+       etags --members *.[chS] `find $(SUBDIRS) -name \*.[chS]`
 
 tags::
-       ctags -T `find . -name \*.[chS]`
+       ctags -T *.[chS] `find . -name \*.[chS]`
 
index 8a7348590772227fc466643b433e39796b2106b7..1c92b77d2783b36e757626687b9fe06d5ca4c4b1 100644 (file)
@@ -1,37 +1,14 @@
 # -*- makefile -*-
 
-include ../Makefile.vars
-
-SHELL = /bin/sh
-
-# Binary utilities.
-# If the host appears to be x86, use the normal tools.
-# Otherwise assume cross-tools are installed as i386-elf-*.
-X86 = i.86\|pentium.*\|[pk][56]\|nexgen\|viac3\|6x86\|athlon.*
-ifneq (0, $(shell expr `uname -m` : '$(X86)'))
-CC = gcc
-LD = ld
-OBJCOPY = objcopy
-else
-CC = i386-elf-gcc
-LD = i386-elf-ld
-OBJCOPY = i386-elf-objcopy
-endif
-
-# Other utilities.
-DD = dd
-RM = rm
-CAT = cat
+include ../Make.vars
+include ../../Make.config
 
 VPATH = ../..
 
 # Compiler and assembler options.
 DEFINES += -DKERNEL
-WARNINGS = -Wall -W -Wstrict-prototypes -Wmissing-prototypes
 CPPFLAGS = -nostdinc -I../.. -I- -I../../lib -I../../lib/kernel        \
           -include constants.h
-CFLAGS = -g -O3 -MMD -msoft-float 
-ASFLAGS = -Wa,--gstabs -MMD
 
 # Core kernel.
 threads_SRC  = threads/init.c          # Main program.
@@ -119,10 +96,4 @@ clean:
 Makefile: ../../Makefile.build
        cp $< $@
 
-%.o: %.c
-       $(CC) -c $< -o $@ $(CFLAGS) $(CPPFLAGS) $(WARNINGS) $(DEFINES)
-
-%.o: %.S
-       $(CC) -c $< -o $@ $(ASFLAGS) $(CPPFLAGS) $(DEFINES)
-
 -include $(DEPENDS)
index c1985c4537f791da77fe27e11228014baeec2c6e..fe63d5273174e5a00a21bb57ca2a8a2db508d9d2 100644 (file)
@@ -1,4 +1,4 @@
-include Makefile.vars
+include Make.vars
 BUILD_SUBDIRS = $(addprefix build/, $(SUBDIRS))
 CP = cp
 MKDIR = mkdir
index 96007c117c5fb2527cc5795fd7e42267e3f9ff9d..f3f6d0759fbd6961ec73a50116314c346f6371fa 100644 (file)
--- a/src/TODO
+++ b/src/TODO
@@ -1,3 +1,7 @@
+* Get rid of names for synch primitives?  They increase the size of
+  each one by 16 bytes and are probably not that useful.
+  Alternatively make the names pointers?
+
 * Write, test user programs.
   - addrspace_load() should return thread's esp.
   - thread_execute() shouldn't panic on failure (!).
diff --git a/src/filesys/Make.vars b/src/filesys/Make.vars
new file mode 100644 (file)
index 0000000..5899e51
--- /dev/null
@@ -0,0 +1,6 @@
+DEFINES = -DUSERPROG -DFILESYS
+SUBDIRS = threads devices lib lib/kernel userprog filesys
+
+# Comment out the two lines below to disable VM.
+DEFINES += -DVM
+SUBDIRS += vm
index bc2307b342f5b8fbdfdaf0c8cac9fd9a16d6f749..34c10aa4f508714da040e81389fa51e56ba2d97a 100644 (file)
@@ -1,2 +1 @@
-include Makefile.vars
 include ../Makefile.kernel
diff --git a/src/filesys/Makefile.vars b/src/filesys/Makefile.vars
deleted file mode 100644 (file)
index 5899e51..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-DEFINES = -DUSERPROG -DFILESYS
-SUBDIRS = threads devices lib lib/kernel userprog filesys
-
-# Comment out the two lines below to disable VM.
-DEFINES += -DVM
-SUBDIRS += vm
index 4609fb3be1e1cca30ebb13498c5c62cc78ae428e..b351dd16a5cf09cf7451dd56b8498a5c9c34aaf8 100644 (file)
@@ -6,15 +6,23 @@
 #include <stddef.h>
 #include <stdarg.h>
 
+/* Predefined file handles. */
+#define STDIN_FILENO 0
+#define STDOUT_FILENO 1
+
 /* Standard functions. */
-int vsnprintf (char *, size_t, const char *, va_list) PRINTF_FORMAT (3, 0);
+int printf (const char *, ...) PRINTF_FORMAT (1, 2);
 int snprintf (char *, size_t, const char *, ...) PRINTF_FORMAT (3, 4);
 int vprintf (const char *, va_list) PRINTF_FORMAT (1, 0);
-int printf (const char *, ...) PRINTF_FORMAT (1, 2);
+int vsnprintf (char *, size_t, const char *, va_list) PRINTF_FORMAT (3, 0);
 int putchar (int);
 int puts (const char *);
 
 /* Nonstandard functions. */
+#ifndef KERNEL
+int hprintf (int, const char *, ...) PRINTF_FORMAT (2, 3);
+int vhprintf (int, const char *, va_list) PRINTF_FORMAT (2, 0);
+#endif
 void hex_dump (const void *, size_t size, bool ascii);
 
 /* Internal functions. */
index 72e06f41dd3755aa2decd6126f5b7b6085c0444b..5a243bd28798ef9d92747d16f38839f6028cb1c3 100644 (file)
 #define SYS_filesize 7          /* Obtains a file's size. */
 #define SYS_read 8              /* Reads from a file. */
 #define SYS_write 9             /* Writes to a file. */
-#define SYS_close 10            /* Closes a file. */
-#define SYS_mmap 12             /* Maps a file into memory. */
-#define SYS_munmap 13           /* Removes a memory mapping. */
-#define SYS_chdir 14            /* Changes the current directory. */
-#define SYS_mkdir 15            /* Create a directory. */
-#define SYS_lsdir 16            /* Lists the current directory to stdout. */
-
-/* Predefined file handles. */
-#define STDIN_FILENO 0
-#define STDOUT_FILENO 1
+#define SYS_seek 10             /* Change position in a file. */
+#define SYS_tell 11             /* Report current position in a file. */
+#define SYS_close 12            /* Closes a file. */
+#define SYS_mmap 13             /* Maps a file into memory. */
+#define SYS_munmap 14           /* Removes a memory mapping. */
+#define SYS_chdir 15            /* Changes the current directory. */
+#define SYS_mkdir 16            /* Create a directory. */
+#define SYS_lsdir 17            /* Lists the current directory to stdout. */
 
 #endif /* lib/syscall-nr.h */
index 709a5c86ad6ebc5186af9c8497b86eada1bd8c71..d2b9dc72f44899704d14fc48f113e269cea5b0fc 100644 (file)
@@ -2,43 +2,26 @@
 #include <syscall.h>
 #include <syscall-nr.h>
 
-static void vprintf_helper (char, void *);
-
-/* Auxiliary data for vprintf_helper(). */
-struct vprintf_aux 
-  {
-    char buf[64];       /* Character buffer. */
-    char *p;            /* Current position in buffer. */
-    int char_cnt;       /* Total characters written so far. */
-  };
-
 /* The standard vprintf() function,
-   which is like printf() but uses a va_list.
-   Writes its output to the STDOUT_FILENO handle. */
+   which is like printf() but uses a va_list. */
 int
 vprintf (const char *format, va_list args) 
 {
-  struct vprintf_aux aux;
-  aux.p = aux.buf;
-  aux.char_cnt = 0;
-  __vprintf (format, args, vprintf_helper, &aux);
-  if (aux.p > aux.buf)
-    write (STDOUT_FILENO, aux.buf, aux.p - aux.buf);
-  return aux.char_cnt;
+  return vhprintf (STDOUT_FILENO, format, args);
 }
 
-/* Helper function for vprintf(). */
-static void
-vprintf_helper (char c, void *aux_
+/* Like printf(), but writes output to the given HANDLE. */
+int
+hprintf (int handle, const char *format, ...
 {
-  struct vprintf_aux *aux = aux_;
-  *aux->p++ = c;
-  if (aux->p >= aux->buf + sizeof aux->buf)
-    {
-      write (STDOUT_FILENO, aux->buf, aux->p - aux->buf);
-      aux->p = aux->buf;
-    }
-  aux->char_cnt++;
+  va_list args;
+  int retval;
+
+  va_start (args, format);
+  retval = vhprintf (handle, format, args);
+  va_end (args);
+
+  return retval;
 }
 
 /* Writes string S to the console, followed by a new-line
@@ -61,3 +44,51 @@ putchar (int c)
   write (STDOUT_FILENO, &c2, 1);
   return c;
 }
+\f
+/* Auxiliary data for vhprintf_helper(). */
+struct vhprintf_aux 
+  {
+    char buf[64];       /* Character buffer. */
+    char *p;            /* Current position in buffer. */
+    int char_cnt;       /* Total characters written so far. */
+    int handle;         /* Output file handle. */
+  };
+
+static void add_char (char, void *);
+static void flush (struct vhprintf_aux *);
+
+/* Formats the printf() format specification FORMAT with
+   arguments given in ARGS and writes the output to the given
+   HANDLE. */
+int
+vhprintf (int handle, const char *format, va_list args) 
+{
+  struct vhprintf_aux aux;
+  aux.p = aux.buf;
+  aux.char_cnt = 0;
+  aux.handle = handle;
+  __vprintf (format, args, add_char, &aux);
+  flush (&aux);
+  return aux.char_cnt;
+}
+
+/* Adds C to the buffer in AUX, flushing it if the buffer fills
+   up. */
+static void
+add_char (char c, void *aux_) 
+{
+  struct vhprintf_aux *aux = aux_;
+  *aux->p++ = c;
+  if (aux->p >= aux->buf + sizeof aux->buf)
+    flush (aux);
+  aux->char_cnt++;
+}
+
+/* Flushes the buffer in AUX. */
+static void
+flush (struct vhprintf_aux *aux)
+{
+  if (aux->p > aux->buf)
+    write (aux->handle, aux->buf, aux->p - aux->buf);
+  aux->p = aux->buf;
+}
index efabc018c4b80650b9c896c08e16382fc834577d..506712f323a2e07e7acf2078fa63ad2cd751e0c1 100644 (file)
@@ -58,6 +58,18 @@ write (int fd, const void *buffer, unsigned size)
   return syscall (SYS_write, fd, buffer, size);
 }
 
+void
+seek (int fd, unsigned position) 
+{
+  syscall (SYS_seek, fd, position);
+}
+
+unsigned
+tell (int fd) 
+{
+  return syscall (SYS_tell, fd);
+}
+
 void
 close (int fd)
 {
index a594016cb1ff1db565f5739a97169f873d00167a..c07f3ea6b7fa3bf93fc3edfaa3bdc2e54276b720 100644 (file)
@@ -16,6 +16,8 @@ int open (const char *file);
 int filesize (int fd);
 int read (int fd, void *buffer, unsigned length);
 int write (int fd, const void *buffer, unsigned length);
+void seek (int fd, unsigned position);
+unsigned tell (int fd);
 void close (int fd);
 bool mmap (int fd, void *addr, unsigned length);
 bool munmap (void *addr, unsigned length);
diff --git a/src/lib/user/user.c b/src/lib/user/user.c
deleted file mode 100644 (file)
index 8b13789..0000000
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/src/lib/user/user.h b/src/lib/user/user.h
deleted file mode 100644 (file)
index 6bebf6d..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef __LIB_USER_USER_H
-#define __LIB_USER_USER_H
-
-#ifdef KERNEL
-#error This header is user-only.
-#endif
-
-/* <stdlib.h> */
-#define EXIT_SUCCESS 0
-#define EXIT_FAILURE 1
-void exit (int);
-void abort (void);
-
-#endif /* lib/user/user.h */
diff --git a/src/tests/Makefile b/src/tests/Makefile
new file mode 100644 (file)
index 0000000..764eae6
--- /dev/null
@@ -0,0 +1,8 @@
+all::
+       $(MAKE) -C userprog
+
+clean::
+       $(MAKE) -C userprog clean
+
+distclean:: clean
+       find . -name '*~' -exec rm '{}' \;
diff --git a/src/tests/userprog/Makefile b/src/tests/userprog/Makefile
new file mode 100644 (file)
index 0000000..9af275f
--- /dev/null
@@ -0,0 +1,63 @@
+include ../../Make.config
+
+SHELL = /bin/sh
+
+LDFLAGS = -nostdlib -static -Wl,-T,elf.x
+LDLIBS = $(shell $(CC) -print-libgcc-file-name)
+
+VPATH = ../..
+
+DEFINES = -DUSER
+CPPFLAGS = -nostdinc -I../.. -I- -I../../lib -I../../lib/user
+
+# C library sources linked into every test program.
+LIB_SRC  = lib/debug.c                 # Debug code.
+LIB_SRC += lib/random.c                        # Pseudo-random numbers.
+LIB_SRC += lib/stdio.c                 # I/O library.
+LIB_SRC += lib/stdlib.c                        # atoi()
+LIB_SRC += lib/string.c                        # String functions.
+LIB_SRC += lib/user/syscall.c          # System calls.
+LIB_SRC += lib/user/syscall-stub.S     # System call stub.
+LIB_SRC += lib/user/console.c          # Console code.
+
+LIB_OBJ = $(patsubst %.c,%.o,$(patsubst %.S,%.o,$(LIB_SRC)))
+LIB_DEP = $(patsubst %.o,%.d,$(LIB_OBJ))
+LIB = libc.a lib/user/entry.o
+
+PROGS = bubsort echo halt insult lineup matmult recursor shell
+bubsort_SRC = bubsort.c
+echo_SRC = echo.c
+halt_SRC = halt.c
+insult_SRC = insult.c
+lineup_SRC = lineup.c
+matmult_SRC = matmult.c
+recursor_SRC = recursor.c
+shell_SRC = shell.c
+
+PROGS_SRC = $(foreach prog,$(PROGS),$($(prog)_SRC))
+PROGS_OBJ = $(patsubst %.c,%.o,$(patsubst %.S,%.o,$(PROGS_SRC)))
+PROGS_DEP = $(patsubst %.o,%.d,$(PROGS_OBJ))
+
+all: $(PROGS)
+
+define TEMPLATE
+$(1)_OBJ = $(patsubst %.c,%.o,$(patsubst %.S,%.o,$($(1)_SRC)))
+$(1): $$($(1)_OBJ) $$(LIB)
+endef
+
+$(foreach prog,$(PROGS),$(eval $(call TEMPLATE,$(prog))))
+
+$(PROGS): $(LIB)
+
+libc.a: $(LIB_OBJ)
+       rm -f $@
+       ar r $@ $^
+       ranlib $@
+
+clean:
+       rm -f $(PROGS) $(PROGS_OBJ) $(PROGS_DEP)
+       rm -f $(LIB_DEP) $(LIB_OBJ) lib/user/entry.[do] libc.a 
+
+.PHONY: all clean
+
+-include $(LIB_DEP) $(PROGS_DEP)
diff --git a/src/tests/userprog/bubsort.c b/src/tests/userprog/bubsort.c
new file mode 100644 (file)
index 0000000..343219e
--- /dev/null
@@ -0,0 +1,38 @@
+/* sort.c 
+
+   Test program to sort a large number of integers.
+   Intention is to stress virtual memory system.
+   Ideally, we could read the unsorted array off of the file
+   system, and store the result back to the file system! */
+#include <stdio.h>
+
+/* Size of array to sort. */
+#define SORT_SIZE 128
+
+int
+main (void)
+{
+  /* Array to sort.  Static to reduce stack usage. */
+  static int array[SORT_SIZE];
+
+  int i, j, tmp;
+
+  /* First initialize the array in descending order. */
+  for (i = 0; i < SORT_SIZE; i++)
+    array[i] = SORT_SIZE - i - 1;
+
+  /* Then sort in ascending order. */
+  for (i = 0; i < SORT_SIZE - 1; i++)
+    for (j = 0; j < SORT_SIZE - 1 - i; j++)
+      if (array[j] > array[j + 1])
+       {
+         tmp = array[j];
+         array[j] = array[j + 1];
+         array[j + 1] = tmp;
+       }
+
+  printf ("sort exiting with code %d\n", array[0]);
+  return array[0];
+}
diff --git a/src/tests/userprog/echo.c b/src/tests/userprog/echo.c
new file mode 100644 (file)
index 0000000..c0ecd00
--- /dev/null
@@ -0,0 +1,13 @@
+#include <stdio.h>
+
+int
+main (int argc, char **argv)
+{
+  int i;
+
+  for (i = 0; i < argc; i++)
+    printf ("%s ", argv[i]);
+  printf ("\n");
+
+  return 0;
+}
diff --git a/src/tests/userprog/elf.x b/src/tests/userprog/elf.x
new file mode 100644 (file)
index 0000000..2fb94e1
--- /dev/null
@@ -0,0 +1,24 @@
+/* Default linker script, for normal executables */
+OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
+OUTPUT_ARCH(i386)
+ENTRY(_start)
+SECTIONS
+{
+  . = 0x08048000 + SIZEOF_HEADERS;
+  .text : { 
+    *(.text .text.*) 
+    . = ALIGN(0x1000);
+  } =0x90909090
+  .rodata : { 
+    *(.rodata .rodata.*) 
+    . = ALIGN(0x1000); 
+  }
+  .data : { 
+    *(.data .data.*) 
+    . = ALIGN(0x1000);
+  } 
+  .bss : { 
+    *(.bss .bss.*)
+    . = ALIGN(0x1000);
+  }
+}
diff --git a/src/tests/userprog/halt.c b/src/tests/userprog/halt.c
new file mode 100644 (file)
index 0000000..bad7250
--- /dev/null
@@ -0,0 +1,14 @@
+/* halt.c
+
+   Simple program to test whether running a user program works.
+       
+   Just invokes a system call that shuts down the OS. */
+
+#include <syscall.h>
+
+int
+main (void)
+{
+  halt ();
+  /* not reached */
+}
diff --git a/src/tests/userprog/insult.c b/src/tests/userprog/insult.c
new file mode 100644 (file)
index 0000000..2f7933d
--- /dev/null
@@ -0,0 +1,364 @@
+/* Insult.c
+
+   This is a version of the famous CS 107 random sentence
+   generator.  I wrote a program that reads a grammar definition
+   file and writes a C file containing that grammar as hard code
+   static C strings.  Thus the majority of the code below in
+   machine generated and totally unreadable.  The arrays created
+   are specially designed to make generating the sentences as
+   easy as possible.
+
+   Originally by Greg Hutchins, March 1998.
+   Modified by Ben Pfaff for Pintos, Sept 2004. */
+char *start[] =
+  { "You", "1", "5", ".", "May", "13", ".", "With", "the", "19", "of", "18",
+",", "may", "13", "."
+};
+char startLoc[] = { 3, 0, 4, 7, 16 };
+char *adj[] = { "3", "4", "2", ",", "1" };
+char adjLoc[] = { 3, 0, 1, 2, 5 };
+char *adj3[] = { "3", "4" };
+char adj3Loc[] = { 2, 0, 1, 2 };
+char *adj1[] =
+  { "lame", "dried", "up", "par-broiled", "bloated", "half-baked", "spiteful",
+"egotistical", "ungrateful", "stupid", "moronic", "fat", "ugly", "puny", "pitiful",
+"insignificant", "blithering", "repulsive", "worthless", "blundering", "retarded",
+"useless", "obnoxious", "low-budget", "assinine", "neurotic", "subhuman", "crochety",
+"indescribable", "contemptible", "unspeakable", "sick", "lazy", "good-for-nothing",
+"slutty", "mentally-deficient", "creepy", "sloppy", "dismal", "pompous", "pathetic",
+"friendless", "revolting", "slovenly", "cantankerous", "uncultured", "insufferable",
+"gross", "unkempt", "defective", "crumby"
+};
+char adj1Loc[] =
+  { 50, 0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
+43, 44, 45, 46, 47, 48, 49, 50, 51 };
+char *adj2[] =
+  { "putrefied", "festering", "funky", "moldy", "leprous", "curdled", "fetid",
+"slimy", "crusty", "sweaty", "damp", "deranged", "smelly", "stenchy", "malignant",
+"noxious", "grimy", "reeky", "nasty", "mutilated", "sloppy", "gruesome", "grisly",
+"sloshy", "wormy", "mealy", "spoiled", "contaminated", "rancid", "musty",
+"fly-covered", "moth-eaten", "decaying", "decomposed", "freeze-dried", "defective",
+"petrified", "rotting", "scabrous", "hirsute"
+};
+char adj2Loc[] =
+  { 40, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40 };
+char *name[] =
+  { "10", ",", "bad", "excuse", "for", "6", ",", "6", "for", "brains", ",",
+"4", "11", "8", "for", "brains", "offspring", "of", "a", "motherless", "10", "7", "6",
+"7", "4", "11", "8"
+};
+char nameLoc[] = { 7, 0, 1, 6, 10, 16, 21, 23, 27 };
+char *stuff[] =
+  { "shit", "toe", "jam", "filth", "puss", "earwax", "leaf", "clippings",
+"bat", "guano", "mucus", "fungus", "mung", "refuse", "earwax", "spittoon", "spittle",
+"phlegm"
+};
+char stuffLoc[] = { 14, 0, 1, 3, 4, 5, 6, 8, 10, 11, 12, 13, 14, 15, 17, 18 };
+char *noun_and_prep[] =
+  { "bit", "of", "piece", "of", "vat", "of", "lump", "of", "crock", "of",
+"ball", "of", "tub", "of", "load", "of", "bucket", "of", "mound", "of", "glob", "of", "bag",
+"of", "heap", "of", "mountain", "of", "load", "of", "barrel", "of", "sack", "of", "blob", "of",
+"pile", "of", "truckload", "of", "vat", "of"
+};
+char noun_and_prepLoc[] =
+  { 21, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36,
+38, 40, 42 };
+char *organics[] =
+  { "droppings", "mung", "zits", "puckies", "tumors", "cysts", "tumors",
+"livers", "froth", "parts", "scabs", "guts", "entrails", "blubber", "carcuses", "gizards",
+"9"
+};
+char organicsLoc[] =
+  { 17, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 };
+char *body_parts[] =
+  { "kidneys", "genitals", "buttocks", "earlobes", "innards", "feet"
+};
+char body_partsLoc[] = { 6, 0, 1, 2, 3, 4, 5, 6 };
+char *noun[] =
+  { "pop", "tart", "warthog", "twinkie", "barnacle", "fondue", "pot",
+"cretin", "fuckwad", "moron", "ass", "neanderthal", "nincompoop", "simpleton", "11"
+};
+char nounLoc[] = { 13, 0, 2, 3, 4, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
+char *animal[] =
+  { "donkey", "llama", "dingo", "lizard", "gekko", "lemur", "moose", "camel",
+"goat", "eel"
+};
+char animalLoc[] = { 10, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
+char *good_verb[] =
+  { "love", "cuddle", "fondle", "adore", "smooch", "hug", "caress", "worship",
+"look", "at", "touch"
+};
+char good_verbLoc[] = { 10, 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11 };
+char *curse[] =
+  { "14", "20", "23", "14", "17", "20", "23", "14", "find", "your", "9",
+"suddenly", "delectable", "14", "and", "14", "seek", "a", "battleground", "23"
+};
+char curseLoc[] = { 4, 0, 3, 7, 13, 20 };
+char *afflictors[] =
+  { "15", "21", "15", "21", "15", "21", "15", "21", "a", "22", "Rush",
+"Limbaugh", "the", "hosts", "of", "Hades"
+};
+char afflictorsLoc[] = { 6, 0, 2, 4, 6, 8, 12, 16 };
+char *quantity[] =
+  { "a", "4", "hoard", "of", "a", "4", "pack", "of", "a", "truckload", "of",
+"a", "swarm", "of", "many", "an", "army", "of", "a", "4", "heard", "of", "a", "4",
+"platoon", "of", "a", "4", "and", "4", "group", "of", "16"
+};
+char quantityLoc[] = { 10, 0, 4, 8, 11, 14, 15, 18, 22, 26, 32, 33 };
+char *numbers[] =
+  { "a", "thousand", "three", "million", "ninty-nine", "nine-hundred,",
+"ninty-nine", "forty-two", "a", "gazillion", "sixty-eight", "times", "thirty-three"
+};
+char numbersLoc[] = { 7, 0, 2, 4, 5, 7, 8, 10, 13 };
+char *adv[] =
+  { "viciously", "manicly", "merrily", "happily", ",", "with", "the", "19",
+"of", "18", ",", "gleefully", ",", "with", "much", "ritualistic", "celebration", ",",
+"franticly"
+};
+char advLoc[] = { 8, 0, 1, 2, 3, 4, 11, 12, 18, 19 };
+char *metaphor[] =
+  { "an", "irate", "manticore", "Thor's", "belch", "Alah's", "fist", "16",
+"titans", "a", "particularly", "vicious", "she-bear", "in", "the", "midst", "of", "her",
+"menstrual", "cycle", "a", "pissed-off", "Jabberwock"
+};
+char metaphorLoc[] = { 6, 0, 3, 5, 7, 9, 20, 23 };
+char *force[] = { "force", "fury", "power", "rage" };
+char forceLoc[] = { 4, 0, 1, 2, 3, 4 };
+char *bad_action[] =
+  { "spit", "shimmy", "slobber", "find", "refuge", "find", "shelter", "dance",
+"retch", "vomit", "defecate", "erect", "a", "strip", "mall", "build", "a", "26", "have", "a",
+"religious", "experience", "discharge", "bodily", "waste", "fart", "dance", "drool",
+"lambada", "spill", "16", "rusty", "tacks", "bite", "you", "sneeze", "sing", "16",
+"campfire", "songs", "smite", "you", "16", "times", "construct", "a", "new", "home", "throw",
+"a", "party", "procreate"
+};
+char bad_actionLoc[] =
+  { 25, 0, 1, 2, 3, 5, 7, 8, 9, 10, 11, 15, 18, 22, 25, 26, 27, 28, 29, 33,
+35, 36, 40, 44, 48, 51, 52 };
+char *beasties[] =
+  { "yaks", "22", "maggots", "22", "cockroaches", "stinging", "scorpions",
+"fleas", "22", "weasels", "22", "gnats", "South", "American", "killer", "bees", "spiders",
+"4", "monkeys", "22", "wiener-dogs", "22", "rats", "22", "wolverines", "4", ",", "22",
+"pit-fiends"
+};
+char beastiesLoc[] =
+  { 14, 0, 1, 3, 5, 7, 8, 10, 12, 16, 17, 19, 21, 23, 25, 29 };
+char *condition[] =
+  { "frothing", "manic", "crazed", "plague-ridden", "disease-carrying",
+"biting", "rabid", "blood-thirsty", "ravaging", "slavering"
+};
+char conditionLoc[] = { 10, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
+char *place[] =
+  { "in", "24", "25", "upon", "your", "mother's", "grave", "on", "24", "best",
+"rug", "in", "the", "26", "you", "call", "home", "upon", "your", "heinie"
+};
+char placeLoc[] = { 5, 0, 3, 7, 11, 17, 20 };
+char *relation[] =
+  { "your", "your", "your", "your", "father's", "your", "mother's", "your",
+"grandma's"
+};
+char relationLoc[] = { 6, 0, 1, 2, 3, 5, 7, 9 };
+char *in_something[] =
+  { "entrails", "anal", "cavity", "shoes", "house", "pantry", "general",
+"direction", "pants", "bed"
+};
+char in_somethingLoc[] = { 8, 0, 1, 3, 4, 5, 6, 8, 9, 10 };
+char *bad_place[] =
+  { "rat", "hole", "sewer", "toxic", "dump", "oil", "refinery", "landfill",
+"porto-pottie"
+};
+char bad_placeLoc[] = { 6, 0, 2, 3, 5, 7, 8, 9 };
+char **daGrammar[27];
+char *daGLoc[27];
+
+static void
+init_grammar (void)
+{
+  daGrammar[0] = start;
+  daGLoc[0] = startLoc;
+  daGrammar[1] = adj;
+  daGLoc[1] = adjLoc;
+  daGrammar[2] = adj3;
+  daGLoc[2] = adj3Loc;
+  daGrammar[3] = adj1;
+  daGLoc[3] = adj1Loc;
+  daGrammar[4] = adj2;
+  daGLoc[4] = adj2Loc;
+  daGrammar[5] = name;
+  daGLoc[5] = nameLoc;
+  daGrammar[6] = stuff;
+  daGLoc[6] = stuffLoc;
+  daGrammar[7] = noun_and_prep;
+  daGLoc[7] = noun_and_prepLoc;
+  daGrammar[8] = organics;
+  daGLoc[8] = organicsLoc;
+  daGrammar[9] = body_parts;
+  daGLoc[9] = body_partsLoc;
+  daGrammar[10] = noun;
+  daGLoc[10] = nounLoc;
+  daGrammar[11] = animal;
+  daGLoc[11] = animalLoc;
+  daGrammar[12] = good_verb;
+  daGLoc[12] = good_verbLoc;
+  daGrammar[13] = curse;
+  daGLoc[13] = curseLoc;
+  daGrammar[14] = afflictors;
+  daGLoc[14] = afflictorsLoc;
+  daGrammar[15] = quantity;
+  daGLoc[15] = quantityLoc;
+  daGrammar[16] = numbers;
+  daGLoc[16] = numbersLoc;
+  daGrammar[17] = adv;
+  daGLoc[17] = advLoc;
+  daGrammar[18] = metaphor;
+  daGLoc[18] = metaphorLoc;
+  daGrammar[19] = force;
+  daGLoc[19] = forceLoc;
+  daGrammar[20] = bad_action;
+  daGLoc[20] = bad_actionLoc;
+  daGrammar[21] = beasties;
+  daGLoc[21] = beastiesLoc;
+  daGrammar[22] = condition;
+  daGLoc[22] = conditionLoc;
+  daGrammar[23] = place;
+  daGLoc[23] = placeLoc;
+  daGrammar[24] = relation;
+  daGLoc[24] = relationLoc;
+  daGrammar[25] = in_something;
+  daGLoc[25] = in_somethingLoc;
+  daGrammar[26] = bad_place;
+  daGLoc[26] = bad_placeLoc;
+}
+\f
+#include <ctype.h>
+#include <debug.h>
+#include <random.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syscall.h>
+
+void expand (int num, char **grammar[], char *location[], int handle);
+
+static void
+usage (int ret_code, const char *message, ...) PRINTF_FORMAT (2, 3);
+
+static void
+usage (int ret_code, const char *message, ...)
+{
+  va_list args;
+
+  if (message != NULL) 
+    {
+      va_start (args, message);
+      vprintf (message, args);
+      va_end (args);
+    }
+  
+  printf ("\n"
+          "Usage: insult [OPTION]...\n"
+          "Prints random insults to screen.\n\n"
+          "  -h:               this help message\n"
+          "  -s <integer>:     set the random seed (default 4951)\n"
+          "  -n <integer>:     choose number of insults (default 4)\n"
+          "  -f <filename>:    redirect output to a File.\n");
+
+  exit (ret_code);
+}
+
+int
+main (int argc, char *argv[])
+{
+  int sentence_cnt, new_seed, i, file_flag, sent_flag, seed_flag;
+  int handle;
+  
+  new_seed = 4951;
+  sentence_cnt = 4;
+  file_flag = 0;
+  seed_flag = 0;
+  sent_flag = 0;
+  handle = STDOUT_FILENO;
+
+  for (i = 1; i < argc; i++)
+    {
+      if (strcmp (argv[1], "-h") == 0)
+        usage (0, NULL);
+      else if (strcmp (argv[i], "-s") == 0)
+       {
+         if (seed_flag++)
+           usage (-1, "Can't have more than one seed");
+         if (++i >= argc)
+           usage (-1, "Missing value for -s");
+         new_seed = atoi (argv[i]);
+       }
+      else if (strcmp (argv[i], "-n") == 0)
+       {
+         if (sent_flag++)
+           usage (-1, "Can't have more than one sentence option");
+         if (++i >= argc)
+           usage (-1, "Missing value for -n");
+         sentence_cnt = atoi (argv[i]);
+         if (sentence_cnt < 1)
+           usage (-1, "Must have at least one sentence");
+       }
+      else if (strcmp (argv[i], "-f") == 0)
+       {
+         if (file_flag++)
+           usage (-1, "Can't have more than one output file");
+         if (++i >= argc)
+           usage (-1, "Missing value for -f");
+         create (argv[i]);
+         handle = open (argv[i]);
+          if (handle < 0)
+            {
+              printf ("%s: open failed\n", argv[i]);
+              return -1;
+            }
+       }
+      else
+        usage (-1, "Unrecognized flag");
+    }
+
+  init_grammar ();
+
+  random_init (new_seed);
+  hprintf (handle, "\n");
+
+  for (i = 0; i < sentence_cnt; i++)
+    {
+      hprintf (handle, "\n");
+      expand (0, daGrammar, daGLoc, handle);
+      hprintf (handle, "\n\n");
+    }
+  
+  if (file_flag)
+    close (handle);
+
+  return 0;
+}
+
+void
+expand (int num, char **grammar[], char *location[], int handle)
+{
+  char *word;
+  int i, which, listStart, listEnd;
+
+  which = random_ulong () % location[num][0] + 1;
+  listStart = location[num][which];
+  listEnd = location[num][which + 1];
+  for (i = listStart; i < listEnd; i++)
+    {
+      word = grammar[num][i];
+      if (!isdigit (*word))
+       {
+         if (!ispunct (*word))
+            hprintf (handle, " ");
+          hprintf (handle, "%s", word);
+       }
+      else
+       expand (atoi (word), grammar, location, handle);
+    }
+
+}
diff --git a/src/tests/userprog/lineup.c b/src/tests/userprog/lineup.c
new file mode 100644 (file)
index 0000000..44636e7
--- /dev/null
@@ -0,0 +1,46 @@
+/* lineup.c
+
+   Converts a file to uppercase in-place.
+
+   Incidentally, another way to do this while avoiding the seeks
+   would be to open the input file, then remove() it and reopen
+   it under another handle.  Because of Unix deletion semantics
+   this works fine. */
+
+#include <ctype.h>
+#include <stdio.h>
+#include <syscall.h>
+
+int
+main (int argc, char *argv[])
+{
+  char buf[1024];
+  int handle;
+
+  if (argc != 2)
+    exit (1);
+
+  handle = open (argv[1]);
+  if (handle < 0)
+    exit (2);
+
+  for (;;) 
+    {
+      int n, i;
+
+      n = read (handle, buf, sizeof buf);
+      if (n <= 0)
+        break;
+
+      for (i = 0; i < n; i++)
+        buf[i] = toupper ((unsigned char) buf[i]);
+
+      seek (handle, tell (handle) - n);
+      if (write (handle, buf, n) != n)
+        printf ("write failed\n");
+    }
+
+  close (handle);
+
+  return 0;
+}
diff --git a/src/tests/userprog/matmult.c b/src/tests/userprog/matmult.c
new file mode 100644 (file)
index 0000000..e88b4c9
--- /dev/null
@@ -0,0 +1,55 @@
+/* matmult.c 
+
+   Test program to do matrix multiplication on large arrays.
+   Intended to stress virtual memory system.
+   
+   Ideally, we could read the matrices off of the file system,
+   and store the result back to the file system!
+ */
+
+#include <syscall.h>
+
+/* You should define this to be large enough that the arrays
+   don't fit in physical memory.
+
+   Dim    Memory
+   ---  --------
+    20     93 kB
+    30    316 kB
+    40    750 kB
+    50  1,464 kB
+    60  2,531 kB
+    70  4,019 kB
+    80  6,000 kB
+    90  8,542 kB
+   100 11,718 kB */
+#define Dim 20
+
+int A[Dim][Dim];
+int B[Dim][Dim];
+int C[Dim][Dim];
+
+int
+main (void)
+{
+  int i, j, k;
+
+  /* Initialize the matrices. */
+  for (i = 0; i < Dim; i++)
+    for (j = 0; j < Dim; j++)
+      {
+       A[i][j] = i;
+       B[i][j] = j;
+       C[i][j] = 0;
+      }
+
+  /* Multiply matrices. */
+  for (i = 0; i < Dim; i++)    
+    for (j = 0; j < Dim; j++)
+      for (k = 0; k < Dim; k++)
+       C[i][j] += A[i][k] * B[k][j];
+
+  /* Done. */
+  exit (C[Dim - 1][Dim - 1]);
+}
diff --git a/src/tests/userprog/recursor.c b/src/tests/userprog/recursor.c
new file mode 100644 (file)
index 0000000..b7422f1
--- /dev/null
@@ -0,0 +1,31 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <syscall.h>
+
+int
+main (int argc, char *argv[])
+{
+  char buffer[128];
+  pid_t pid;
+  int retval = 0;
+
+  if (argc != 4) 
+    {
+      printf ("usage: recursor <string> <depth> <joinp>\n");
+      exit (1);
+    }
+
+  /* Print args. */
+  printf ("%s %s %s %s\n", argv[0], argv[1], argv[2], argv[3]);
+
+  /* Execute child and wait for it to finish if requested. */
+  snprintf (buffer, sizeof buffer,
+            "recursor fork %d %s", atoi (argv[2]) + 1, argv[3]);
+  pid = exec (buffer);
+  if (atoi (argv[3]))
+    retval = join (pid);
+
+  /* Done. */
+  printf ("%s: dying, retval=%d\n", argv[1], retval);
+  exit (retval);
+}
diff --git a/src/tests/userprog/shell.c b/src/tests/userprog/shell.c
new file mode 100644 (file)
index 0000000..905e18b
--- /dev/null
@@ -0,0 +1,28 @@
+#include <stdio.h>
+#include <syscall.h>
+
+int
+main (void)
+{
+  for (;;) 
+    {
+      char command[80], *cp;
+
+      /* Prompt. */
+      printf ("--");
+
+      /* Read and echo command. */
+      for (cp = command; cp < command + sizeof command - 1; cp++)
+        {
+          read (STDIN_FILENO, cp, 1);
+          putchar (*cp);
+          if (*cp == '\n')
+            break;
+        }
+      *cp = '\0';
+      
+      /* Execute command. */
+      if (cp > command) 
+        join (exec (command));
+    }
+}
diff --git a/src/threads/Make.vars b/src/threads/Make.vars
new file mode 100644 (file)
index 0000000..55ef2b2
--- /dev/null
@@ -0,0 +1,2 @@
+DEFINES = 
+SUBDIRS = threads devices lib lib/kernel
index bc2307b342f5b8fbdfdaf0c8cac9fd9a16d6f749..34c10aa4f508714da040e81389fa51e56ba2d97a 100644 (file)
@@ -1,2 +1 @@
-include Makefile.vars
 include ../Makefile.kernel
diff --git a/src/threads/Makefile.vars b/src/threads/Makefile.vars
deleted file mode 100644 (file)
index 55ef2b2..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-DEFINES = 
-SUBDIRS = threads devices lib lib/kernel
diff --git a/src/userprog/Make.vars b/src/userprog/Make.vars
new file mode 100644 (file)
index 0000000..03e8f08
--- /dev/null
@@ -0,0 +1,2 @@
+DEFINES = -DUSERPROG -DFILESYS
+SUBDIRS = threads devices lib lib/kernel userprog filesys
index bc2307b342f5b8fbdfdaf0c8cac9fd9a16d6f749..34c10aa4f508714da040e81389fa51e56ba2d97a 100644 (file)
@@ -1,2 +1 @@
-include Makefile.vars
 include ../Makefile.kernel
diff --git a/src/userprog/Makefile.vars b/src/userprog/Makefile.vars
deleted file mode 100644 (file)
index 03e8f08..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-DEFINES = -DUSERPROG -DFILESYS
-SUBDIRS = threads devices lib lib/kernel userprog filesys