diff options
Diffstat (limited to 'pintos-progos/tests/vm')
88 files changed, 2218 insertions, 0 deletions
diff --git a/pintos-progos/tests/vm/Grading b/pintos-progos/tests/vm/Grading new file mode 100644 index 0000000..f0c2c13 --- /dev/null +++ b/pintos-progos/tests/vm/Grading | |||
| @@ -0,0 +1,12 @@ | |||
| 1 | # Percentage of the testing point total designated for each set of | ||
| 2 | # tests. | ||
| 3 | |||
| 4 | # This project is primarily about virtual memory, but all the previous | ||
| 5 | # functionality should work too, and it's easy to screw it up, thus | ||
| 6 | # the equal weight placed on each. | ||
| 7 | |||
| 8 | 50% tests/vm/Rubric.functionality | ||
| 9 | 15% tests/vm/Rubric.robustness | ||
| 10 | 10% tests/userprog/Rubric.functionality | ||
| 11 | 5% tests/userprog/Rubric.robustness | ||
| 12 | 20% tests/filesys/base/Rubric | ||
diff --git a/pintos-progos/tests/vm/Make.tests b/pintos-progos/tests/vm/Make.tests new file mode 100644 index 0000000..0307ccc --- /dev/null +++ b/pintos-progos/tests/vm/Make.tests | |||
| @@ -0,0 +1,107 @@ | |||
| 1 | # -*- makefile -*- | ||
| 2 | |||
| 3 | tests/vm_TESTS = $(addprefix tests/vm/,pt-grow-stack pt-grow-pusha \ | ||
| 4 | pt-grow-bad pt-big-stk-obj pt-bad-addr pt-bad-read pt-write-code \ | ||
| 5 | pt-write-code2 pt-grow-stk-sc mmap-read \ | ||
| 6 | mmap-close mmap-unmap mmap-overlap mmap-twice mmap-write mmap-exit \ | ||
| 7 | mmap-shuffle mmap-bad-fd mmap-clean mmap-inherit mmap-misalign \ | ||
| 8 | mmap-null mmap-over-code mmap-over-data mmap-over-stk mmap-remove \ | ||
| 9 | mmap-zero mmap-lazy-seq) | ||
| 10 | |||
| 11 | # Deactivated | ||
| 12 | PAGE_TESTS=page-linear page-parallel page-merge-seq \ | ||
| 13 | page-merge-par page-merge-stk page-merge-mm page-shuffle | ||
| 14 | |||
| 15 | tests/vm_PROGS = $(tests/vm_TESTS) $(addprefix tests/vm/,child-linear \ | ||
| 16 | child-sort child-qsort child-qsort-mm child-mm-wrt child-inherit) | ||
| 17 | |||
| 18 | tests/vm/pt-grow-stack_SRC = tests/vm/pt-grow-stack.c tests/arc4.c \ | ||
| 19 | tests/cksum.c tests/lib.c tests/main.c | ||
| 20 | tests/vm/pt-grow-pusha_SRC = tests/vm/pt-grow-pusha.c tests/lib.c \ | ||
| 21 | tests/main.c | ||
| 22 | tests/vm/pt-grow-bad_SRC = tests/vm/pt-grow-bad.c tests/lib.c tests/main.c | ||
| 23 | tests/vm/pt-big-stk-obj_SRC = tests/vm/pt-big-stk-obj.c tests/arc4.c \ | ||
| 24 | tests/cksum.c tests/lib.c tests/main.c | ||
| 25 | tests/vm/pt-bad-addr_SRC = tests/vm/pt-bad-addr.c tests/lib.c tests/main.c | ||
| 26 | tests/vm/pt-bad-read_SRC = tests/vm/pt-bad-read.c tests/lib.c tests/main.c | ||
| 27 | tests/vm/pt-write-code_SRC = tests/vm/pt-write-code.c tests/lib.c tests/main.c | ||
| 28 | tests/vm/pt-write-code2_SRC = tests/vm/pt-write-code-2.c tests/lib.c tests/main.c | ||
| 29 | tests/vm/pt-grow-stk-sc_SRC = tests/vm/pt-grow-stk-sc.c tests/lib.c tests/main.c | ||
| 30 | tests/vm/page-linear_SRC = tests/vm/page-linear.c tests/arc4.c \ | ||
| 31 | tests/lib.c tests/main.c | ||
| 32 | tests/vm/page-parallel_SRC = tests/vm/page-parallel.c tests/lib.c tests/main.c | ||
| 33 | tests/vm/page-merge-seq_SRC = tests/vm/page-merge-seq.c tests/arc4.c \ | ||
| 34 | tests/lib.c tests/main.c | ||
| 35 | tests/vm/page-merge-par_SRC = tests/vm/page-merge-par.c \ | ||
| 36 | tests/vm/parallel-merge.c tests/arc4.c tests/lib.c tests/main.c | ||
| 37 | tests/vm/page-merge-stk_SRC = tests/vm/page-merge-stk.c \ | ||
| 38 | tests/vm/parallel-merge.c tests/arc4.c tests/lib.c tests/main.c | ||
| 39 | tests/vm/page-merge-mm_SRC = tests/vm/page-merge-mm.c \ | ||
| 40 | tests/vm/parallel-merge.c tests/arc4.c tests/lib.c tests/main.c | ||
| 41 | tests/vm/page-shuffle_SRC = tests/vm/page-shuffle.c tests/arc4.c \ | ||
| 42 | tests/cksum.c tests/lib.c tests/main.c | ||
| 43 | tests/vm/mmap-read_SRC = tests/vm/mmap-read.c tests/lib.c tests/main.c | ||
| 44 | tests/vm/mmap-close_SRC = tests/vm/mmap-close.c tests/lib.c tests/main.c | ||
| 45 | tests/vm/mmap-unmap_SRC = tests/vm/mmap-unmap.c tests/lib.c tests/main.c | ||
| 46 | tests/vm/mmap-overlap_SRC = tests/vm/mmap-overlap.c tests/lib.c tests/main.c | ||
| 47 | tests/vm/mmap-twice_SRC = tests/vm/mmap-twice.c tests/lib.c tests/main.c | ||
| 48 | tests/vm/mmap-write_SRC = tests/vm/mmap-write.c tests/lib.c tests/main.c | ||
| 49 | tests/vm/mmap-lazy-seq_SRC = tests/vm/mmap-lazy-seq.c tests/lib.c tests/main.c | ||
| 50 | tests/vm/mmap-exit_SRC = tests/vm/mmap-exit.c tests/lib.c tests/main.c | ||
| 51 | tests/vm/mmap-shuffle_SRC = tests/vm/mmap-shuffle.c tests/arc4.c \ | ||
| 52 | tests/cksum.c tests/lib.c tests/main.c | ||
| 53 | tests/vm/mmap-bad-fd_SRC = tests/vm/mmap-bad-fd.c tests/lib.c tests/main.c | ||
| 54 | tests/vm/mmap-clean_SRC = tests/vm/mmap-clean.c tests/lib.c tests/main.c | ||
| 55 | tests/vm/mmap-inherit_SRC = tests/vm/mmap-inherit.c tests/lib.c tests/main.c | ||
| 56 | tests/vm/mmap-misalign_SRC = tests/vm/mmap-misalign.c tests/lib.c \ | ||
| 57 | tests/main.c | ||
| 58 | tests/vm/mmap-null_SRC = tests/vm/mmap-null.c tests/lib.c tests/main.c | ||
| 59 | tests/vm/mmap-over-code_SRC = tests/vm/mmap-over-code.c tests/lib.c \ | ||
| 60 | tests/main.c | ||
| 61 | tests/vm/mmap-over-data_SRC = tests/vm/mmap-over-data.c tests/lib.c \ | ||
| 62 | tests/main.c | ||
| 63 | tests/vm/mmap-over-stk_SRC = tests/vm/mmap-over-stk.c tests/lib.c tests/main.c | ||
| 64 | tests/vm/mmap-remove_SRC = tests/vm/mmap-remove.c tests/lib.c tests/main.c | ||
| 65 | tests/vm/mmap-zero_SRC = tests/vm/mmap-zero.c tests/lib.c tests/main.c | ||
| 66 | |||
| 67 | tests/vm/child-linear_SRC = tests/vm/child-linear.c tests/arc4.c tests/lib.c | ||
| 68 | tests/vm/child-qsort_SRC = tests/vm/child-qsort.c tests/vm/qsort.c tests/lib.c | ||
| 69 | tests/vm/child-qsort-mm_SRC = tests/vm/child-qsort-mm.c tests/vm/qsort.c \ | ||
| 70 | tests/lib.c | ||
| 71 | tests/vm/child-sort_SRC = tests/vm/child-sort.c tests/lib.c | ||
| 72 | tests/vm/child-mm-wrt_SRC = tests/vm/child-mm-wrt.c tests/lib.c tests/main.c | ||
| 73 | tests/vm/child-inherit_SRC = tests/vm/child-inherit.c tests/lib.c tests/main.c | ||
| 74 | |||
| 75 | tests/vm/pt-bad-read_PUTFILES = tests/vm/sample.txt | ||
| 76 | tests/vm/pt-write-code2_PUTFILES = tests/vm/sample.txt | ||
| 77 | tests/vm/mmap-close_PUTFILES = tests/vm/sample.txt | ||
| 78 | tests/vm/mmap-read_PUTFILES = tests/vm/sample.txt | ||
| 79 | tests/vm/mmap-unmap_PUTFILES = tests/vm/sample.txt | ||
| 80 | tests/vm/mmap-twice_PUTFILES = tests/vm/sample.txt | ||
| 81 | tests/vm/mmap-overlap_PUTFILES = tests/vm/zeros | ||
| 82 | tests/vm/mmap-exit_PUTFILES = tests/vm/child-mm-wrt | ||
| 83 | tests/vm/page-parallel_PUTFILES = tests/vm/child-linear | ||
| 84 | tests/vm/page-merge-seq_PUTFILES = tests/vm/child-sort | ||
| 85 | tests/vm/page-merge-par_PUTFILES = tests/vm/child-sort | ||
| 86 | tests/vm/page-merge-stk_PUTFILES = tests/vm/child-qsort | ||
| 87 | tests/vm/page-merge-mm_PUTFILES = tests/vm/child-qsort-mm | ||
| 88 | tests/vm/mmap-clean_PUTFILES = tests/vm/sample.txt | ||
| 89 | tests/vm/mmap-inherit_PUTFILES = tests/vm/sample.txt tests/vm/child-inherit | ||
| 90 | tests/vm/mmap-misalign_PUTFILES = tests/vm/sample.txt | ||
| 91 | tests/vm/mmap-null_PUTFILES = tests/vm/sample.txt | ||
| 92 | tests/vm/mmap-over-code_PUTFILES = tests/vm/sample.txt | ||
| 93 | tests/vm/mmap-over-data_PUTFILES = tests/vm/sample.txt | ||
| 94 | tests/vm/mmap-over-stk_PUTFILES = tests/vm/sample.txt | ||
| 95 | tests/vm/mmap-remove_PUTFILES = tests/vm/sample.txt | ||
| 96 | |||
| 97 | tests/vm/page-linear.output: TIMEOUT = 300 | ||
| 98 | tests/vm/page-shuffle.output: TIMEOUT = 600 | ||
| 99 | tests/vm/mmap-shuffle.output: TIMEOUT = 600 | ||
| 100 | tests/vm/page-merge-seq.output: TIMEOUT = 600 | ||
| 101 | tests/vm/page-merge-par.output: TIMEOUT = 600 | ||
| 102 | |||
| 103 | tests/vm/zeros: | ||
| 104 | dd if=/dev/zero of=$@ bs=1024 count=6 | ||
| 105 | |||
| 106 | clean:: | ||
| 107 | rm -f tests/vm/zeros | ||
diff --git a/pintos-progos/tests/vm/Rubric.functionality b/pintos-progos/tests/vm/Rubric.functionality new file mode 100644 index 0000000..ede0221 --- /dev/null +++ b/pintos-progos/tests/vm/Rubric.functionality | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | Functionality of virtual memory subsystem: | ||
| 2 | - Test stack growth. | ||
| 3 | 3 pt-grow-stack | ||
| 4 | 3 pt-grow-stk-sc | ||
| 5 | 3 pt-big-stk-obj | ||
| 6 | 3 pt-grow-pusha | ||
| 7 | |||
| 8 | - Test "mmap" system call. | ||
| 9 | 2 mmap-read | ||
| 10 | 2 mmap-write | ||
| 11 | 2 mmap-shuffle | ||
| 12 | |||
| 13 | 2 mmap-twice | ||
| 14 | |||
| 15 | 2 mmap-unmap | ||
| 16 | 1 mmap-exit | ||
| 17 | |||
| 18 | 3 mmap-clean | ||
| 19 | |||
| 20 | 2 mmap-close | ||
| 21 | 2 mmap-remove | ||
diff --git a/pintos-progos/tests/vm/Rubric.paging b/pintos-progos/tests/vm/Rubric.paging new file mode 100644 index 0000000..cf1d871 --- /dev/null +++ b/pintos-progos/tests/vm/Rubric.paging | |||
| @@ -0,0 +1,8 @@ | |||
| 1 | - Test paging behavior. | ||
| 2 | 3 page-linear | ||
| 3 | 3 page-parallel | ||
| 4 | 3 page-shuffle | ||
| 5 | 4 page-merge-seq | ||
| 6 | 4 page-merge-par | ||
| 7 | 4 page-merge-mm | ||
| 8 | 4 page-merge-stk | ||
diff --git a/pintos-progos/tests/vm/Rubric.robustness b/pintos-progos/tests/vm/Rubric.robustness new file mode 100644 index 0000000..eca0af4 --- /dev/null +++ b/pintos-progos/tests/vm/Rubric.robustness | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | Robustness of virtual memory subsystem: | ||
| 2 | - Test robustness of page table support. | ||
| 3 | 2 pt-bad-addr | ||
| 4 | 3 pt-bad-read | ||
| 5 | 2 pt-write-code | ||
| 6 | 3 pt-write-code2 | ||
| 7 | 4 pt-grow-bad | ||
| 8 | |||
| 9 | - Test robustness of "mmap" system call. | ||
| 10 | 1 mmap-bad-fd | ||
| 11 | 1 mmap-inherit | ||
| 12 | 1 mmap-null | ||
| 13 | 1 mmap-zero | ||
| 14 | |||
| 15 | 2 mmap-misalign | ||
| 16 | |||
| 17 | 2 mmap-over-code | ||
| 18 | 2 mmap-over-data | ||
| 19 | 2 mmap-over-stk | ||
| 20 | 2 mmap-overlap | ||
| 21 | 4 mmap-lazy-seq | ||
diff --git a/pintos-progos/tests/vm/child-inherit.c b/pintos-progos/tests/vm/child-inherit.c new file mode 100644 index 0000000..d3186a1 --- /dev/null +++ b/pintos-progos/tests/vm/child-inherit.c | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | /* Child process for mmap-inherit test. | ||
| 2 | Tries to write to a mapping present in the parent. | ||
| 3 | The process must be terminated with -1 exit code. */ | ||
| 4 | |||
| 5 | #include <string.h> | ||
| 6 | #include "tests/vm/sample.inc" | ||
| 7 | #include "tests/lib.h" | ||
| 8 | #include "tests/main.h" | ||
| 9 | |||
| 10 | void | ||
| 11 | test_main (void) | ||
| 12 | { | ||
| 13 | memset ((char *) 0x54321000, 0, 4096); | ||
| 14 | fail ("child can modify parent's memory mappings"); | ||
| 15 | } | ||
| 16 | |||
diff --git a/pintos-progos/tests/vm/child-linear.c b/pintos-progos/tests/vm/child-linear.c new file mode 100644 index 0000000..eca3e3f --- /dev/null +++ b/pintos-progos/tests/vm/child-linear.c | |||
| @@ -0,0 +1,36 @@ | |||
| 1 | /* Child process of page-parallel. | ||
| 2 | Encrypts 1 MB of zeros, then decrypts it, and ensures that | ||
| 3 | the zeros are back. */ | ||
| 4 | |||
| 5 | #include <string.h> | ||
| 6 | #include "tests/arc4.h" | ||
| 7 | #include "tests/lib.h" | ||
| 8 | #include "tests/main.h" | ||
| 9 | |||
| 10 | const char *test_name = "child-linear"; | ||
| 11 | |||
| 12 | #define SIZE (1024 * 1024) | ||
| 13 | static char buf[SIZE]; | ||
| 14 | |||
| 15 | int | ||
| 16 | main (int argc, char *argv[]) | ||
| 17 | { | ||
| 18 | const char *key = argv[argc - 1]; | ||
| 19 | struct arc4 arc4; | ||
| 20 | size_t i; | ||
| 21 | |||
| 22 | /* Encrypt zeros. */ | ||
| 23 | arc4_init (&arc4, key, strlen (key)); | ||
| 24 | arc4_crypt (&arc4, buf, SIZE); | ||
| 25 | |||
| 26 | /* Decrypt back to zeros. */ | ||
| 27 | arc4_init (&arc4, key, strlen (key)); | ||
| 28 | arc4_crypt (&arc4, buf, SIZE); | ||
| 29 | |||
| 30 | /* Check that it's all zeros. */ | ||
| 31 | for (i = 0; i < SIZE; i++) | ||
| 32 | if (buf[i] != '\0') | ||
| 33 | fail ("byte %zu != 0", i); | ||
| 34 | |||
| 35 | return 0x42; | ||
| 36 | } | ||
diff --git a/pintos-progos/tests/vm/child-mm-wrt.c b/pintos-progos/tests/vm/child-mm-wrt.c new file mode 100644 index 0000000..8419788 --- /dev/null +++ b/pintos-progos/tests/vm/child-mm-wrt.c | |||
| @@ -0,0 +1,24 @@ | |||
| 1 | /* Child process of mmap-exit. | ||
| 2 | Mmaps a file and writes to it via the mmap'ing, then exits | ||
| 3 | without calling munmap. The data in the mapped region must be | ||
| 4 | written out at program termination. */ | ||
| 5 | |||
| 6 | #include <string.h> | ||
| 7 | #include <syscall.h> | ||
| 8 | #include "tests/vm/sample.inc" | ||
| 9 | #include "tests/lib.h" | ||
| 10 | #include "tests/main.h" | ||
| 11 | |||
| 12 | #define ACTUAL ((void *) 0x10000000) | ||
| 13 | |||
| 14 | void | ||
| 15 | test_main (void) | ||
| 16 | { | ||
| 17 | int handle; | ||
| 18 | |||
| 19 | CHECK (create ("sample.txt", sizeof sample), "create \"sample.txt\""); | ||
| 20 | CHECK ((handle = open ("sample.txt")) > 1, "open \"sample.txt\""); | ||
| 21 | CHECK (mmap (handle, ACTUAL) != MAP_FAILED, "mmap \"sample.txt\""); | ||
| 22 | memcpy (ACTUAL, sample, sizeof sample); | ||
| 23 | } | ||
| 24 | |||
diff --git a/pintos-progos/tests/vm/child-qsort-mm.c b/pintos-progos/tests/vm/child-qsort-mm.c new file mode 100644 index 0000000..db45499 --- /dev/null +++ b/pintos-progos/tests/vm/child-qsort-mm.c | |||
| @@ -0,0 +1,25 @@ | |||
| 1 | /* Mmaps a 128 kB file "sorts" the bytes in it, using quick sort, | ||
| 2 | a multi-pass divide and conquer algorithm. */ | ||
| 3 | |||
| 4 | #include <debug.h> | ||
| 5 | #include <syscall.h> | ||
| 6 | #include "tests/lib.h" | ||
| 7 | #include "tests/main.h" | ||
| 8 | #include "tests/vm/qsort.h" | ||
| 9 | |||
| 10 | const char *test_name = "child-qsort-mm"; | ||
| 11 | |||
| 12 | int | ||
| 13 | main (int argc UNUSED, char *argv[]) | ||
| 14 | { | ||
| 15 | int handle; | ||
| 16 | unsigned char *p = (unsigned char *) 0x10000000; | ||
| 17 | |||
| 18 | quiet = true; | ||
| 19 | |||
| 20 | CHECK ((handle = open (argv[1])) > 1, "open \"%s\"", argv[1]); | ||
| 21 | CHECK (mmap (handle, p) != MAP_FAILED, "mmap \"%s\"", argv[1]); | ||
| 22 | qsort_bytes (p, 1024 * 128); | ||
| 23 | |||
| 24 | return 80; | ||
| 25 | } | ||
diff --git a/pintos-progos/tests/vm/child-qsort.c b/pintos-progos/tests/vm/child-qsort.c new file mode 100644 index 0000000..355f4eb --- /dev/null +++ b/pintos-progos/tests/vm/child-qsort.c | |||
| @@ -0,0 +1,32 @@ | |||
| 1 | /* Reads a 128 kB file onto the stack and "sorts" the bytes in | ||
| 2 | it, using quick sort, a multi-pass divide and conquer | ||
| 3 | algorithm. The sorted data is written back to the same file | ||
| 4 | in-place. */ | ||
| 5 | |||
| 6 | #include <debug.h> | ||
| 7 | #include <syscall.h> | ||
| 8 | #include "tests/lib.h" | ||
| 9 | #include "tests/main.h" | ||
| 10 | #include "tests/vm/qsort.h" | ||
| 11 | |||
| 12 | const char *test_name = "child-qsort"; | ||
| 13 | |||
| 14 | int | ||
| 15 | main (int argc UNUSED, char *argv[]) | ||
| 16 | { | ||
| 17 | int handle; | ||
| 18 | unsigned char buf[128 * 1024]; | ||
| 19 | size_t size; | ||
| 20 | |||
| 21 | quiet = true; | ||
| 22 | |||
| 23 | CHECK ((handle = open (argv[1])) > 1, "open \"%s\"", argv[1]); | ||
| 24 | |||
| 25 | size = read (handle, buf, sizeof buf); | ||
| 26 | qsort_bytes (buf, sizeof buf); | ||
| 27 | seek (handle, 0); | ||
| 28 | write (handle, buf, size); | ||
| 29 | close (handle); | ||
| 30 | |||
| 31 | return 72; | ||
| 32 | } | ||
diff --git a/pintos-progos/tests/vm/child-sort.c b/pintos-progos/tests/vm/child-sort.c new file mode 100644 index 0000000..dff2c77 --- /dev/null +++ b/pintos-progos/tests/vm/child-sort.c | |||
| @@ -0,0 +1,42 @@ | |||
| 1 | /* Reads a 128 kB file into static data and "sorts" the bytes in | ||
| 2 | it, using counting sort, a single-pass algorithm. The sorted | ||
| 3 | data is written back to the same file in-place. */ | ||
| 4 | |||
| 5 | #include <debug.h> | ||
| 6 | #include <syscall.h> | ||
| 7 | #include "tests/lib.h" | ||
| 8 | #include "tests/main.h" | ||
| 9 | |||
| 10 | const char *test_name = "child-sort"; | ||
| 11 | |||
| 12 | unsigned char buf[128 * 1024]; | ||
| 13 | size_t histogram[256]; | ||
| 14 | |||
| 15 | int | ||
| 16 | main (int argc UNUSED, char *argv[]) | ||
| 17 | { | ||
| 18 | int handle; | ||
| 19 | unsigned char *p; | ||
| 20 | size_t size; | ||
| 21 | size_t i; | ||
| 22 | |||
| 23 | quiet = true; | ||
| 24 | |||
| 25 | CHECK ((handle = open (argv[1])) > 1, "open \"%s\"", argv[1]); | ||
| 26 | |||
| 27 | size = read (handle, buf, sizeof buf); | ||
| 28 | for (i = 0; i < size; i++) | ||
| 29 | histogram[buf[i]]++; | ||
| 30 | p = buf; | ||
| 31 | for (i = 0; i < sizeof histogram / sizeof *histogram; i++) | ||
| 32 | { | ||
| 33 | size_t j = histogram[i]; | ||
| 34 | while (j-- > 0) | ||
| 35 | *p++ = i; | ||
| 36 | } | ||
| 37 | seek (handle, 0); | ||
| 38 | write (handle, buf, size); | ||
| 39 | close (handle); | ||
| 40 | |||
| 41 | return 123; | ||
| 42 | } | ||
diff --git a/pintos-progos/tests/vm/mmap-bad-fd.c b/pintos-progos/tests/vm/mmap-bad-fd.c new file mode 100644 index 0000000..76a7b50 --- /dev/null +++ b/pintos-progos/tests/vm/mmap-bad-fd.c | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | /* Tries to mmap an invalid fd, | ||
| 2 | which must either fail silently or terminate the process with | ||
| 3 | exit code -1. */ | ||
| 4 | |||
| 5 | #include <syscall.h> | ||
| 6 | #include "tests/lib.h" | ||
| 7 | #include "tests/main.h" | ||
| 8 | |||
| 9 | void | ||
| 10 | test_main (void) | ||
| 11 | { | ||
| 12 | CHECK (mmap (0x5678, (void *) 0x10000000) == MAP_FAILED, | ||
| 13 | "try to mmap invalid fd"); | ||
| 14 | } | ||
| 15 | |||
diff --git a/pintos-progos/tests/vm/mmap-bad-fd.ck b/pintos-progos/tests/vm/mmap-bad-fd.ck new file mode 100644 index 0000000..f3f58d5 --- /dev/null +++ b/pintos-progos/tests/vm/mmap-bad-fd.ck | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected ([<<'EOF', <<'EOF']); | ||
| 6 | (mmap-bad-fd) begin | ||
| 7 | (mmap-bad-fd) try to mmap invalid fd | ||
| 8 | (mmap-bad-fd) end | ||
| 9 | mmap-bad-fd: exit(0) | ||
| 10 | EOF | ||
| 11 | (mmap-bad-fd) begin | ||
| 12 | (mmap-bad-fd) try to mmap invalid fd | ||
| 13 | mmap-bad-fd: exit(-1) | ||
| 14 | EOF | ||
| 15 | pass; | ||
diff --git a/pintos-progos/tests/vm/mmap-clean.c b/pintos-progos/tests/vm/mmap-clean.c new file mode 100644 index 0000000..ea1dc9c --- /dev/null +++ b/pintos-progos/tests/vm/mmap-clean.c | |||
| @@ -0,0 +1,53 @@ | |||
| 1 | /* Verifies that mmap'd regions are only written back on munmap | ||
| 2 | if the data was actually modified in memory. */ | ||
| 3 | |||
| 4 | #include <string.h> | ||
| 5 | #include <syscall.h> | ||
| 6 | #include "tests/vm/sample.inc" | ||
| 7 | #include "tests/lib.h" | ||
| 8 | #include "tests/main.h" | ||
| 9 | |||
| 10 | void | ||
| 11 | test_main (void) | ||
| 12 | { | ||
| 13 | static const char overwrite[] = "Now is the time for all good..."; | ||
| 14 | static char buffer[sizeof sample - 1]; | ||
| 15 | char *actual = (char *) 0x54321000; | ||
| 16 | int handle; | ||
| 17 | mapid_t map; | ||
| 18 | |||
| 19 | /* Open file, map, verify data. */ | ||
| 20 | CHECK ((handle = open ("sample.txt")) > 1, "open \"sample.txt\""); | ||
| 21 | CHECK ((map = mmap (handle, actual)) != MAP_FAILED, "mmap \"sample.txt\""); | ||
| 22 | if (memcmp (actual, sample, strlen (sample))) | ||
| 23 | fail ("read of mmap'd file reported bad data"); | ||
| 24 | |||
| 25 | /* Modify file. */ | ||
| 26 | CHECK (write (handle, overwrite, strlen (overwrite)) | ||
| 27 | == (int) strlen (overwrite), | ||
| 28 | "write \"sample.txt\""); | ||
| 29 | |||
| 30 | /* Close mapping. Data should not be written back, because we | ||
| 31 | didn't modify it via the mapping. */ | ||
| 32 | msg ("munmap \"sample.txt\""); | ||
| 33 | munmap (map); | ||
| 34 | |||
| 35 | /* Read file back. */ | ||
| 36 | msg ("seek \"sample.txt\""); | ||
| 37 | seek (handle, 0); | ||
| 38 | CHECK (read (handle, buffer, sizeof buffer) == sizeof buffer, | ||
| 39 | "read \"sample.txt\""); | ||
| 40 | |||
| 41 | /* Verify that file overwrite worked. */ | ||
| 42 | if (memcmp (buffer, overwrite, strlen (overwrite)) | ||
| 43 | || memcmp (buffer + strlen (overwrite), sample + strlen (overwrite), | ||
| 44 | strlen (sample) - strlen (overwrite))) | ||
| 45 | { | ||
| 46 | if (!memcmp (buffer, sample, strlen (sample))) | ||
| 47 | fail ("munmap wrote back clean page"); | ||
| 48 | else | ||
| 49 | fail ("read surprising data from file"); | ||
| 50 | } | ||
| 51 | else | ||
| 52 | msg ("file change was retained after munmap"); | ||
| 53 | } | ||
diff --git a/pintos-progos/tests/vm/mmap-clean.ck b/pintos-progos/tests/vm/mmap-clean.ck new file mode 100644 index 0000000..1666d6c --- /dev/null +++ b/pintos-progos/tests/vm/mmap-clean.ck | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); | ||
| 6 | (mmap-clean) begin | ||
| 7 | (mmap-clean) open "sample.txt" | ||
| 8 | (mmap-clean) mmap "sample.txt" | ||
| 9 | (mmap-clean) write "sample.txt" | ||
| 10 | (mmap-clean) munmap "sample.txt" | ||
| 11 | (mmap-clean) seek "sample.txt" | ||
| 12 | (mmap-clean) read "sample.txt" | ||
| 13 | (mmap-clean) file change was retained after munmap | ||
| 14 | (mmap-clean) end | ||
| 15 | EOF | ||
| 16 | pass; | ||
diff --git a/pintos-progos/tests/vm/mmap-close.c b/pintos-progos/tests/vm/mmap-close.c new file mode 100644 index 0000000..d016ee3 --- /dev/null +++ b/pintos-progos/tests/vm/mmap-close.c | |||
| @@ -0,0 +1,27 @@ | |||
| 1 | /* Verifies that memory mappings persist after file close. */ | ||
| 2 | |||
| 3 | #include <string.h> | ||
| 4 | #include <syscall.h> | ||
| 5 | #include "tests/vm/sample.inc" | ||
| 6 | #include "tests/arc4.h" | ||
| 7 | #include "tests/lib.h" | ||
| 8 | #include "tests/main.h" | ||
| 9 | |||
| 10 | #define ACTUAL ((void *) 0x10000000) | ||
| 11 | |||
| 12 | void | ||
| 13 | test_main (void) | ||
| 14 | { | ||
| 15 | int handle; | ||
| 16 | mapid_t map; | ||
| 17 | |||
| 18 | CHECK ((handle = open ("sample.txt")) > 1, "open \"sample.txt\""); | ||
| 19 | CHECK ((map = mmap (handle, ACTUAL)) != MAP_FAILED, "mmap \"sample.txt\""); | ||
| 20 | |||
| 21 | close (handle); | ||
| 22 | |||
| 23 | if (memcmp (ACTUAL, sample, strlen (sample))) | ||
| 24 | fail ("read of mmap'd file reported bad data"); | ||
| 25 | |||
| 26 | munmap (map); | ||
| 27 | } | ||
diff --git a/pintos-progos/tests/vm/mmap-close.ck b/pintos-progos/tests/vm/mmap-close.ck new file mode 100644 index 0000000..d15e41a --- /dev/null +++ b/pintos-progos/tests/vm/mmap-close.ck | |||
| @@ -0,0 +1,11 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); | ||
| 6 | (mmap-close) begin | ||
| 7 | (mmap-close) open "sample.txt" | ||
| 8 | (mmap-close) mmap "sample.txt" | ||
| 9 | (mmap-close) end | ||
| 10 | EOF | ||
| 11 | pass; | ||
diff --git a/pintos-progos/tests/vm/mmap-exit.c b/pintos-progos/tests/vm/mmap-exit.c new file mode 100644 index 0000000..7a2278a --- /dev/null +++ b/pintos-progos/tests/vm/mmap-exit.c | |||
| @@ -0,0 +1,22 @@ | |||
| 1 | /* Executes child-mm-wrt and verifies that the writes that should | ||
| 2 | have occurred really did. */ | ||
| 3 | |||
| 4 | #include <syscall.h> | ||
| 5 | #include "tests/vm/sample.inc" | ||
| 6 | #include "tests/lib.h" | ||
| 7 | #include "tests/main.h" | ||
| 8 | |||
| 9 | void | ||
| 10 | test_main (void) | ||
| 11 | { | ||
| 12 | pid_t child; | ||
| 13 | |||
| 14 | /* Make child write file. */ | ||
| 15 | quiet = true; | ||
| 16 | CHECK ((child = exec ("child-mm-wrt")) != -1, "exec \"child-mm-wrt\""); | ||
| 17 | CHECK (wait (child) == 0, "wait for child (should return 0)"); | ||
| 18 | quiet = false; | ||
| 19 | |||
| 20 | /* Check file contents. */ | ||
| 21 | check_file ("sample.txt", sample, sizeof sample); | ||
| 22 | } | ||
diff --git a/pintos-progos/tests/vm/mmap-exit.ck b/pintos-progos/tests/vm/mmap-exit.ck new file mode 100644 index 0000000..457d34a --- /dev/null +++ b/pintos-progos/tests/vm/mmap-exit.ck | |||
| @@ -0,0 +1,17 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); | ||
| 6 | (mmap-exit) begin | ||
| 7 | (child-mm-wrt) begin | ||
| 8 | (child-mm-wrt) create "sample.txt" | ||
| 9 | (child-mm-wrt) open "sample.txt" | ||
| 10 | (child-mm-wrt) mmap "sample.txt" | ||
| 11 | (child-mm-wrt) end | ||
| 12 | (mmap-exit) open "sample.txt" for verification | ||
| 13 | (mmap-exit) verified contents of "sample.txt" | ||
| 14 | (mmap-exit) close "sample.txt" | ||
| 15 | (mmap-exit) end | ||
| 16 | EOF | ||
| 17 | pass; | ||
diff --git a/pintos-progos/tests/vm/mmap-inherit.c b/pintos-progos/tests/vm/mmap-inherit.c new file mode 100644 index 0000000..7fa9607 --- /dev/null +++ b/pintos-progos/tests/vm/mmap-inherit.c | |||
| @@ -0,0 +1,32 @@ | |||
| 1 | /* Maps a file into memory and runs child-inherit to verify that | ||
| 2 | mappings are not inherited. */ | ||
| 3 | |||
| 4 | #include <string.h> | ||
| 5 | #include <syscall.h> | ||
| 6 | #include "tests/vm/sample.inc" | ||
| 7 | #include "tests/lib.h" | ||
| 8 | #include "tests/main.h" | ||
| 9 | |||
| 10 | void | ||
| 11 | test_main (void) | ||
| 12 | { | ||
| 13 | char *actual = (char *) 0x54321000; | ||
| 14 | int handle; | ||
| 15 | pid_t child; | ||
| 16 | |||
| 17 | /* Open file, map, verify data. */ | ||
| 18 | CHECK ((handle = open ("sample.txt")) > 1, "open \"sample.txt\""); | ||
| 19 | CHECK (mmap (handle, actual) != MAP_FAILED, "mmap \"sample.txt\""); | ||
| 20 | if (memcmp (actual, sample, strlen (sample))) | ||
| 21 | fail ("read of mmap'd file reported bad data"); | ||
| 22 | |||
| 23 | /* Spawn child and wait. */ | ||
| 24 | CHECK ((child = exec ("child-inherit")) != -1, "exec \"child-inherit\""); | ||
| 25 | quiet = true; | ||
| 26 | CHECK (wait (child) == -1, "wait for child (should return -1)"); | ||
| 27 | quiet = false; | ||
| 28 | |||
| 29 | /* Verify data again. */ | ||
| 30 | CHECK (!memcmp (actual, sample, strlen (sample)), | ||
| 31 | "checking that mmap'd file still has same data"); | ||
| 32 | } | ||
diff --git a/pintos-progos/tests/vm/mmap-inherit.ck b/pintos-progos/tests/vm/mmap-inherit.ck new file mode 100644 index 0000000..c54638a --- /dev/null +++ b/pintos-progos/tests/vm/mmap-inherit.ck | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected (IGNORE_USER_FAULTS => 1, [<<'EOF']); | ||
| 6 | (mmap-inherit) begin | ||
| 7 | (mmap-inherit) open "sample.txt" | ||
| 8 | (mmap-inherit) mmap "sample.txt" | ||
| 9 | (mmap-inherit) exec "child-inherit" | ||
| 10 | (child-inherit) begin | ||
| 11 | child-inherit: exit(-1) | ||
| 12 | (mmap-inherit) checking that mmap'd file still has same data | ||
| 13 | (mmap-inherit) end | ||
| 14 | mmap-inherit: exit(0) | ||
| 15 | EOF | ||
| 16 | pass; | ||
diff --git a/pintos-progos/tests/vm/mmap-lazy-seq.c b/pintos-progos/tests/vm/mmap-lazy-seq.c new file mode 100644 index 0000000..b8f07bd --- /dev/null +++ b/pintos-progos/tests/vm/mmap-lazy-seq.c | |||
| @@ -0,0 +1,52 @@ | |||
| 1 | /* Create a large file, and mmap it several times, writing to | ||
| 2 | different pages. Then unmaps the file, and reads the data back | ||
| 3 | to verify */ | ||
| 4 | |||
| 5 | #include <string.h> | ||
| 6 | #include <syscall.h> | ||
| 7 | #include "tests/vm/sample.inc" | ||
| 8 | #include "tests/lib.h" | ||
| 9 | #include "tests/main.h" | ||
| 10 | |||
| 11 | /* Offset needs to be larger or equal to page size */ | ||
| 12 | #define OFFSET(i) (8192*(i)) | ||
| 13 | /* Number of times file is mmapped */ | ||
| 14 | #define N (8) | ||
| 15 | /* Size of file */ | ||
| 16 | #define FILE_SIZE (1024*1024) | ||
| 17 | /* Address for mmap */ | ||
| 18 | #define ACTUAL(i) ((void *) (0x10000000 + (i)*FILE_SIZE)) | ||
| 19 | |||
| 20 | |||
| 21 | void | ||
| 22 | test_main (void) | ||
| 23 | { | ||
| 24 | int i; | ||
| 25 | int handle; | ||
| 26 | mapid_t map[N]; | ||
| 27 | char buf[1024]; | ||
| 28 | /* create file */ | ||
| 29 | CHECK (create ("sample.txt", FILE_SIZE), "create \"sample.txt\""); | ||
| 30 | CHECK ((handle = open ("sample.txt")) > 1, "open \"sample.txt\""); | ||
| 31 | /* mmap */ | ||
| 32 | for (i = 0; i < N; i++) { | ||
| 33 | CHECK ((map[i] = mmap (handle, ACTUAL(i))) != MAP_FAILED, "mmap \"sample.txt\""); | ||
| 34 | } | ||
| 35 | /* write */ | ||
| 36 | for (i = 0; i < N; i++) { | ||
| 37 | memcpy (buf, ACTUAL(i)+OFFSET(i+N), 1024); /* not checked */ | ||
| 38 | memcpy (ACTUAL(i)+OFFSET(i), sample, strlen (sample)); | ||
| 39 | } | ||
| 40 | /* munmap */ | ||
| 41 | for (i = 0; i < N; i++) { | ||
| 42 | munmap (map[i]); | ||
| 43 | } | ||
| 44 | /* Read back via read(). */ | ||
| 45 | for (i = 0; i < N; i++) { | ||
| 46 | seek (handle, OFFSET(i)); | ||
| 47 | read (handle, buf, strlen (sample)); | ||
| 48 | CHECK (!memcmp (buf, sample, strlen (sample)), | ||
| 49 | "compare read data against written data"); | ||
| 50 | } | ||
| 51 | close (handle); | ||
| 52 | } | ||
diff --git a/pintos-progos/tests/vm/mmap-lazy-seq.ck b/pintos-progos/tests/vm/mmap-lazy-seq.ck new file mode 100644 index 0000000..dd0e240 --- /dev/null +++ b/pintos-progos/tests/vm/mmap-lazy-seq.ck | |||
| @@ -0,0 +1,27 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); | ||
| 6 | (mmap-lazy-seq) begin | ||
| 7 | (mmap-lazy-seq) create "sample.txt" | ||
| 8 | (mmap-lazy-seq) open "sample.txt" | ||
| 9 | (mmap-lazy-seq) mmap "sample.txt" | ||
| 10 | (mmap-lazy-seq) mmap "sample.txt" | ||
| 11 | (mmap-lazy-seq) mmap "sample.txt" | ||
| 12 | (mmap-lazy-seq) mmap "sample.txt" | ||
| 13 | (mmap-lazy-seq) mmap "sample.txt" | ||
| 14 | (mmap-lazy-seq) mmap "sample.txt" | ||
| 15 | (mmap-lazy-seq) mmap "sample.txt" | ||
| 16 | (mmap-lazy-seq) mmap "sample.txt" | ||
| 17 | (mmap-lazy-seq) compare read data against written data | ||
| 18 | (mmap-lazy-seq) compare read data against written data | ||
| 19 | (mmap-lazy-seq) compare read data against written data | ||
| 20 | (mmap-lazy-seq) compare read data against written data | ||
| 21 | (mmap-lazy-seq) compare read data against written data | ||
| 22 | (mmap-lazy-seq) compare read data against written data | ||
| 23 | (mmap-lazy-seq) compare read data against written data | ||
| 24 | (mmap-lazy-seq) compare read data against written data | ||
| 25 | (mmap-lazy-seq) end | ||
| 26 | EOF | ||
| 27 | pass; | ||
diff --git a/pintos-progos/tests/vm/mmap-misalign.c b/pintos-progos/tests/vm/mmap-misalign.c new file mode 100644 index 0000000..34141a9 --- /dev/null +++ b/pintos-progos/tests/vm/mmap-misalign.c | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | /* Verifies that misaligned memory mappings are disallowed. */ | ||
| 2 | |||
| 3 | #include <syscall.h> | ||
| 4 | #include "tests/lib.h" | ||
| 5 | #include "tests/main.h" | ||
| 6 | |||
| 7 | void | ||
| 8 | test_main (void) | ||
| 9 | { | ||
| 10 | int handle; | ||
| 11 | |||
| 12 | CHECK ((handle = open ("sample.txt")) > 1, "open \"sample.txt\""); | ||
| 13 | CHECK (mmap (handle, (void *) 0x10001234) == MAP_FAILED, | ||
| 14 | "try to mmap at misaligned address"); | ||
| 15 | } | ||
| 16 | |||
diff --git a/pintos-progos/tests/vm/mmap-misalign.ck b/pintos-progos/tests/vm/mmap-misalign.ck new file mode 100644 index 0000000..145a2e8 --- /dev/null +++ b/pintos-progos/tests/vm/mmap-misalign.ck | |||
| @@ -0,0 +1,11 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); | ||
| 6 | (mmap-misalign) begin | ||
| 7 | (mmap-misalign) open "sample.txt" | ||
| 8 | (mmap-misalign) try to mmap at misaligned address | ||
| 9 | (mmap-misalign) end | ||
| 10 | EOF | ||
| 11 | pass; | ||
diff --git a/pintos-progos/tests/vm/mmap-null.c b/pintos-progos/tests/vm/mmap-null.c new file mode 100644 index 0000000..f8ef075 --- /dev/null +++ b/pintos-progos/tests/vm/mmap-null.c | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | /* Verifies that memory mappings at address 0 are disallowed. */ | ||
| 2 | |||
| 3 | #include <syscall.h> | ||
| 4 | #include "tests/lib.h" | ||
| 5 | #include "tests/main.h" | ||
| 6 | |||
| 7 | void | ||
| 8 | test_main (void) | ||
| 9 | { | ||
| 10 | int handle; | ||
| 11 | |||
| 12 | CHECK ((handle = open ("sample.txt")) > 1, "open \"sample.txt\""); | ||
| 13 | CHECK (mmap (handle, NULL) == MAP_FAILED, "try to mmap at address 0"); | ||
| 14 | } | ||
| 15 | |||
diff --git a/pintos-progos/tests/vm/mmap-null.ck b/pintos-progos/tests/vm/mmap-null.ck new file mode 100644 index 0000000..aacdd65 --- /dev/null +++ b/pintos-progos/tests/vm/mmap-null.ck | |||
| @@ -0,0 +1,11 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); | ||
| 6 | (mmap-null) begin | ||
| 7 | (mmap-null) open "sample.txt" | ||
| 8 | (mmap-null) try to mmap at address 0 | ||
| 9 | (mmap-null) end | ||
| 10 | EOF | ||
| 11 | pass; | ||
diff --git a/pintos-progos/tests/vm/mmap-over-code.c b/pintos-progos/tests/vm/mmap-over-code.c new file mode 100644 index 0000000..d3619a3 --- /dev/null +++ b/pintos-progos/tests/vm/mmap-over-code.c | |||
| @@ -0,0 +1,19 @@ | |||
| 1 | /* Verifies that mapping over the code segment is disallowed. */ | ||
| 2 | |||
| 3 | #include <stdint.h> | ||
| 4 | #include <round.h> | ||
| 5 | #include <syscall.h> | ||
| 6 | #include "tests/lib.h" | ||
| 7 | #include "tests/main.h" | ||
| 8 | |||
| 9 | void | ||
| 10 | test_main (void) | ||
| 11 | { | ||
| 12 | uintptr_t test_main_page = ROUND_DOWN ((uintptr_t) test_main, 4096); | ||
| 13 | int handle; | ||
| 14 | |||
| 15 | CHECK ((handle = open ("sample.txt")) > 1, "open \"sample.txt\""); | ||
| 16 | CHECK (mmap (handle, (void *) test_main_page) == MAP_FAILED, | ||
| 17 | "try to mmap over code segment"); | ||
| 18 | } | ||
| 19 | |||
diff --git a/pintos-progos/tests/vm/mmap-over-code.ck b/pintos-progos/tests/vm/mmap-over-code.ck new file mode 100644 index 0000000..b5b23c7 --- /dev/null +++ b/pintos-progos/tests/vm/mmap-over-code.ck | |||
| @@ -0,0 +1,11 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); | ||
| 6 | (mmap-over-code) begin | ||
| 7 | (mmap-over-code) open "sample.txt" | ||
| 8 | (mmap-over-code) try to mmap over code segment | ||
| 9 | (mmap-over-code) end | ||
| 10 | EOF | ||
| 11 | pass; | ||
diff --git a/pintos-progos/tests/vm/mmap-over-data.c b/pintos-progos/tests/vm/mmap-over-data.c new file mode 100644 index 0000000..9ea5d49 --- /dev/null +++ b/pintos-progos/tests/vm/mmap-over-data.c | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | /* Verifies that mapping over the data segment is disallowed. */ | ||
| 2 | |||
| 3 | #include <stdint.h> | ||
| 4 | #include <round.h> | ||
| 5 | #include <syscall.h> | ||
| 6 | #include "tests/lib.h" | ||
| 7 | #include "tests/main.h" | ||
| 8 | |||
| 9 | static char x; | ||
| 10 | |||
| 11 | void | ||
| 12 | test_main (void) | ||
| 13 | { | ||
| 14 | uintptr_t x_page = ROUND_DOWN ((uintptr_t) &x, 4096); | ||
| 15 | int handle; | ||
| 16 | |||
| 17 | CHECK ((handle = open ("sample.txt")) > 1, "open \"sample.txt\""); | ||
| 18 | CHECK (mmap (handle, (void *) x_page) == MAP_FAILED, | ||
| 19 | "try to mmap over data segment"); | ||
| 20 | } | ||
| 21 | |||
diff --git a/pintos-progos/tests/vm/mmap-over-data.ck b/pintos-progos/tests/vm/mmap-over-data.ck new file mode 100644 index 0000000..98770cc --- /dev/null +++ b/pintos-progos/tests/vm/mmap-over-data.ck | |||
| @@ -0,0 +1,11 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); | ||
| 6 | (mmap-over-data) begin | ||
| 7 | (mmap-over-data) open "sample.txt" | ||
| 8 | (mmap-over-data) try to mmap over data segment | ||
| 9 | (mmap-over-data) end | ||
| 10 | EOF | ||
| 11 | pass; | ||
diff --git a/pintos-progos/tests/vm/mmap-over-stk.c b/pintos-progos/tests/vm/mmap-over-stk.c new file mode 100644 index 0000000..4e241e8 --- /dev/null +++ b/pintos-progos/tests/vm/mmap-over-stk.c | |||
| @@ -0,0 +1,19 @@ | |||
| 1 | /* Verifies that mapping over the stack segment is disallowed. */ | ||
| 2 | |||
| 3 | #include <stdint.h> | ||
| 4 | #include <round.h> | ||
| 5 | #include <syscall.h> | ||
| 6 | #include "tests/lib.h" | ||
| 7 | #include "tests/main.h" | ||
| 8 | |||
| 9 | void | ||
| 10 | test_main (void) | ||
| 11 | { | ||
| 12 | int handle; | ||
| 13 | uintptr_t handle_page = ROUND_DOWN ((uintptr_t) &handle, 4096); | ||
| 14 | |||
| 15 | CHECK ((handle = open ("sample.txt")) > 1, "open \"sample.txt\""); | ||
| 16 | CHECK (mmap (handle, (void *) handle_page) == MAP_FAILED, | ||
| 17 | "try to mmap over stack segment"); | ||
| 18 | } | ||
| 19 | |||
diff --git a/pintos-progos/tests/vm/mmap-over-stk.ck b/pintos-progos/tests/vm/mmap-over-stk.ck new file mode 100644 index 0000000..e6880cf --- /dev/null +++ b/pintos-progos/tests/vm/mmap-over-stk.ck | |||
| @@ -0,0 +1,11 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); | ||
| 6 | (mmap-over-stk) begin | ||
| 7 | (mmap-over-stk) open "sample.txt" | ||
| 8 | (mmap-over-stk) try to mmap over stack segment | ||
| 9 | (mmap-over-stk) end | ||
| 10 | EOF | ||
| 11 | pass; | ||
diff --git a/pintos-progos/tests/vm/mmap-overlap.c b/pintos-progos/tests/vm/mmap-overlap.c new file mode 100644 index 0000000..668ae5f --- /dev/null +++ b/pintos-progos/tests/vm/mmap-overlap.c | |||
| @@ -0,0 +1,20 @@ | |||
| 1 | /* Verifies that overlapping memory mappings are disallowed. */ | ||
| 2 | |||
| 3 | #include <syscall.h> | ||
| 4 | #include "tests/vm/sample.inc" | ||
| 5 | #include "tests/lib.h" | ||
| 6 | #include "tests/main.h" | ||
| 7 | |||
| 8 | void | ||
| 9 | test_main (void) | ||
| 10 | { | ||
| 11 | char *start = (char *) 0x10000000; | ||
| 12 | int fd[2]; | ||
| 13 | |||
| 14 | CHECK ((fd[0] = open ("zeros")) > 1, "open \"zeros\" once"); | ||
| 15 | CHECK (mmap (fd[0], start) != MAP_FAILED, "mmap \"zeros\""); | ||
| 16 | CHECK ((fd[1] = open ("zeros")) > 1 && fd[0] != fd[1], | ||
| 17 | "open \"zeros\" again"); | ||
| 18 | CHECK (mmap (fd[1], start + 4096) == MAP_FAILED, | ||
| 19 | "try to mmap \"zeros\" again"); | ||
| 20 | } | ||
diff --git a/pintos-progos/tests/vm/mmap-overlap.ck b/pintos-progos/tests/vm/mmap-overlap.ck new file mode 100644 index 0000000..f13801e --- /dev/null +++ b/pintos-progos/tests/vm/mmap-overlap.ck | |||
| @@ -0,0 +1,13 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); | ||
| 6 | (mmap-overlap) begin | ||
| 7 | (mmap-overlap) open "zeros" once | ||
| 8 | (mmap-overlap) mmap "zeros" | ||
| 9 | (mmap-overlap) open "zeros" again | ||
| 10 | (mmap-overlap) try to mmap "zeros" again | ||
| 11 | (mmap-overlap) end | ||
| 12 | EOF | ||
| 13 | pass; | ||
diff --git a/pintos-progos/tests/vm/mmap-read.c b/pintos-progos/tests/vm/mmap-read.c new file mode 100644 index 0000000..c0f23a1 --- /dev/null +++ b/pintos-progos/tests/vm/mmap-read.c | |||
| @@ -0,0 +1,32 @@ | |||
| 1 | /* Uses a memory mapping to read a file. */ | ||
| 2 | |||
| 3 | #include <string.h> | ||
| 4 | #include <syscall.h> | ||
| 5 | #include "tests/vm/sample.inc" | ||
| 6 | #include "tests/lib.h" | ||
| 7 | #include "tests/main.h" | ||
| 8 | |||
| 9 | void | ||
| 10 | test_main (void) | ||
| 11 | { | ||
| 12 | char *actual = (char *) 0x10000000; | ||
| 13 | int handle; | ||
| 14 | mapid_t map; | ||
| 15 | size_t i; | ||
| 16 | |||
| 17 | CHECK ((handle = open ("sample.txt")) > 1, "open \"sample.txt\""); | ||
| 18 | CHECK ((map = mmap (handle, actual)) != MAP_FAILED, "mmap \"sample.txt\""); | ||
| 19 | |||
| 20 | /* Check that data is correct. */ | ||
| 21 | if (memcmp (actual, sample, strlen (sample))) | ||
| 22 | fail ("read of mmap'd file reported bad data"); | ||
| 23 | |||
| 24 | /* Verify that data is followed by zeros. */ | ||
| 25 | for (i = strlen (sample); i < 4096; i++) | ||
| 26 | if (actual[i] != 0) | ||
| 27 | fail ("byte %zu of mmap'd region has value %02hhx (should be 0)", | ||
| 28 | i, actual[i]); | ||
| 29 | |||
| 30 | munmap (map); | ||
| 31 | close (handle); | ||
| 32 | } | ||
diff --git a/pintos-progos/tests/vm/mmap-read.ck b/pintos-progos/tests/vm/mmap-read.ck new file mode 100644 index 0000000..95ab790 --- /dev/null +++ b/pintos-progos/tests/vm/mmap-read.ck | |||
| @@ -0,0 +1,11 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); | ||
| 6 | (mmap-read) begin | ||
| 7 | (mmap-read) open "sample.txt" | ||
| 8 | (mmap-read) mmap "sample.txt" | ||
| 9 | (mmap-read) end | ||
| 10 | EOF | ||
| 11 | pass; | ||
diff --git a/pintos-progos/tests/vm/mmap-remove.c b/pintos-progos/tests/vm/mmap-remove.c new file mode 100644 index 0000000..5f7444d --- /dev/null +++ b/pintos-progos/tests/vm/mmap-remove.c | |||
| @@ -0,0 +1,43 @@ | |||
| 1 | /* Deletes and closes file that is mapped into memory | ||
| 2 | and verifies that it can still be read through the mapping. */ | ||
| 3 | |||
| 4 | #include <string.h> | ||
| 5 | #include <syscall.h> | ||
| 6 | #include "tests/vm/sample.inc" | ||
| 7 | #include "tests/lib.h" | ||
| 8 | #include "tests/main.h" | ||
| 9 | |||
| 10 | void | ||
| 11 | test_main (void) | ||
| 12 | { | ||
| 13 | char *actual = (char *) 0x10000000; | ||
| 14 | int handle; | ||
| 15 | mapid_t map; | ||
| 16 | size_t i; | ||
| 17 | |||
| 18 | /* Map file. */ | ||
| 19 | CHECK ((handle = open ("sample.txt")) > 1, "open \"sample.txt\""); | ||
| 20 | CHECK ((map = mmap (handle, actual)) != MAP_FAILED, "mmap \"sample.txt\""); | ||
| 21 | |||
| 22 | /* Close file and delete it. */ | ||
| 23 | close (handle); | ||
| 24 | CHECK (remove ("sample.txt"), "remove \"sample.txt\""); | ||
| 25 | CHECK (open ("sample.txt") == -1, "try to open \"sample.txt\""); | ||
| 26 | |||
| 27 | /* Create a new file in hopes of overwriting data from the old | ||
| 28 | one, in case the file system has incorrectly freed the | ||
| 29 | file's data. */ | ||
| 30 | CHECK (create ("another", 4096 * 10), "create \"another\""); | ||
| 31 | |||
| 32 | /* Check that mapped data is correct. */ | ||
| 33 | if (memcmp (actual, sample, strlen (sample))) | ||
| 34 | fail ("read of mmap'd file reported bad data"); | ||
| 35 | |||
| 36 | /* Verify that data is followed by zeros. */ | ||
| 37 | for (i = strlen (sample); i < 4096; i++) | ||
| 38 | if (actual[i] != 0) | ||
| 39 | fail ("byte %zu of mmap'd region has value %02hhx (should be 0)", | ||
| 40 | i, actual[i]); | ||
| 41 | |||
| 42 | munmap (map); | ||
| 43 | } | ||
diff --git a/pintos-progos/tests/vm/mmap-remove.ck b/pintos-progos/tests/vm/mmap-remove.ck new file mode 100644 index 0000000..d3cc938 --- /dev/null +++ b/pintos-progos/tests/vm/mmap-remove.ck | |||
| @@ -0,0 +1,14 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); | ||
| 6 | (mmap-remove) begin | ||
| 7 | (mmap-remove) open "sample.txt" | ||
| 8 | (mmap-remove) mmap "sample.txt" | ||
| 9 | (mmap-remove) remove "sample.txt" | ||
| 10 | (mmap-remove) try to open "sample.txt" | ||
| 11 | (mmap-remove) create "another" | ||
| 12 | (mmap-remove) end | ||
| 13 | EOF | ||
| 14 | pass; | ||
diff --git a/pintos-progos/tests/vm/mmap-shuffle.c b/pintos-progos/tests/vm/mmap-shuffle.c new file mode 100644 index 0000000..29921ad --- /dev/null +++ b/pintos-progos/tests/vm/mmap-shuffle.c | |||
| @@ -0,0 +1,38 @@ | |||
| 1 | /* Creates a 128 kB file and repeatedly shuffles data in it | ||
| 2 | through a memory mapping. */ | ||
| 3 | |||
| 4 | #include <stdio.h> | ||
| 5 | #include <string.h> | ||
| 6 | #include <syscall.h> | ||
| 7 | #include "tests/arc4.h" | ||
| 8 | #include "tests/cksum.h" | ||
| 9 | #include "tests/lib.h" | ||
| 10 | #include "tests/main.h" | ||
| 11 | |||
| 12 | #define SIZE (128 * 1024) | ||
| 13 | |||
| 14 | static char *buf = (char *) 0x10000000; | ||
| 15 | |||
| 16 | void | ||
| 17 | test_main (void) | ||
| 18 | { | ||
| 19 | size_t i; | ||
| 20 | int handle; | ||
| 21 | |||
| 22 | /* Create file, mmap. */ | ||
| 23 | CHECK (create ("buffer", SIZE), "create \"buffer\""); | ||
| 24 | CHECK ((handle = open ("buffer")) > 1, "open \"buffer\""); | ||
| 25 | CHECK (mmap (handle, buf) != MAP_FAILED, "mmap \"buffer\""); | ||
| 26 | |||
| 27 | /* Initialize. */ | ||
| 28 | for (i = 0; i < SIZE; i++) | ||
| 29 | buf[i] = i * 257; | ||
| 30 | msg ("init: cksum=%lu", cksum (buf, SIZE)); | ||
| 31 | |||
| 32 | /* Shuffle repeatedly. */ | ||
| 33 | for (i = 0; i < 10; i++) | ||
| 34 | { | ||
| 35 | shuffle (buf, SIZE, 1); | ||
| 36 | msg ("shuffle %zu: cksum=%lu", i, cksum (buf, SIZE)); | ||
| 37 | } | ||
| 38 | } | ||
diff --git a/pintos-progos/tests/vm/mmap-shuffle.ck b/pintos-progos/tests/vm/mmap-shuffle.ck new file mode 100644 index 0000000..c158301 --- /dev/null +++ b/pintos-progos/tests/vm/mmap-shuffle.ck | |||
| @@ -0,0 +1,47 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | use tests::cksum; | ||
| 6 | use tests::lib; | ||
| 7 | |||
| 8 | my ($init, @shuffle); | ||
| 9 | if (1) { | ||
| 10 | # Use precalculated values. | ||
| 11 | $init = 3115322833; | ||
| 12 | @shuffle = (1691062564, 1973575879, 1647619479, 96566261, 3885786467, | ||
| 13 | 3022003332, 3614934266, 2704001777, 735775156, 1864109763); | ||
| 14 | } else { | ||
| 15 | # Recalculate values. | ||
| 16 | my ($buf) = ""; | ||
| 17 | for my $i (0...128 * 1024 - 1) { | ||
| 18 | $buf .= chr (($i * 257) & 0xff); | ||
| 19 | } | ||
| 20 | $init = cksum ($buf); | ||
| 21 | |||
| 22 | random_init (0); | ||
| 23 | for my $i (1...10) { | ||
| 24 | $buf = shuffle ($buf, length ($buf), 1); | ||
| 25 | push (@shuffle, cksum ($buf)); | ||
| 26 | } | ||
| 27 | } | ||
| 28 | |||
| 29 | check_expected (IGNORE_EXIT_CODES => 1, [<<EOF]); | ||
| 30 | (mmap-shuffle) begin | ||
| 31 | (mmap-shuffle) create "buffer" | ||
| 32 | (mmap-shuffle) open "buffer" | ||
| 33 | (mmap-shuffle) mmap "buffer" | ||
| 34 | (mmap-shuffle) init: cksum=$init | ||
| 35 | (mmap-shuffle) shuffle 0: cksum=$shuffle[0] | ||
| 36 | (mmap-shuffle) shuffle 1: cksum=$shuffle[1] | ||
| 37 | (mmap-shuffle) shuffle 2: cksum=$shuffle[2] | ||
| 38 | (mmap-shuffle) shuffle 3: cksum=$shuffle[3] | ||
| 39 | (mmap-shuffle) shuffle 4: cksum=$shuffle[4] | ||
| 40 | (mmap-shuffle) shuffle 5: cksum=$shuffle[5] | ||
| 41 | (mmap-shuffle) shuffle 6: cksum=$shuffle[6] | ||
| 42 | (mmap-shuffle) shuffle 7: cksum=$shuffle[7] | ||
| 43 | (mmap-shuffle) shuffle 8: cksum=$shuffle[8] | ||
| 44 | (mmap-shuffle) shuffle 9: cksum=$shuffle[9] | ||
| 45 | (mmap-shuffle) end | ||
| 46 | EOF | ||
| 47 | pass; | ||
diff --git a/pintos-progos/tests/vm/mmap-twice.c b/pintos-progos/tests/vm/mmap-twice.c new file mode 100644 index 0000000..d277a37 --- /dev/null +++ b/pintos-progos/tests/vm/mmap-twice.c | |||
| @@ -0,0 +1,28 @@ | |||
| 1 | /* Maps the same file into memory twice and verifies that the | ||
| 2 | same data is readable in both. */ | ||
| 3 | |||
| 4 | #include <string.h> | ||
| 5 | #include <syscall.h> | ||
| 6 | #include "tests/vm/sample.inc" | ||
| 7 | #include "tests/lib.h" | ||
| 8 | #include "tests/main.h" | ||
| 9 | |||
| 10 | void | ||
| 11 | test_main (void) | ||
| 12 | { | ||
| 13 | char *actual[2] = {(char *) 0x10000000, (char *) 0x20000000}; | ||
| 14 | size_t i; | ||
| 15 | int handle[2]; | ||
| 16 | |||
| 17 | for (i = 0; i < 2; i++) | ||
| 18 | { | ||
| 19 | CHECK ((handle[i] = open ("sample.txt")) > 1, | ||
| 20 | "open \"sample.txt\" #%zu", i); | ||
| 21 | CHECK (mmap (handle[i], actual[i]) != MAP_FAILED, | ||
| 22 | "mmap \"sample.txt\" #%zu at %p", i, (void *) actual[i]); | ||
| 23 | } | ||
| 24 | |||
| 25 | for (i = 0; i < 2; i++) | ||
| 26 | CHECK (!memcmp (actual[i], sample, strlen (sample)), | ||
| 27 | "compare mmap'd file %zu against data", i); | ||
| 28 | } | ||
diff --git a/pintos-progos/tests/vm/mmap-twice.ck b/pintos-progos/tests/vm/mmap-twice.ck new file mode 100644 index 0000000..05e9724 --- /dev/null +++ b/pintos-progos/tests/vm/mmap-twice.ck | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); | ||
| 6 | (mmap-twice) begin | ||
| 7 | (mmap-twice) open "sample.txt" #0 | ||
| 8 | (mmap-twice) mmap "sample.txt" #0 at 0x10000000 | ||
| 9 | (mmap-twice) open "sample.txt" #1 | ||
| 10 | (mmap-twice) mmap "sample.txt" #1 at 0x20000000 | ||
| 11 | (mmap-twice) compare mmap'd file 0 against data | ||
| 12 | (mmap-twice) compare mmap'd file 1 against data | ||
| 13 | (mmap-twice) end | ||
| 14 | EOF | ||
| 15 | pass; | ||
diff --git a/pintos-progos/tests/vm/mmap-unmap.c b/pintos-progos/tests/vm/mmap-unmap.c new file mode 100644 index 0000000..d35a79e --- /dev/null +++ b/pintos-progos/tests/vm/mmap-unmap.c | |||
| @@ -0,0 +1,23 @@ | |||
| 1 | /* Maps and unmaps a file and verifies that the mapped region is | ||
| 2 | inaccessible afterward. */ | ||
| 3 | |||
| 4 | #include <syscall.h> | ||
| 5 | #include "tests/vm/sample.inc" | ||
| 6 | #include "tests/lib.h" | ||
| 7 | #include "tests/main.h" | ||
| 8 | |||
| 9 | #define ACTUAL ((void *) 0x10000000) | ||
| 10 | |||
| 11 | void | ||
| 12 | test_main (void) | ||
| 13 | { | ||
| 14 | int handle; | ||
| 15 | mapid_t map; | ||
| 16 | |||
| 17 | CHECK ((handle = open ("sample.txt")) > 1, "open \"sample.txt\""); | ||
| 18 | CHECK ((map = mmap (handle, ACTUAL)) != MAP_FAILED, "mmap \"sample.txt\""); | ||
| 19 | |||
| 20 | munmap (map); | ||
| 21 | |||
| 22 | fail ("unmapped memory is readable (%d)", *(int *) ACTUAL); | ||
| 23 | } | ||
diff --git a/pintos-progos/tests/vm/mmap-unmap.ck b/pintos-progos/tests/vm/mmap-unmap.ck new file mode 100644 index 0000000..119658c --- /dev/null +++ b/pintos-progos/tests/vm/mmap-unmap.ck | |||
| @@ -0,0 +1,7 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | use tests::vm::process_death; | ||
| 6 | |||
| 7 | check_process_death ('mmap-unmap'); | ||
diff --git a/pintos-progos/tests/vm/mmap-write.c b/pintos-progos/tests/vm/mmap-write.c new file mode 100644 index 0000000..46e8043 --- /dev/null +++ b/pintos-progos/tests/vm/mmap-write.c | |||
| @@ -0,0 +1,32 @@ | |||
| 1 | /* Writes to a file through a mapping, and unmaps the file, | ||
| 2 | then reads the data in the file back using the read system | ||
| 3 | call to verify. */ | ||
| 4 | |||
| 5 | #include <string.h> | ||
| 6 | #include <syscall.h> | ||
| 7 | #include "tests/vm/sample.inc" | ||
| 8 | #include "tests/lib.h" | ||
| 9 | #include "tests/main.h" | ||
| 10 | |||
| 11 | #define ACTUAL ((void *) 0x10000000) | ||
| 12 | |||
| 13 | void | ||
| 14 | test_main (void) | ||
| 15 | { | ||
| 16 | int handle; | ||
| 17 | mapid_t map; | ||
| 18 | char buf[1024]; | ||
| 19 | |||
| 20 | /* Write file via mmap. */ | ||
| 21 | CHECK (create ("sample.txt", strlen (sample)), "create \"sample.txt\""); | ||
| 22 | CHECK ((handle = open ("sample.txt")) > 1, "open \"sample.txt\""); | ||
| 23 | CHECK ((map = mmap (handle, ACTUAL)) != MAP_FAILED, "mmap \"sample.txt\""); | ||
| 24 | memcpy (ACTUAL, sample, strlen (sample)); | ||
| 25 | munmap (map); | ||
| 26 | |||
| 27 | /* Read back via read(). */ | ||
| 28 | read (handle, buf, strlen (sample)); | ||
| 29 | CHECK (!memcmp (buf, sample, strlen (sample)), | ||
| 30 | "compare read data against written data"); | ||
| 31 | close (handle); | ||
| 32 | } | ||
diff --git a/pintos-progos/tests/vm/mmap-write.ck b/pintos-progos/tests/vm/mmap-write.ck new file mode 100644 index 0000000..d2c9cc5 --- /dev/null +++ b/pintos-progos/tests/vm/mmap-write.ck | |||
| @@ -0,0 +1,13 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); | ||
| 6 | (mmap-write) begin | ||
| 7 | (mmap-write) create "sample.txt" | ||
| 8 | (mmap-write) open "sample.txt" | ||
| 9 | (mmap-write) mmap "sample.txt" | ||
| 10 | (mmap-write) compare read data against written data | ||
| 11 | (mmap-write) end | ||
| 12 | EOF | ||
| 13 | pass; | ||
diff --git a/pintos-progos/tests/vm/mmap-zero.c b/pintos-progos/tests/vm/mmap-zero.c new file mode 100644 index 0000000..368b759 --- /dev/null +++ b/pintos-progos/tests/vm/mmap-zero.c | |||
| @@ -0,0 +1,27 @@ | |||
| 1 | /* Tries to map a zero-length file, which may or may not work but | ||
| 2 | should not terminate the process or crash. | ||
| 3 | Then dereferences the address that we tried to map, | ||
| 4 | and the process must be terminated with -1 exit code. */ | ||
| 5 | |||
| 6 | #include <syscall.h> | ||
| 7 | #include "tests/lib.h" | ||
| 8 | #include "tests/main.h" | ||
| 9 | |||
| 10 | void | ||
| 11 | test_main (void) | ||
| 12 | { | ||
| 13 | char *data = (char *) 0x7f000000; | ||
| 14 | int handle; | ||
| 15 | |||
| 16 | CHECK (create ("empty", 0), "create empty file \"empty\""); | ||
| 17 | CHECK ((handle = open ("empty")) > 1, "open \"empty\""); | ||
| 18 | |||
| 19 | /* Calling mmap() might succeed or fail. We don't care. */ | ||
| 20 | msg ("mmap \"empty\""); | ||
| 21 | mmap (handle, data); | ||
| 22 | |||
| 23 | /* Regardless of whether the call worked, *data should cause | ||
| 24 | the process to be terminated. */ | ||
| 25 | fail ("unmapped memory is readable (%d)", *data); | ||
| 26 | } | ||
| 27 | |||
diff --git a/pintos-progos/tests/vm/mmap-zero.ck b/pintos-progos/tests/vm/mmap-zero.ck new file mode 100644 index 0000000..6033d5d --- /dev/null +++ b/pintos-progos/tests/vm/mmap-zero.ck | |||
| @@ -0,0 +1,12 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected (IGNORE_USER_FAULTS => 1, [<<'EOF']); | ||
| 6 | (mmap-zero) begin | ||
| 7 | (mmap-zero) create empty file "empty" | ||
| 8 | (mmap-zero) open "empty" | ||
| 9 | (mmap-zero) mmap "empty" | ||
| 10 | mmap-zero: exit(-1) | ||
| 11 | EOF | ||
| 12 | pass; | ||
diff --git a/pintos-progos/tests/vm/page-linear.c b/pintos-progos/tests/vm/page-linear.c new file mode 100644 index 0000000..652a47b --- /dev/null +++ b/pintos-progos/tests/vm/page-linear.c | |||
| @@ -0,0 +1,44 @@ | |||
| 1 | /* Encrypts, then decrypts, 2 MB of memory and verifies that the | ||
| 2 | values are as they should be. */ | ||
| 3 | |||
| 4 | #include <string.h> | ||
| 5 | #include "tests/arc4.h" | ||
| 6 | #include "tests/lib.h" | ||
| 7 | #include "tests/main.h" | ||
| 8 | |||
| 9 | #define SIZE (2 * 1024 * 1024) | ||
| 10 | |||
| 11 | static char buf[SIZE]; | ||
| 12 | |||
| 13 | void | ||
| 14 | test_main (void) | ||
| 15 | { | ||
| 16 | struct arc4 arc4; | ||
| 17 | size_t i; | ||
| 18 | |||
| 19 | /* Initialize to 0x5a. */ | ||
| 20 | msg ("initialize"); | ||
| 21 | memset (buf, 0x5a, sizeof buf); | ||
| 22 | |||
| 23 | /* Check that it's all 0x5a. */ | ||
| 24 | msg ("read pass"); | ||
| 25 | for (i = 0; i < SIZE; i++) | ||
| 26 | if (buf[i] != 0x5a) | ||
| 27 | fail ("byte %zu != 0x5a", i); | ||
| 28 | |||
| 29 | /* Encrypt zeros. */ | ||
| 30 | msg ("read/modify/write pass one"); | ||
| 31 | arc4_init (&arc4, "foobar", 6); | ||
| 32 | arc4_crypt (&arc4, buf, SIZE); | ||
| 33 | |||
| 34 | /* Decrypt back to zeros. */ | ||
| 35 | msg ("read/modify/write pass two"); | ||
| 36 | arc4_init (&arc4, "foobar", 6); | ||
| 37 | arc4_crypt (&arc4, buf, SIZE); | ||
| 38 | |||
| 39 | /* Check that it's all 0x5a. */ | ||
| 40 | msg ("read pass"); | ||
| 41 | for (i = 0; i < SIZE; i++) | ||
| 42 | if (buf[i] != 0x5a) | ||
| 43 | fail ("byte %zu != 0x5a", i); | ||
| 44 | } | ||
diff --git a/pintos-progos/tests/vm/page-linear.ck b/pintos-progos/tests/vm/page-linear.ck new file mode 100644 index 0000000..dcbc884 --- /dev/null +++ b/pintos-progos/tests/vm/page-linear.ck | |||
| @@ -0,0 +1,14 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); | ||
| 6 | (page-linear) begin | ||
| 7 | (page-linear) initialize | ||
| 8 | (page-linear) read pass | ||
| 9 | (page-linear) read/modify/write pass one | ||
| 10 | (page-linear) read/modify/write pass two | ||
| 11 | (page-linear) read pass | ||
| 12 | (page-linear) end | ||
| 13 | EOF | ||
| 14 | pass; | ||
diff --git a/pintos-progos/tests/vm/page-merge-mm.c b/pintos-progos/tests/vm/page-merge-mm.c new file mode 100644 index 0000000..908c71c --- /dev/null +++ b/pintos-progos/tests/vm/page-merge-mm.c | |||
| @@ -0,0 +1,8 @@ | |||
| 1 | #include "tests/main.h" | ||
| 2 | #include "tests/vm/parallel-merge.h" | ||
| 3 | |||
| 4 | void | ||
| 5 | test_main (void) | ||
| 6 | { | ||
| 7 | parallel_merge ("child-qsort-mm", 80); | ||
| 8 | } | ||
diff --git a/pintos-progos/tests/vm/page-merge-mm.ck b/pintos-progos/tests/vm/page-merge-mm.ck new file mode 100644 index 0000000..74fa980 --- /dev/null +++ b/pintos-progos/tests/vm/page-merge-mm.ck | |||
| @@ -0,0 +1,29 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); | ||
| 6 | (page-merge-mm) begin | ||
| 7 | (page-merge-mm) init | ||
| 8 | (page-merge-mm) sort chunk 0 | ||
| 9 | (page-merge-mm) sort chunk 1 | ||
| 10 | (page-merge-mm) sort chunk 2 | ||
| 11 | (page-merge-mm) sort chunk 3 | ||
| 12 | (page-merge-mm) sort chunk 4 | ||
| 13 | (page-merge-mm) sort chunk 5 | ||
| 14 | (page-merge-mm) sort chunk 6 | ||
| 15 | (page-merge-mm) sort chunk 7 | ||
| 16 | (page-merge-mm) wait for child 0 | ||
| 17 | (page-merge-mm) wait for child 1 | ||
| 18 | (page-merge-mm) wait for child 2 | ||
| 19 | (page-merge-mm) wait for child 3 | ||
| 20 | (page-merge-mm) wait for child 4 | ||
| 21 | (page-merge-mm) wait for child 5 | ||
| 22 | (page-merge-mm) wait for child 6 | ||
| 23 | (page-merge-mm) wait for child 7 | ||
| 24 | (page-merge-mm) merge | ||
| 25 | (page-merge-mm) verify | ||
| 26 | (page-merge-mm) success, buf_idx=1,048,576 | ||
| 27 | (page-merge-mm) end | ||
| 28 | EOF | ||
| 29 | pass; | ||
diff --git a/pintos-progos/tests/vm/page-merge-par.c b/pintos-progos/tests/vm/page-merge-par.c new file mode 100644 index 0000000..e7e1609 --- /dev/null +++ b/pintos-progos/tests/vm/page-merge-par.c | |||
| @@ -0,0 +1,8 @@ | |||
| 1 | #include "tests/main.h" | ||
| 2 | #include "tests/vm/parallel-merge.h" | ||
| 3 | |||
| 4 | void | ||
| 5 | test_main (void) | ||
| 6 | { | ||
| 7 | parallel_merge ("child-sort", 123); | ||
| 8 | } | ||
diff --git a/pintos-progos/tests/vm/page-merge-par.ck b/pintos-progos/tests/vm/page-merge-par.ck new file mode 100644 index 0000000..31f8aa7 --- /dev/null +++ b/pintos-progos/tests/vm/page-merge-par.ck | |||
| @@ -0,0 +1,29 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); | ||
| 6 | (page-merge-par) begin | ||
| 7 | (page-merge-par) init | ||
| 8 | (page-merge-par) sort chunk 0 | ||
| 9 | (page-merge-par) sort chunk 1 | ||
| 10 | (page-merge-par) sort chunk 2 | ||
| 11 | (page-merge-par) sort chunk 3 | ||
| 12 | (page-merge-par) sort chunk 4 | ||
| 13 | (page-merge-par) sort chunk 5 | ||
| 14 | (page-merge-par) sort chunk 6 | ||
| 15 | (page-merge-par) sort chunk 7 | ||
| 16 | (page-merge-par) wait for child 0 | ||
| 17 | (page-merge-par) wait for child 1 | ||
| 18 | (page-merge-par) wait for child 2 | ||
| 19 | (page-merge-par) wait for child 3 | ||
| 20 | (page-merge-par) wait for child 4 | ||
| 21 | (page-merge-par) wait for child 5 | ||
| 22 | (page-merge-par) wait for child 6 | ||
| 23 | (page-merge-par) wait for child 7 | ||
| 24 | (page-merge-par) merge | ||
| 25 | (page-merge-par) verify | ||
| 26 | (page-merge-par) success, buf_idx=1,048,576 | ||
| 27 | (page-merge-par) end | ||
| 28 | EOF | ||
| 29 | pass; | ||
diff --git a/pintos-progos/tests/vm/page-merge-seq.c b/pintos-progos/tests/vm/page-merge-seq.c new file mode 100644 index 0000000..12e3880 --- /dev/null +++ b/pintos-progos/tests/vm/page-merge-seq.c | |||
| @@ -0,0 +1,137 @@ | |||
| 1 | /* Generates about 1 MB of random data that is then divided into | ||
| 2 | 16 chunks. A separate subprocess sorts each chunk in | ||
| 3 | sequence. Then we merge the chunks and verify that the result | ||
| 4 | is what it should be. */ | ||
| 5 | |||
| 6 | #include <syscall.h> | ||
| 7 | #include "tests/arc4.h" | ||
| 8 | #include "tests/lib.h" | ||
| 9 | #include "tests/main.h" | ||
| 10 | |||
| 11 | /* This is the max file size for an older version of the Pintos | ||
| 12 | file system that had 126 direct blocks each pointing to a | ||
| 13 | single disk sector. We could raise it now. */ | ||
| 14 | #define CHUNK_SIZE (126 * 512) | ||
| 15 | #define CHUNK_CNT 16 /* Number of chunks. */ | ||
| 16 | #define DATA_SIZE (CHUNK_CNT * CHUNK_SIZE) /* Buffer size. */ | ||
| 17 | |||
| 18 | unsigned char buf1[DATA_SIZE], buf2[DATA_SIZE]; | ||
| 19 | size_t histogram[256]; | ||
| 20 | |||
| 21 | /* Initialize buf1 with random data, | ||
| 22 | then count the number of instances of each value within it. */ | ||
| 23 | static void | ||
| 24 | init (void) | ||
| 25 | { | ||
| 26 | struct arc4 arc4; | ||
| 27 | size_t i; | ||
| 28 | |||
| 29 | msg ("init"); | ||
| 30 | |||
| 31 | arc4_init (&arc4, "foobar", 6); | ||
| 32 | arc4_crypt (&arc4, buf1, sizeof buf1); | ||
| 33 | for (i = 0; i < sizeof buf1; i++) | ||
| 34 | histogram[buf1[i]]++; | ||
| 35 | } | ||
| 36 | |||
| 37 | /* Sort each chunk of buf1 using a subprocess. */ | ||
| 38 | static void | ||
| 39 | sort_chunks (void) | ||
| 40 | { | ||
| 41 | size_t i; | ||
| 42 | |||
| 43 | create ("buffer", CHUNK_SIZE); | ||
| 44 | for (i = 0; i < CHUNK_CNT; i++) | ||
| 45 | { | ||
| 46 | pid_t child; | ||
| 47 | int handle; | ||
| 48 | |||
| 49 | msg ("sort chunk %zu", i); | ||
| 50 | |||
| 51 | /* Write this chunk to a file. */ | ||
| 52 | quiet = true; | ||
| 53 | CHECK ((handle = open ("buffer")) > 1, "open \"buffer\""); | ||
| 54 | write (handle, buf1 + CHUNK_SIZE * i, CHUNK_SIZE); | ||
| 55 | close (handle); | ||
| 56 | |||
| 57 | /* Sort with subprocess. */ | ||
| 58 | CHECK ((child = exec ("child-sort buffer")) != -1, | ||
| 59 | "exec \"child-sort buffer\""); | ||
| 60 | CHECK (wait (child) == 123, "wait for child-sort"); | ||
| 61 | |||
| 62 | /* Read chunk back from file. */ | ||
| 63 | CHECK ((handle = open ("buffer")) > 1, "open \"buffer\""); | ||
| 64 | read (handle, buf1 + CHUNK_SIZE * i, CHUNK_SIZE); | ||
| 65 | close (handle); | ||
| 66 | |||
| 67 | quiet = false; | ||
| 68 | } | ||
| 69 | } | ||
| 70 | |||
| 71 | /* Merge the sorted chunks in buf1 into a fully sorted buf2. */ | ||
| 72 | static void | ||
| 73 | merge (void) | ||
| 74 | { | ||
| 75 | unsigned char *mp[CHUNK_CNT]; | ||
| 76 | size_t mp_left; | ||
| 77 | unsigned char *op; | ||
| 78 | size_t i; | ||
| 79 | |||
| 80 | msg ("merge"); | ||
| 81 | |||
| 82 | /* Initialize merge pointers. */ | ||
| 83 | mp_left = CHUNK_CNT; | ||
| 84 | for (i = 0; i < CHUNK_CNT; i++) | ||
| 85 | mp[i] = buf1 + CHUNK_SIZE * i; | ||
| 86 | |||
| 87 | /* Merge. */ | ||
| 88 | op = buf2; | ||
| 89 | while (mp_left > 0) | ||
| 90 | { | ||
| 91 | /* Find smallest value. */ | ||
| 92 | size_t min = 0; | ||
| 93 | for (i = 1; i < mp_left; i++) | ||
| 94 | if (*mp[i] < *mp[min]) | ||
| 95 | min = i; | ||
| 96 | |||
| 97 | /* Append value to buf2. */ | ||
| 98 | *op++ = *mp[min]; | ||
| 99 | |||
| 100 | /* Advance merge pointer. | ||
| 101 | Delete this chunk from the set if it's emptied. */ | ||
| 102 | if ((++mp[min] - buf1) % CHUNK_SIZE == 0) | ||
| 103 | mp[min] = mp[--mp_left]; | ||
| 104 | } | ||
| 105 | } | ||
| 106 | |||
| 107 | static void | ||
| 108 | verify (void) | ||
| 109 | { | ||
| 110 | size_t buf_idx; | ||
| 111 | size_t hist_idx; | ||
| 112 | |||
| 113 | msg ("verify"); | ||
| 114 | |||
| 115 | buf_idx = 0; | ||
| 116 | for (hist_idx = 0; hist_idx < sizeof histogram / sizeof *histogram; | ||
| 117 | hist_idx++) | ||
| 118 | { | ||
| 119 | while (histogram[hist_idx]-- > 0) | ||
| 120 | { | ||
| 121 | if (buf2[buf_idx] != hist_idx) | ||
| 122 | fail ("bad value %d in byte %zu", buf2[buf_idx], buf_idx); | ||
| 123 | buf_idx++; | ||
| 124 | } | ||
| 125 | } | ||
| 126 | |||
| 127 | msg ("success, buf_idx=%'zu", buf_idx); | ||
| 128 | } | ||
| 129 | |||
| 130 | void | ||
| 131 | test_main (void) | ||
| 132 | { | ||
| 133 | init (); | ||
| 134 | sort_chunks (); | ||
| 135 | merge (); | ||
| 136 | verify (); | ||
| 137 | } | ||
diff --git a/pintos-progos/tests/vm/page-merge-seq.ck b/pintos-progos/tests/vm/page-merge-seq.ck new file mode 100644 index 0000000..d78f69d --- /dev/null +++ b/pintos-progos/tests/vm/page-merge-seq.ck | |||
| @@ -0,0 +1,29 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); | ||
| 6 | (page-merge-seq) begin | ||
| 7 | (page-merge-seq) init | ||
| 8 | (page-merge-seq) sort chunk 0 | ||
| 9 | (page-merge-seq) sort chunk 1 | ||
| 10 | (page-merge-seq) sort chunk 2 | ||
| 11 | (page-merge-seq) sort chunk 3 | ||
| 12 | (page-merge-seq) sort chunk 4 | ||
| 13 | (page-merge-seq) sort chunk 5 | ||
| 14 | (page-merge-seq) sort chunk 6 | ||
| 15 | (page-merge-seq) sort chunk 7 | ||
| 16 | (page-merge-seq) sort chunk 8 | ||
| 17 | (page-merge-seq) sort chunk 9 | ||
| 18 | (page-merge-seq) sort chunk 10 | ||
| 19 | (page-merge-seq) sort chunk 11 | ||
| 20 | (page-merge-seq) sort chunk 12 | ||
| 21 | (page-merge-seq) sort chunk 13 | ||
| 22 | (page-merge-seq) sort chunk 14 | ||
| 23 | (page-merge-seq) sort chunk 15 | ||
| 24 | (page-merge-seq) merge | ||
| 25 | (page-merge-seq) verify | ||
| 26 | (page-merge-seq) success, buf_idx=1,032,192 | ||
| 27 | (page-merge-seq) end | ||
| 28 | EOF | ||
| 29 | pass; | ||
diff --git a/pintos-progos/tests/vm/page-merge-stk.c b/pintos-progos/tests/vm/page-merge-stk.c new file mode 100644 index 0000000..5eb1069 --- /dev/null +++ b/pintos-progos/tests/vm/page-merge-stk.c | |||
| @@ -0,0 +1,8 @@ | |||
| 1 | #include "tests/main.h" | ||
| 2 | #include "tests/vm/parallel-merge.h" | ||
| 3 | |||
| 4 | void | ||
| 5 | test_main (void) | ||
| 6 | { | ||
| 7 | parallel_merge ("child-qsort", 72); | ||
| 8 | } | ||
diff --git a/pintos-progos/tests/vm/page-merge-stk.ck b/pintos-progos/tests/vm/page-merge-stk.ck new file mode 100644 index 0000000..c5bc1ae --- /dev/null +++ b/pintos-progos/tests/vm/page-merge-stk.ck | |||
| @@ -0,0 +1,29 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); | ||
| 6 | (page-merge-stk) begin | ||
| 7 | (page-merge-stk) init | ||
| 8 | (page-merge-stk) sort chunk 0 | ||
| 9 | (page-merge-stk) sort chunk 1 | ||
| 10 | (page-merge-stk) sort chunk 2 | ||
| 11 | (page-merge-stk) sort chunk 3 | ||
| 12 | (page-merge-stk) sort chunk 4 | ||
| 13 | (page-merge-stk) sort chunk 5 | ||
| 14 | (page-merge-stk) sort chunk 6 | ||
| 15 | (page-merge-stk) sort chunk 7 | ||
| 16 | (page-merge-stk) wait for child 0 | ||
| 17 | (page-merge-stk) wait for child 1 | ||
| 18 | (page-merge-stk) wait for child 2 | ||
| 19 | (page-merge-stk) wait for child 3 | ||
| 20 | (page-merge-stk) wait for child 4 | ||
| 21 | (page-merge-stk) wait for child 5 | ||
| 22 | (page-merge-stk) wait for child 6 | ||
| 23 | (page-merge-stk) wait for child 7 | ||
| 24 | (page-merge-stk) merge | ||
| 25 | (page-merge-stk) verify | ||
| 26 | (page-merge-stk) success, buf_idx=1,048,576 | ||
| 27 | (page-merge-stk) end | ||
| 28 | EOF | ||
| 29 | pass; | ||
diff --git a/pintos-progos/tests/vm/page-parallel.c b/pintos-progos/tests/vm/page-parallel.c new file mode 100644 index 0000000..9d619e0 --- /dev/null +++ b/pintos-progos/tests/vm/page-parallel.c | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | /* Runs 4 child-linear processes at once. */ | ||
| 2 | |||
| 3 | #include <syscall.h> | ||
| 4 | #include "tests/lib.h" | ||
| 5 | #include "tests/main.h" | ||
| 6 | |||
| 7 | #define CHILD_CNT 4 | ||
| 8 | |||
| 9 | void | ||
| 10 | test_main (void) | ||
| 11 | { | ||
| 12 | pid_t children[CHILD_CNT]; | ||
| 13 | int i; | ||
| 14 | |||
| 15 | for (i = 0; i < CHILD_CNT; i++) | ||
| 16 | CHECK ((children[i] = exec ("child-linear")) != -1, | ||
| 17 | "exec \"child-linear\""); | ||
| 18 | |||
| 19 | for (i = 0; i < CHILD_CNT; i++) | ||
| 20 | CHECK (wait (children[i]) == 0x42, "wait for child %d", i); | ||
| 21 | } | ||
diff --git a/pintos-progos/tests/vm/page-parallel.ck b/pintos-progos/tests/vm/page-parallel.ck new file mode 100644 index 0000000..90c14ef --- /dev/null +++ b/pintos-progos/tests/vm/page-parallel.ck | |||
| @@ -0,0 +1,17 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); | ||
| 6 | (page-parallel) begin | ||
| 7 | (page-parallel) exec "child-linear" | ||
| 8 | (page-parallel) exec "child-linear" | ||
| 9 | (page-parallel) exec "child-linear" | ||
| 10 | (page-parallel) exec "child-linear" | ||
| 11 | (page-parallel) wait for child 0 | ||
| 12 | (page-parallel) wait for child 1 | ||
| 13 | (page-parallel) wait for child 2 | ||
| 14 | (page-parallel) wait for child 3 | ||
| 15 | (page-parallel) end | ||
| 16 | EOF | ||
| 17 | pass; | ||
diff --git a/pintos-progos/tests/vm/page-shuffle.c b/pintos-progos/tests/vm/page-shuffle.c new file mode 100644 index 0000000..095a9da --- /dev/null +++ b/pintos-progos/tests/vm/page-shuffle.c | |||
| @@ -0,0 +1,30 @@ | |||
| 1 | /* Shuffles a 128 kB data buffer 10 times, printing the checksum | ||
| 2 | after each time. */ | ||
| 3 | |||
| 4 | #include <stdbool.h> | ||
| 5 | #include "tests/arc4.h" | ||
| 6 | #include "tests/cksum.h" | ||
| 7 | #include "tests/lib.h" | ||
| 8 | #include "tests/main.h" | ||
| 9 | |||
| 10 | #define SIZE (128 * 1024) | ||
| 11 | |||
| 12 | static char buf[SIZE]; | ||
| 13 | |||
| 14 | void | ||
| 15 | test_main (void) | ||
| 16 | { | ||
| 17 | size_t i; | ||
| 18 | |||
| 19 | /* Initialize. */ | ||
| 20 | for (i = 0; i < sizeof buf; i++) | ||
| 21 | buf[i] = i * 257; | ||
| 22 | msg ("init: cksum=%lu", cksum (buf, sizeof buf)); | ||
| 23 | |||
| 24 | /* Shuffle repeatedly. */ | ||
| 25 | for (i = 0; i < 10; i++) | ||
| 26 | { | ||
| 27 | shuffle (buf, sizeof buf, 1); | ||
| 28 | msg ("shuffle %zu: cksum=%lu", i, cksum (buf, sizeof buf)); | ||
| 29 | } | ||
| 30 | } | ||
diff --git a/pintos-progos/tests/vm/page-shuffle.ck b/pintos-progos/tests/vm/page-shuffle.ck new file mode 100644 index 0000000..6447d38 --- /dev/null +++ b/pintos-progos/tests/vm/page-shuffle.ck | |||
| @@ -0,0 +1,44 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | use tests::cksum; | ||
| 6 | use tests::lib; | ||
| 7 | |||
| 8 | my ($init, @shuffle); | ||
| 9 | if (1) { | ||
| 10 | # Use precalculated values. | ||
| 11 | $init = 3115322833; | ||
| 12 | @shuffle = (1691062564, 1973575879, 1647619479, 96566261, 3885786467, | ||
| 13 | 3022003332, 3614934266, 2704001777, 735775156, 1864109763); | ||
| 14 | } else { | ||
| 15 | # Recalculate values. | ||
| 16 | my ($buf) = ""; | ||
| 17 | for my $i (0...128 * 1024 - 1) { | ||
| 18 | $buf .= chr (($i * 257) & 0xff); | ||
| 19 | } | ||
| 20 | $init = cksum ($buf); | ||
| 21 | |||
| 22 | random_init (0); | ||
| 23 | for my $i (1...10) { | ||
| 24 | $buf = shuffle ($buf, length ($buf), 1); | ||
| 25 | push (@shuffle, cksum ($buf)); | ||
| 26 | } | ||
| 27 | } | ||
| 28 | |||
| 29 | check_expected (IGNORE_EXIT_CODES => 1, [<<EOF]); | ||
| 30 | (page-shuffle) begin | ||
| 31 | (page-shuffle) init: cksum=$init | ||
| 32 | (page-shuffle) shuffle 0: cksum=$shuffle[0] | ||
| 33 | (page-shuffle) shuffle 1: cksum=$shuffle[1] | ||
| 34 | (page-shuffle) shuffle 2: cksum=$shuffle[2] | ||
| 35 | (page-shuffle) shuffle 3: cksum=$shuffle[3] | ||
| 36 | (page-shuffle) shuffle 4: cksum=$shuffle[4] | ||
| 37 | (page-shuffle) shuffle 5: cksum=$shuffle[5] | ||
| 38 | (page-shuffle) shuffle 6: cksum=$shuffle[6] | ||
| 39 | (page-shuffle) shuffle 7: cksum=$shuffle[7] | ||
| 40 | (page-shuffle) shuffle 8: cksum=$shuffle[8] | ||
| 41 | (page-shuffle) shuffle 9: cksum=$shuffle[9] | ||
| 42 | (page-shuffle) end | ||
| 43 | EOF | ||
| 44 | pass; | ||
diff --git a/pintos-progos/tests/vm/parallel-merge.c b/pintos-progos/tests/vm/parallel-merge.c new file mode 100644 index 0000000..cc09bb1 --- /dev/null +++ b/pintos-progos/tests/vm/parallel-merge.c | |||
| @@ -0,0 +1,149 @@ | |||
| 1 | /* Generates about 1 MB of random data that is then divided into | ||
| 2 | 16 chunks. A separate subprocess sorts each chunk; the | ||
| 3 | subprocesses run in parallel. Then we merge the chunks and | ||
| 4 | verify that the result is what it should be. */ | ||
| 5 | |||
| 6 | #include "tests/vm/parallel-merge.h" | ||
| 7 | #include <stdio.h> | ||
| 8 | #include <syscall.h> | ||
| 9 | #include "tests/arc4.h" | ||
| 10 | #include "tests/lib.h" | ||
| 11 | #include "tests/main.h" | ||
| 12 | |||
| 13 | #define CHUNK_SIZE (128 * 1024) | ||
| 14 | #define CHUNK_CNT 8 /* Number of chunks. */ | ||
| 15 | #define DATA_SIZE (CHUNK_CNT * CHUNK_SIZE) /* Buffer size. */ | ||
| 16 | |||
| 17 | unsigned char buf1[DATA_SIZE], buf2[DATA_SIZE]; | ||
| 18 | size_t histogram[256]; | ||
| 19 | |||
| 20 | /* Initialize buf1 with random data, | ||
| 21 | then count the number of instances of each value within it. */ | ||
| 22 | static void | ||
| 23 | init (void) | ||
| 24 | { | ||
| 25 | struct arc4 arc4; | ||
| 26 | size_t i; | ||
| 27 | |||
| 28 | msg ("init"); | ||
| 29 | |||
| 30 | arc4_init (&arc4, "foobar", 6); | ||
| 31 | arc4_crypt (&arc4, buf1, sizeof buf1); | ||
| 32 | for (i = 0; i < sizeof buf1; i++) | ||
| 33 | histogram[buf1[i]]++; | ||
| 34 | } | ||
| 35 | |||
| 36 | /* Sort each chunk of buf1 using SUBPROCESS, | ||
| 37 | which is expected to return EXIT_STATUS. */ | ||
| 38 | static void | ||
| 39 | sort_chunks (const char *subprocess, int exit_status) | ||
| 40 | { | ||
| 41 | pid_t children[CHUNK_CNT]; | ||
| 42 | size_t i; | ||
| 43 | |||
| 44 | for (i = 0; i < CHUNK_CNT; i++) | ||
| 45 | { | ||
| 46 | char fn[128]; | ||
| 47 | char cmd[128]; | ||
| 48 | int handle; | ||
| 49 | |||
| 50 | msg ("sort chunk %zu", i); | ||
| 51 | |||
| 52 | /* Write this chunk to a file. */ | ||
| 53 | snprintf (fn, sizeof fn, "buf%zu", i); | ||
| 54 | create (fn, CHUNK_SIZE); | ||
| 55 | quiet = true; | ||
| 56 | CHECK ((handle = open (fn)) > 1, "open \"%s\"", fn); | ||
| 57 | write (handle, buf1 + CHUNK_SIZE * i, CHUNK_SIZE); | ||
| 58 | close (handle); | ||
| 59 | |||
| 60 | /* Sort with subprocess. */ | ||
| 61 | snprintf (cmd, sizeof cmd, "%s %s", subprocess, fn); | ||
| 62 | CHECK ((children[i] = exec (cmd)) != -1, "exec \"%s\"", cmd); | ||
| 63 | quiet = false; | ||
| 64 | } | ||
| 65 | |||
| 66 | for (i = 0; i < CHUNK_CNT; i++) | ||
| 67 | { | ||
| 68 | char fn[128]; | ||
| 69 | int handle; | ||
| 70 | |||
| 71 | CHECK (wait (children[i]) == exit_status, "wait for child %zu", i); | ||
| 72 | |||
| 73 | /* Read chunk back from file. */ | ||
| 74 | quiet = true; | ||
| 75 | snprintf (fn, sizeof fn, "buf%zu", i); | ||
| 76 | CHECK ((handle = open (fn)) > 1, "open \"%s\"", fn); | ||
| 77 | read (handle, buf1 + CHUNK_SIZE * i, CHUNK_SIZE); | ||
| 78 | close (handle); | ||
| 79 | quiet = false; | ||
| 80 | } | ||
| 81 | } | ||
| 82 | |||
| 83 | /* Merge the sorted chunks in buf1 into a fully sorted buf2. */ | ||
| 84 | static void | ||
| 85 | merge (void) | ||
| 86 | { | ||
| 87 | unsigned char *mp[CHUNK_CNT]; | ||
| 88 | size_t mp_left; | ||
| 89 | unsigned char *op; | ||
| 90 | size_t i; | ||
| 91 | |||
| 92 | msg ("merge"); | ||
| 93 | |||
| 94 | /* Initialize merge pointers. */ | ||
| 95 | mp_left = CHUNK_CNT; | ||
| 96 | for (i = 0; i < CHUNK_CNT; i++) | ||
| 97 | mp[i] = buf1 + CHUNK_SIZE * i; | ||
| 98 | |||
| 99 | /* Merge. */ | ||
| 100 | op = buf2; | ||
| 101 | while (mp_left > 0) | ||
| 102 | { | ||
| 103 | /* Find smallest value. */ | ||
| 104 | size_t min = 0; | ||
| 105 | for (i = 1; i < mp_left; i++) | ||
| 106 | if (*mp[i] < *mp[min]) | ||
| 107 | min = i; | ||
| 108 | |||
| 109 | /* Append value to buf2. */ | ||
| 110 | *op++ = *mp[min]; | ||
| 111 | |||
| 112 | /* Advance merge pointer. | ||
| 113 | Delete this chunk from the set if it's emptied. */ | ||
| 114 | if ((++mp[min] - buf1) % CHUNK_SIZE == 0) | ||
| 115 | mp[min] = mp[--mp_left]; | ||
| 116 | } | ||
| 117 | } | ||
| 118 | |||
| 119 | static void | ||
| 120 | verify (void) | ||
| 121 | { | ||
| 122 | size_t buf_idx; | ||
| 123 | size_t hist_idx; | ||
| 124 | |||
| 125 | msg ("verify"); | ||
| 126 | |||
| 127 | buf_idx = 0; | ||
| 128 | for (hist_idx = 0; hist_idx < sizeof histogram / sizeof *histogram; | ||
| 129 | hist_idx++) | ||
| 130 | { | ||
| 131 | while (histogram[hist_idx]-- > 0) | ||
| 132 | { | ||
| 133 | if (buf2[buf_idx] != hist_idx) | ||
| 134 | fail ("bad value %d in byte %zu", buf2[buf_idx], buf_idx); | ||
| 135 | buf_idx++; | ||
| 136 | } | ||
| 137 | } | ||
| 138 | |||
| 139 | msg ("success, buf_idx=%'zu", buf_idx); | ||
| 140 | } | ||
| 141 | |||
| 142 | void | ||
| 143 | parallel_merge (const char *child_name, int exit_status) | ||
| 144 | { | ||
| 145 | init (); | ||
| 146 | sort_chunks (child_name, exit_status); | ||
| 147 | merge (); | ||
| 148 | verify (); | ||
| 149 | } | ||
diff --git a/pintos-progos/tests/vm/parallel-merge.h b/pintos-progos/tests/vm/parallel-merge.h new file mode 100644 index 0000000..a6b6431 --- /dev/null +++ b/pintos-progos/tests/vm/parallel-merge.h | |||
| @@ -0,0 +1,6 @@ | |||
| 1 | #ifndef TESTS_VM_PARALLEL_MERGE | ||
| 2 | #define TESTS_VM_PARALLEL_MERGE 1 | ||
| 3 | |||
| 4 | void parallel_merge (const char *child_name, int exit_status); | ||
| 5 | |||
| 6 | #endif /* tests/vm/parallel-merge.h */ | ||
diff --git a/pintos-progos/tests/vm/process_death.pm b/pintos-progos/tests/vm/process_death.pm new file mode 100644 index 0000000..52039a1 --- /dev/null +++ b/pintos-progos/tests/vm/process_death.pm | |||
| @@ -0,0 +1,22 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | |||
| 6 | sub check_process_death { | ||
| 7 | my ($proc_name) = @_; | ||
| 8 | our ($test); | ||
| 9 | my (@output) = read_text_file ("$test.output"); | ||
| 10 | |||
| 11 | common_checks ("run", @output); | ||
| 12 | @output = get_core_output ("run", @output); | ||
| 13 | fail "First line of output is not `($proc_name) begin' message.\n" | ||
| 14 | if $output[0] ne "($proc_name) begin"; | ||
| 15 | fail "Output missing '$proc_name: exit(-1)' message.\n" | ||
| 16 | if !grep ("$proc_name: exit(-1)" eq $_, @output); | ||
| 17 | fail "Output contains '($proc_name) end' message.\n" | ||
| 18 | if grep (/\($proc_name\) end/, @output); | ||
| 19 | pass; | ||
| 20 | } | ||
| 21 | |||
| 22 | 1; | ||
diff --git a/pintos-progos/tests/vm/pt-bad-addr.c b/pintos-progos/tests/vm/pt-bad-addr.c new file mode 100644 index 0000000..3ca4084 --- /dev/null +++ b/pintos-progos/tests/vm/pt-bad-addr.c | |||
| @@ -0,0 +1,11 @@ | |||
| 1 | /* Accesses a bad address. | ||
| 2 | The process must be terminated with -1 exit code. */ | ||
| 3 | |||
| 4 | #include "tests/lib.h" | ||
| 5 | #include "tests/main.h" | ||
| 6 | |||
| 7 | void | ||
| 8 | test_main (void) | ||
| 9 | { | ||
| 10 | fail ("bad addr read as %d", *(int *) 0x04000000); | ||
| 11 | } | ||
diff --git a/pintos-progos/tests/vm/pt-bad-addr.ck b/pintos-progos/tests/vm/pt-bad-addr.ck new file mode 100644 index 0000000..09ea039 --- /dev/null +++ b/pintos-progos/tests/vm/pt-bad-addr.ck | |||
| @@ -0,0 +1,7 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | use tests::vm::process_death; | ||
| 6 | |||
| 7 | check_process_death ('pt-bad-addr'); | ||
diff --git a/pintos-progos/tests/vm/pt-bad-read.c b/pintos-progos/tests/vm/pt-bad-read.c new file mode 100644 index 0000000..ee791ff --- /dev/null +++ b/pintos-progos/tests/vm/pt-bad-read.c | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | /* Reads from a file into a bad address. | ||
| 2 | The process must be terminated with -1 exit code. */ | ||
| 3 | |||
| 4 | #include <syscall.h> | ||
| 5 | #include "tests/lib.h" | ||
| 6 | #include "tests/main.h" | ||
| 7 | |||
| 8 | void | ||
| 9 | test_main (void) | ||
| 10 | { | ||
| 11 | int handle; | ||
| 12 | |||
| 13 | CHECK ((handle = open ("sample.txt")) > 1, "open \"sample.txt\""); | ||
| 14 | read (handle, (char *) &handle - 4096, 1); | ||
| 15 | fail ("survived reading data into bad address"); | ||
| 16 | } | ||
diff --git a/pintos-progos/tests/vm/pt-bad-read.ck b/pintos-progos/tests/vm/pt-bad-read.ck new file mode 100644 index 0000000..1f96bb4 --- /dev/null +++ b/pintos-progos/tests/vm/pt-bad-read.ck | |||
| @@ -0,0 +1,10 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected ([<<'EOF']); | ||
| 6 | (pt-bad-read) begin | ||
| 7 | (pt-bad-read) open "sample.txt" | ||
| 8 | pt-bad-read: exit(-1) | ||
| 9 | EOF | ||
| 10 | pass; | ||
diff --git a/pintos-progos/tests/vm/pt-big-stk-obj.c b/pintos-progos/tests/vm/pt-big-stk-obj.c new file mode 100644 index 0000000..6b630ec --- /dev/null +++ b/pintos-progos/tests/vm/pt-big-stk-obj.c | |||
| @@ -0,0 +1,20 @@ | |||
| 1 | /* Allocates and writes to a 64 kB object on the stack. | ||
| 2 | This must succeed. */ | ||
| 3 | |||
| 4 | #include <string.h> | ||
| 5 | #include "tests/arc4.h" | ||
| 6 | #include "tests/cksum.h" | ||
| 7 | #include "tests/lib.h" | ||
| 8 | #include "tests/main.h" | ||
| 9 | |||
| 10 | void | ||
| 11 | test_main (void) | ||
| 12 | { | ||
| 13 | char stk_obj[65536]; | ||
| 14 | struct arc4 arc4; | ||
| 15 | |||
| 16 | arc4_init (&arc4, "foobar", 6); | ||
| 17 | memset (stk_obj, 0, sizeof stk_obj); | ||
| 18 | arc4_crypt (&arc4, stk_obj, sizeof stk_obj); | ||
| 19 | msg ("cksum: %lu", cksum (stk_obj, sizeof stk_obj)); | ||
| 20 | } | ||
diff --git a/pintos-progos/tests/vm/pt-big-stk-obj.ck b/pintos-progos/tests/vm/pt-big-stk-obj.ck new file mode 100644 index 0000000..eb5853a --- /dev/null +++ b/pintos-progos/tests/vm/pt-big-stk-obj.ck | |||
| @@ -0,0 +1,10 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); | ||
| 6 | (pt-big-stk-obj) begin | ||
| 7 | (pt-big-stk-obj) cksum: 3256410166 | ||
| 8 | (pt-big-stk-obj) end | ||
| 9 | EOF | ||
| 10 | pass; | ||
diff --git a/pintos-progos/tests/vm/pt-grow-bad.c b/pintos-progos/tests/vm/pt-grow-bad.c new file mode 100644 index 0000000..d4beba2 --- /dev/null +++ b/pintos-progos/tests/vm/pt-grow-bad.c | |||
| @@ -0,0 +1,14 @@ | |||
| 1 | /* Read from an address 4,096 bytes below the stack pointer. | ||
| 2 | The process must be terminated with -1 exit code. */ | ||
| 3 | |||
| 4 | #include <string.h> | ||
| 5 | #include "tests/arc4.h" | ||
| 6 | #include "tests/cksum.h" | ||
| 7 | #include "tests/lib.h" | ||
| 8 | #include "tests/main.h" | ||
| 9 | |||
| 10 | void | ||
| 11 | test_main (void) | ||
| 12 | { | ||
| 13 | asm volatile ("movl -4096(%esp), %eax"); | ||
| 14 | } | ||
diff --git a/pintos-progos/tests/vm/pt-grow-bad.ck b/pintos-progos/tests/vm/pt-grow-bad.ck new file mode 100644 index 0000000..4c0ab8a --- /dev/null +++ b/pintos-progos/tests/vm/pt-grow-bad.ck | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected (IGNORE_USER_FAULTS => 1, [<<'EOF']); | ||
| 6 | (pt-grow-bad) begin | ||
| 7 | pt-grow-bad: exit(-1) | ||
| 8 | EOF | ||
| 9 | pass; | ||
diff --git a/pintos-progos/tests/vm/pt-grow-pusha.c b/pintos-progos/tests/vm/pt-grow-pusha.c new file mode 100644 index 0000000..f9762a5 --- /dev/null +++ b/pintos-progos/tests/vm/pt-grow-pusha.c | |||
| @@ -0,0 +1,20 @@ | |||
| 1 | /* Expand the stack by 32 bytes all at once using the PUSHA | ||
| 2 | instruction. | ||
| 3 | This must succeed. */ | ||
| 4 | |||
| 5 | #include <string.h> | ||
| 6 | #include "tests/arc4.h" | ||
| 7 | #include "tests/cksum.h" | ||
| 8 | #include "tests/lib.h" | ||
| 9 | #include "tests/main.h" | ||
| 10 | |||
| 11 | void | ||
| 12 | test_main (void) | ||
| 13 | { | ||
| 14 | asm volatile | ||
| 15 | ("movl %%esp, %%eax;" /* Save a copy of the stack pointer. */ | ||
| 16 | "andl $0xfffff000, %%esp;" /* Move stack pointer to bottom of page. */ | ||
| 17 | "pushal;" /* Push 32 bytes on stack at once. */ | ||
| 18 | "movl %%eax, %%esp" /* Restore copied stack pointer. */ | ||
| 19 | : : : "eax"); /* Tell GCC we destroyed eax. */ | ||
| 20 | } | ||
diff --git a/pintos-progos/tests/vm/pt-grow-pusha.ck b/pintos-progos/tests/vm/pt-grow-pusha.ck new file mode 100644 index 0000000..5000966 --- /dev/null +++ b/pintos-progos/tests/vm/pt-grow-pusha.ck | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); | ||
| 6 | (pt-grow-pusha) begin | ||
| 7 | (pt-grow-pusha) end | ||
| 8 | EOF | ||
| 9 | pass; | ||
diff --git a/pintos-progos/tests/vm/pt-grow-stack.c b/pintos-progos/tests/vm/pt-grow-stack.c new file mode 100644 index 0000000..0997a00 --- /dev/null +++ b/pintos-progos/tests/vm/pt-grow-stack.c | |||
| @@ -0,0 +1,20 @@ | |||
| 1 | /* Demonstrate that the stack can grow. | ||
| 2 | This must succeed. */ | ||
| 3 | |||
| 4 | #include <string.h> | ||
| 5 | #include "tests/arc4.h" | ||
| 6 | #include "tests/cksum.h" | ||
| 7 | #include "tests/lib.h" | ||
| 8 | #include "tests/main.h" | ||
| 9 | |||
| 10 | void | ||
| 11 | test_main (void) | ||
| 12 | { | ||
| 13 | char stack_obj[4096]; | ||
| 14 | struct arc4 arc4; | ||
| 15 | |||
| 16 | arc4_init (&arc4, "foobar", 6); | ||
| 17 | memset (stack_obj, 0, sizeof stack_obj); | ||
| 18 | arc4_crypt (&arc4, stack_obj, sizeof stack_obj); | ||
| 19 | msg ("cksum: %lu", cksum (stack_obj, sizeof stack_obj)); | ||
| 20 | } | ||
diff --git a/pintos-progos/tests/vm/pt-grow-stack.ck b/pintos-progos/tests/vm/pt-grow-stack.ck new file mode 100644 index 0000000..1e669db --- /dev/null +++ b/pintos-progos/tests/vm/pt-grow-stack.ck | |||
| @@ -0,0 +1,10 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); | ||
| 6 | (pt-grow-stack) begin | ||
| 7 | (pt-grow-stack) cksum: 3424492700 | ||
| 8 | (pt-grow-stack) end | ||
| 9 | EOF | ||
| 10 | pass; | ||
diff --git a/pintos-progos/tests/vm/pt-grow-stk-sc.c b/pintos-progos/tests/vm/pt-grow-stk-sc.c new file mode 100644 index 0000000..3efbb5f --- /dev/null +++ b/pintos-progos/tests/vm/pt-grow-stk-sc.c | |||
| @@ -0,0 +1,32 @@ | |||
| 1 | /* This test checks that the stack is properly extended even if | ||
| 2 | the first access to a stack location occurs inside a system | ||
| 3 | call. | ||
| 4 | |||
| 5 | From Godmar Back. */ | ||
| 6 | |||
| 7 | #include <string.h> | ||
| 8 | #include <syscall.h> | ||
| 9 | #include "tests/vm/sample.inc" | ||
| 10 | #include "tests/lib.h" | ||
| 11 | #include "tests/main.h" | ||
| 12 | |||
| 13 | void | ||
| 14 | test_main (void) | ||
| 15 | { | ||
| 16 | int handle; | ||
| 17 | int slen = strlen (sample); | ||
| 18 | char buf2[65536]; | ||
| 19 | |||
| 20 | /* Write file via write(). */ | ||
| 21 | CHECK (create ("sample.txt", slen), "create \"sample.txt\""); | ||
| 22 | CHECK ((handle = open ("sample.txt")) > 1, "open \"sample.txt\""); | ||
| 23 | CHECK (write (handle, sample, slen) == slen, "write \"sample.txt\""); | ||
| 24 | close (handle); | ||
| 25 | |||
| 26 | /* Read back via read(). */ | ||
| 27 | CHECK ((handle = open ("sample.txt")) > 1, "2nd open \"sample.txt\""); | ||
| 28 | CHECK (read (handle, buf2 + 32768, slen) == slen, "read \"sample.txt\""); | ||
| 29 | |||
| 30 | CHECK (!memcmp (sample, buf2 + 32768, slen), "compare written data against read data"); | ||
| 31 | close (handle); | ||
| 32 | } | ||
diff --git a/pintos-progos/tests/vm/pt-grow-stk-sc.ck b/pintos-progos/tests/vm/pt-grow-stk-sc.ck new file mode 100644 index 0000000..23d3b02 --- /dev/null +++ b/pintos-progos/tests/vm/pt-grow-stk-sc.ck | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); | ||
| 6 | (pt-grow-stk-sc) begin | ||
| 7 | (pt-grow-stk-sc) create "sample.txt" | ||
| 8 | (pt-grow-stk-sc) open "sample.txt" | ||
| 9 | (pt-grow-stk-sc) write "sample.txt" | ||
| 10 | (pt-grow-stk-sc) 2nd open "sample.txt" | ||
| 11 | (pt-grow-stk-sc) read "sample.txt" | ||
| 12 | (pt-grow-stk-sc) compare written data against read data | ||
| 13 | (pt-grow-stk-sc) end | ||
| 14 | EOF | ||
| 15 | pass; | ||
diff --git a/pintos-progos/tests/vm/pt-write-code-2.c b/pintos-progos/tests/vm/pt-write-code-2.c new file mode 100644 index 0000000..83bcc2c --- /dev/null +++ b/pintos-progos/tests/vm/pt-write-code-2.c | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | /* Try to write to the code segment using a system call. | ||
| 2 | The process must be terminated with -1 exit code. */ | ||
| 3 | |||
| 4 | #include "tests/lib.h" | ||
| 5 | #include "tests/main.h" | ||
| 6 | |||
| 7 | void | ||
| 8 | test_main (void) | ||
| 9 | { | ||
| 10 | int handle; | ||
| 11 | |||
| 12 | CHECK ((handle = open ("sample.txt")) > 1, "open \"sample.txt\""); | ||
| 13 | read (handle, (void *) test_main, 1); | ||
| 14 | fail ("survived reading data into code segment"); | ||
| 15 | } | ||
diff --git a/pintos-progos/tests/vm/pt-write-code.c b/pintos-progos/tests/vm/pt-write-code.c new file mode 100644 index 0000000..5072cec --- /dev/null +++ b/pintos-progos/tests/vm/pt-write-code.c | |||
| @@ -0,0 +1,12 @@ | |||
| 1 | /* Try to write to the code segment. | ||
| 2 | The process must be terminated with -1 exit code. */ | ||
| 3 | |||
| 4 | #include "tests/lib.h" | ||
| 5 | #include "tests/main.h" | ||
| 6 | |||
| 7 | void | ||
| 8 | test_main (void) | ||
| 9 | { | ||
| 10 | *(int *) test_main = 0; | ||
| 11 | fail ("writing the code segment succeeded"); | ||
| 12 | } | ||
diff --git a/pintos-progos/tests/vm/pt-write-code.ck b/pintos-progos/tests/vm/pt-write-code.ck new file mode 100644 index 0000000..65610fb --- /dev/null +++ b/pintos-progos/tests/vm/pt-write-code.ck | |||
| @@ -0,0 +1,7 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | use tests::vm::process_death; | ||
| 6 | |||
| 7 | check_process_death ('pt-write-code'); | ||
diff --git a/pintos-progos/tests/vm/pt-write-code2.ck b/pintos-progos/tests/vm/pt-write-code2.ck new file mode 100644 index 0000000..69ffc77 --- /dev/null +++ b/pintos-progos/tests/vm/pt-write-code2.ck | |||
| @@ -0,0 +1,10 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected ([<<'EOF']); | ||
| 6 | (pt-write-code2) begin | ||
| 7 | (pt-write-code2) open "sample.txt" | ||
| 8 | pt-write-code2: exit(-1) | ||
| 9 | EOF | ||
| 10 | pass; | ||
diff --git a/pintos-progos/tests/vm/qsort.c b/pintos-progos/tests/vm/qsort.c new file mode 100644 index 0000000..922572c --- /dev/null +++ b/pintos-progos/tests/vm/qsort.c | |||
| @@ -0,0 +1,136 @@ | |||
| 1 | #include "tests/vm/qsort.h" | ||
| 2 | #include <stdbool.h> | ||
| 3 | #include <debug.h> | ||
| 4 | #include <random.h> | ||
| 5 | |||
| 6 | /* Picks a pivot for the quicksort from the SIZE bytes in BUF. */ | ||
| 7 | static unsigned char | ||
| 8 | pick_pivot (unsigned char *buf, size_t size) | ||
| 9 | { | ||
| 10 | ASSERT (size >= 1); | ||
| 11 | return buf[random_ulong () % size]; | ||
| 12 | } | ||
| 13 | |||
| 14 | /* Checks whether the SIZE bytes in ARRAY are divided into an | ||
| 15 | initial LEFT_SIZE elements all less than PIVOT followed by | ||
| 16 | SIZE - LEFT_SIZE elements all greater than or equal to | ||
| 17 | PIVOT. */ | ||
| 18 | static bool | ||
| 19 | is_partitioned (const unsigned char *array, size_t size, | ||
| 20 | unsigned char pivot, size_t left_size) | ||
| 21 | { | ||
| 22 | size_t i; | ||
| 23 | |||
| 24 | for (i = 0; i < left_size; i++) | ||
| 25 | if (array[i] >= pivot) | ||
| 26 | return false; | ||
| 27 | |||
| 28 | for (; i < size; i++) | ||
| 29 | if (array[i] < pivot) | ||
| 30 | return false; | ||
| 31 | |||
| 32 | return true; | ||
| 33 | } | ||
| 34 | |||
| 35 | /* Swaps the bytes at *A and *B. */ | ||
| 36 | static void | ||
| 37 | swap (unsigned char *a, unsigned char *b) | ||
| 38 | { | ||
| 39 | unsigned char t = *a; | ||
| 40 | *a = *b; | ||
| 41 | *b = t; | ||
| 42 | } | ||
| 43 | |||
| 44 | /* Partitions ARRAY in-place in an initial run of bytes all less | ||
| 45 | than PIVOT, followed by a run of bytes all greater than or | ||
| 46 | equal to PIVOT. Returns the length of the initial run. */ | ||
| 47 | static size_t | ||
| 48 | partition (unsigned char *array, size_t size, int pivot) | ||
| 49 | { | ||
| 50 | size_t left_size = size; | ||
| 51 | unsigned char *first = array; | ||
| 52 | unsigned char *last = first + left_size; | ||
| 53 | |||
| 54 | for (;;) | ||
| 55 | { | ||
| 56 | /* Move FIRST forward to point to first element greater than | ||
| 57 | PIVOT. */ | ||
| 58 | for (;;) | ||
| 59 | { | ||
| 60 | if (first == last) | ||
| 61 | { | ||
| 62 | ASSERT (is_partitioned (array, size, pivot, left_size)); | ||
| 63 | return left_size; | ||
| 64 | } | ||
| 65 | else if (*first >= pivot) | ||
| 66 | break; | ||
| 67 | |||
| 68 | first++; | ||
| 69 | } | ||
| 70 | left_size--; | ||
| 71 | |||
| 72 | /* Move LAST backward to point to last element no bigger | ||
| 73 | than PIVOT. */ | ||
| 74 | for (;;) | ||
| 75 | { | ||
| 76 | last--; | ||
| 77 | |||
| 78 | if (first == last) | ||
| 79 | { | ||
| 80 | ASSERT (is_partitioned (array, size, pivot, left_size)); | ||
| 81 | return left_size; | ||
| 82 | } | ||
| 83 | else if (*last < pivot) | ||
| 84 | break; | ||
| 85 | else | ||
| 86 | left_size--; | ||
| 87 | } | ||
| 88 | |||
| 89 | /* By swapping FIRST and LAST we extend the starting and | ||
| 90 | ending sequences that pass and fail, respectively, | ||
| 91 | PREDICATE. */ | ||
| 92 | swap (first, last); | ||
| 93 | first++; | ||
| 94 | } | ||
| 95 | } | ||
| 96 | |||
| 97 | /* Returns true if the SIZE bytes in BUF are in nondecreasing | ||
| 98 | order, false otherwise. */ | ||
| 99 | static bool | ||
| 100 | is_sorted (const unsigned char *buf, size_t size) | ||
| 101 | { | ||
| 102 | size_t i; | ||
| 103 | |||
| 104 | for (i = 1; i < size; i++) | ||
| 105 | if (buf[i - 1] > buf[i]) | ||
| 106 | return false; | ||
| 107 | |||
| 108 | return true; | ||
| 109 | } | ||
| 110 | |||
| 111 | /* Sorts the SIZE bytes in BUF into nondecreasing order, using | ||
| 112 | the quick-sort algorithm. */ | ||
| 113 | void | ||
| 114 | qsort_bytes (unsigned char *buf, size_t size) | ||
| 115 | { | ||
| 116 | if (!is_sorted (buf, size)) | ||
| 117 | { | ||
| 118 | int pivot = pick_pivot (buf, size); | ||
| 119 | |||
| 120 | unsigned char *left_half = buf; | ||
| 121 | size_t left_size = partition (buf, size, pivot); | ||
| 122 | unsigned char *right_half = left_half + left_size; | ||
| 123 | size_t right_size = size - left_size; | ||
| 124 | |||
| 125 | if (left_size <= right_size) | ||
| 126 | { | ||
| 127 | qsort_bytes (left_half, left_size); | ||
| 128 | qsort_bytes (right_half, right_size); | ||
| 129 | } | ||
| 130 | else | ||
| 131 | { | ||
| 132 | qsort_bytes (right_half, right_size); | ||
| 133 | qsort_bytes (left_half, left_size); | ||
| 134 | } | ||
| 135 | } | ||
| 136 | } | ||
diff --git a/pintos-progos/tests/vm/qsort.h b/pintos-progos/tests/vm/qsort.h new file mode 100644 index 0000000..61b65f3 --- /dev/null +++ b/pintos-progos/tests/vm/qsort.h | |||
| @@ -0,0 +1,8 @@ | |||
| 1 | #ifndef TESTS_VM_QSORT_H | ||
| 2 | #define TESTS_VM_QSORT_H 1 | ||
| 3 | |||
| 4 | #include <stddef.h> | ||
| 5 | |||
| 6 | void qsort_bytes (unsigned char *buf, size_t size); | ||
| 7 | |||
| 8 | #endif /* tests/vm/qsort.h */ | ||
diff --git a/pintos-progos/tests/vm/sample.inc b/pintos-progos/tests/vm/sample.inc new file mode 100644 index 0000000..a60a139 --- /dev/null +++ b/pintos-progos/tests/vm/sample.inc | |||
| @@ -0,0 +1,19 @@ | |||
| 1 | char sample[] = { | ||
| 2 | "=== ALL USERS PLEASE NOTE ========================\n" | ||
| 3 | "\n" | ||
| 4 | "CAR and CDR now return extra values.\n" | ||
| 5 | "\n" | ||
| 6 | "The function CAR now returns two values. Since it has to go to the\n" | ||
| 7 | "trouble to figure out if the object is carcdr-able anyway, we figured\n" | ||
| 8 | "you might as well get both halves at once. For example, the following\n" | ||
| 9 | "code shows how to destructure a cons (SOME-CONS) into its two slots\n" | ||
| 10 | "(THE-CAR and THE-CDR):\n" | ||
| 11 | "\n" | ||
| 12 | " (MULTIPLE-VALUE-BIND (THE-CAR THE-CDR) (CAR SOME-CONS) ...)\n" | ||
| 13 | "\n" | ||
| 14 | "For symmetry with CAR, CDR returns a second value which is the CAR of\n" | ||
| 15 | "the object. In a related change, the functions MAKE-ARRAY and CONS\n" | ||
| 16 | "have been fixed so they don't allocate any storage except on the\n" | ||
| 17 | "stack. This should hopefully help people who don't like using the\n" | ||
| 18 | "garbage collector because it cold boots the machine so often.\n" | ||
| 19 | }; | ||
diff --git a/pintos-progos/tests/vm/sample.txt b/pintos-progos/tests/vm/sample.txt new file mode 100644 index 0000000..c446830 --- /dev/null +++ b/pintos-progos/tests/vm/sample.txt | |||
| @@ -0,0 +1,17 @@ | |||
| 1 | === ALL USERS PLEASE NOTE ======================== | ||
| 2 | |||
| 3 | CAR and CDR now return extra values. | ||
| 4 | |||
| 5 | The function CAR now returns two values. Since it has to go to the | ||
| 6 | trouble to figure out if the object is carcdr-able anyway, we figured | ||
| 7 | you might as well get both halves at once. For example, the following | ||
| 8 | code shows how to destructure a cons (SOME-CONS) into its two slots | ||
| 9 | (THE-CAR and THE-CDR): | ||
| 10 | |||
| 11 | (MULTIPLE-VALUE-BIND (THE-CAR THE-CDR) (CAR SOME-CONS) ...) | ||
| 12 | |||
| 13 | For symmetry with CAR, CDR returns a second value which is the CAR of | ||
| 14 | the object. In a related change, the functions MAKE-ARRAY and CONS | ||
| 15 | have been fixed so they don't allocate any storage except on the | ||
| 16 | stack. This should hopefully help people who don't like using the | ||
| 17 | garbage collector because it cold boots the machine so often. | ||
