From 04c55108f55f8a6f4a31a5085151bb729635ff8e Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Mon, 20 Sep 2004 03:01:41 +0000 Subject: [PATCH] Revise makefile structure. Add user tests. --- src/Make.config | 33 ++ src/Makefile | 9 +- src/Makefile.build | 33 +- src/Makefile.kernel | 2 +- src/TODO | 4 + src/filesys/{Makefile.vars => Make.vars} | 0 src/filesys/Makefile | 1 - src/lib/stdio.h | 12 +- src/lib/syscall-nr.h | 18 +- src/lib/user/console.c | 91 ++++-- src/lib/user/syscall.c | 12 + src/lib/user/syscall.h | 2 + src/lib/user/user.c | 1 - src/lib/user/user.h | 14 - src/tests/Makefile | 8 + src/tests/userprog/Makefile | 63 ++++ src/tests/userprog/bubsort.c | 38 +++ src/tests/userprog/echo.c | 13 + src/tests/userprog/elf.x | 24 ++ src/tests/userprog/halt.c | 14 + src/tests/userprog/insult.c | 364 ++++++++++++++++++++++ src/tests/userprog/lineup.c | 46 +++ src/tests/userprog/matmult.c | 55 ++++ src/tests/userprog/recursor.c | 31 ++ src/tests/userprog/shell.c | 28 ++ src/threads/{Makefile.vars => Make.vars} | 0 src/threads/Makefile | 1 - src/userprog/{Makefile.vars => Make.vars} | 0 src/userprog/Makefile | 1 - 29 files changed, 821 insertions(+), 97 deletions(-) create mode 100644 src/Make.config rename src/filesys/{Makefile.vars => Make.vars} (100%) delete mode 100644 src/lib/user/user.c delete mode 100644 src/lib/user/user.h create mode 100644 src/tests/Makefile create mode 100644 src/tests/userprog/Makefile create mode 100644 src/tests/userprog/bubsort.c create mode 100644 src/tests/userprog/echo.c create mode 100644 src/tests/userprog/elf.x create mode 100644 src/tests/userprog/halt.c create mode 100644 src/tests/userprog/insult.c create mode 100644 src/tests/userprog/lineup.c create mode 100644 src/tests/userprog/matmult.c create mode 100644 src/tests/userprog/recursor.c create mode 100644 src/tests/userprog/shell.c rename src/threads/{Makefile.vars => Make.vars} (100%) rename src/userprog/{Makefile.vars => Make.vars} (100%) diff --git a/src/Make.config b/src/Make.config new file mode 100644 index 0000000..d4143b8 --- /dev/null +++ b/src/Make.config @@ -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) diff --git a/src/Makefile b/src/Makefile index d6d3255..90c36af 100644 --- a/src/Makefile +++ b/src/Makefile @@ -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]` diff --git a/src/Makefile.build b/src/Makefile.build index 8a73485..1c92b77 100644 --- a/src/Makefile.build +++ b/src/Makefile.build @@ -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) diff --git a/src/Makefile.kernel b/src/Makefile.kernel index c1985c4..fe63d52 100644 --- a/src/Makefile.kernel +++ b/src/Makefile.kernel @@ -1,4 +1,4 @@ -include Makefile.vars +include Make.vars BUILD_SUBDIRS = $(addprefix build/, $(SUBDIRS)) CP = cp MKDIR = mkdir diff --git a/src/TODO b/src/TODO index 96007c1..f3f6d07 100644 --- 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/Makefile.vars b/src/filesys/Make.vars similarity index 100% rename from src/filesys/Makefile.vars rename to src/filesys/Make.vars diff --git a/src/filesys/Makefile b/src/filesys/Makefile index bc2307b..34c10aa 100644 --- a/src/filesys/Makefile +++ b/src/filesys/Makefile @@ -1,2 +1 @@ -include Makefile.vars include ../Makefile.kernel diff --git a/src/lib/stdio.h b/src/lib/stdio.h index 4609fb3..b351dd1 100644 --- a/src/lib/stdio.h +++ b/src/lib/stdio.h @@ -6,15 +6,23 @@ #include #include +/* 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. */ diff --git a/src/lib/syscall-nr.h b/src/lib/syscall-nr.h index 72e06f4..5a243bd 100644 --- a/src/lib/syscall-nr.h +++ b/src/lib/syscall-nr.h @@ -12,15 +12,13 @@ #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 */ diff --git a/src/lib/user/console.c b/src/lib/user/console.c index 709a5c8..d2b9dc7 100644 --- a/src/lib/user/console.c +++ b/src/lib/user/console.c @@ -2,43 +2,26 @@ #include #include -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; } + +/* 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; +} diff --git a/src/lib/user/syscall.c b/src/lib/user/syscall.c index efabc01..506712f 100644 --- a/src/lib/user/syscall.c +++ b/src/lib/user/syscall.c @@ -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) { diff --git a/src/lib/user/syscall.h b/src/lib/user/syscall.h index a594016..c07f3ea 100644 --- a/src/lib/user/syscall.h +++ b/src/lib/user/syscall.h @@ -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 index 8b13789..0000000 --- a/src/lib/user/user.c +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/lib/user/user.h b/src/lib/user/user.h deleted file mode 100644 index 6bebf6d..0000000 --- a/src/lib/user/user.h +++ /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 - -/* */ -#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 index 0000000..764eae6 --- /dev/null +++ b/src/tests/Makefile @@ -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 index 0000000..9af275f --- /dev/null +++ b/src/tests/userprog/Makefile @@ -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 index 0000000..343219e --- /dev/null +++ b/src/tests/userprog/bubsort.c @@ -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 + +/* 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 index 0000000..c0ecd00 --- /dev/null +++ b/src/tests/userprog/echo.c @@ -0,0 +1,13 @@ +#include + +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 index 0000000..2fb94e1 --- /dev/null +++ b/src/tests/userprog/elf.x @@ -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 index 0000000..bad7250 --- /dev/null +++ b/src/tests/userprog/halt.c @@ -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 + +int +main (void) +{ + halt (); + /* not reached */ +} diff --git a/src/tests/userprog/insult.c b/src/tests/userprog/insult.c new file mode 100644 index 0000000..2f7933d --- /dev/null +++ b/src/tests/userprog/insult.c @@ -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; +} + +#include +#include +#include +#include +#include +#include +#include + +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 : set the random seed (default 4951)\n" + " -n : choose number of insults (default 4)\n" + " -f : 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 index 0000000..44636e7 --- /dev/null +++ b/src/tests/userprog/lineup.c @@ -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 +#include +#include + +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 index 0000000..e88b4c9 --- /dev/null +++ b/src/tests/userprog/matmult.c @@ -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 + +/* 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 index 0000000..b7422f1 --- /dev/null +++ b/src/tests/userprog/recursor.c @@ -0,0 +1,31 @@ +#include +#include +#include + +int +main (int argc, char *argv[]) +{ + char buffer[128]; + pid_t pid; + int retval = 0; + + if (argc != 4) + { + printf ("usage: recursor \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 index 0000000..905e18b --- /dev/null +++ b/src/tests/userprog/shell.c @@ -0,0 +1,28 @@ +#include +#include + +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/Makefile.vars b/src/threads/Make.vars similarity index 100% rename from src/threads/Makefile.vars rename to src/threads/Make.vars diff --git a/src/threads/Makefile b/src/threads/Makefile index bc2307b..34c10aa 100644 --- a/src/threads/Makefile +++ b/src/threads/Makefile @@ -1,2 +1 @@ -include Makefile.vars include ../Makefile.kernel diff --git a/src/userprog/Makefile.vars b/src/userprog/Make.vars similarity index 100% rename from src/userprog/Makefile.vars rename to src/userprog/Make.vars diff --git a/src/userprog/Makefile b/src/userprog/Makefile index bc2307b..34c10aa 100644 --- a/src/userprog/Makefile +++ b/src/userprog/Makefile @@ -1,2 +1 @@ -include Makefile.vars include ../Makefile.kernel -- 2.30.2