X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=grading%2Ffilesys%2Ffslib.c;h=2087d074b379949a18ff3a60030c7fe018875e34;hb=5780c9f434cca090f88463b7f0199d49b4ded288;hp=a94a0d1bb8e8405d13a16489a3e4dfa1f3b308d2;hpb=0f5c19ccf179b35b39ae46dffec60592baeeec00;p=pintos-anon diff --git a/grading/filesys/fslib.c b/grading/filesys/fslib.c index a94a0d1..2087d07 100644 --- a/grading/filesys/fslib.c +++ b/grading/filesys/fslib.c @@ -8,10 +8,19 @@ bool quiet = false; static void -vmsg (const char *format, va_list args) +vmsg (const char *format, va_list args, const char *suffix) { - printf ("(%s) ", test_name); - vprintf (format, args); + /* We go to some trouble to stuff the entire message into a + single buffer and output it in a single system call, because + that'll (typically) ensure that it gets sent to the console + atomically. Otherwise kernel messages like "foo: exit(0)" + can end up being interleaved if we're unlucky. */ + static char buf[1024]; + + snprintf (buf, sizeof buf, "(%s) ", test_name); + vsnprintf (buf + strlen (buf), sizeof buf - strlen (buf), format, args); + strlcpy (buf + strlen (buf), suffix, sizeof buf - strlen (buf)); + write (STDOUT_FILENO, buf, strlen (buf)); } void @@ -22,8 +31,7 @@ msg (const char *format, ...) if (quiet) return; va_start (args, format); - vmsg (format, args); - printf ("\n"); + vmsg (format, args, "\n"); va_end (args); } @@ -33,36 +41,12 @@ fail (const char *format, ...) va_list args; va_start (args, format); - vmsg (format, args); - printf (": FAILED\n"); + vmsg (format, args, ": FAILED\n"); va_end (args); exit (1); } -void -check (bool success, const char *format, ...) -{ - va_list args; - - va_start (args, format); - if (success) - { - if (!quiet) - { - vmsg (format, args); - printf ("\n"); - } - } - else - { - vmsg (format, args); - printf (": FAILED\n"); - exit (1); - } - va_end (args); -} - void seq_test (const char *filename, void *buf, size_t size, size_t initial_size, size_t (*block_size_func) (void), @@ -72,8 +56,8 @@ seq_test (const char *filename, void *buf, size_t size, size_t initial_size, int fd; random_bytes (buf, size); - check (create (filename, initial_size), "create \"%s\"", filename); - check ((fd = open (filename)) > 1, "open \"%s\"", filename); + CHECK (create (filename, initial_size), "create \"%s\"", filename); + CHECK ((fd = open (filename)) > 1, "open \"%s\"", filename); ofs = 0; msg ("writing \"%s\"", filename); @@ -132,7 +116,7 @@ check_file (const char *filename, const void *buf_, size_t size) char block[512]; int fd; - check ((fd = open (filename)) > 1, "open \"%s\" for verification", filename); + CHECK ((fd = open (filename)) > 1, "open \"%s\" for verification", filename); ofs = 0; while (ofs < size) @@ -145,22 +129,74 @@ check_file (const char *filename, const void *buf_, size_t size) fail ("read %zu bytes at offset %zu in \"%s\" failed", block_size, ofs, filename); - if (memcmp (buf + ofs, block, block_size)) - { - if (block_size <= 512) - { - printf ("Expected data:\n"); - hex_dump (ofs, buf + ofs, block_size, false); - printf ("Actually read data:\n"); - hex_dump (ofs, block, block_size, false); - } - fail ("%zu bytes at offset %zu differed from expected", - block_size, ofs); - } - + compare_bytes (block, buf + ofs, block_size, ofs, filename); ofs += block_size; } msg ("close \"%s\"", filename); close (fd); } + +void +compare_bytes (const void *read_data_, const void *expected_data_, size_t size, + size_t ofs, const char *filename) +{ + const uint8_t *read_data = read_data_; + const uint8_t *expected_data = expected_data_; + size_t i, j; + size_t show_cnt; + + if (!memcmp (read_data, expected_data, size)) + return; + + for (i = 0; i < size; i++) + if (read_data[i] != expected_data[i]) + break; + for (j = i + 1; j < size; j++) + if (read_data[j] == expected_data[j]) + break; + + quiet = false; + msg ("%zu bytes read starting at offset %zu in \"%s\" differ " + "from expected.", j - i, ofs + i, filename); + show_cnt = j - i; + if (j - i > 64) + { + show_cnt = 64; + msg ("Showing first differing %zu bytes.", show_cnt); + } + msg ("Data actually read:"); + hex_dump (ofs + i, read_data + i, show_cnt, true); + msg ("Expected data:"); + hex_dump (ofs + i, expected_data + i, show_cnt, true); + fail ("%zu bytes read starting at offset %zu in \"%s\" differ " + "from expected", j - i, ofs, filename); +} + +void +exec_children (const char *child_name, pid_t pids[], size_t child_cnt) +{ + size_t i; + + for (i = 0; i < child_cnt; i++) + { + char cmd_line[128]; + snprintf (cmd_line, sizeof cmd_line, "%s %zu", child_name, i); + CHECK ((pids[i] = exec (cmd_line)) != PID_ERROR, + "exec child %zu of %zu: \"%s\"", i + 1, child_cnt, cmd_line); + } +} + +void +wait_children (pid_t pids[], size_t child_cnt) +{ + size_t i; + + for (i = 0; i < child_cnt; i++) + { + int status = wait (pids[i]); + CHECK (status == (int) i, + "wait for child %zu of %zu returned %d (expected %zu)", + i + 1, child_cnt, status, i); + } +}