Add test that checks that recent_cpu decays properly for blocked
authorBen Pfaff <blp@cs.stanford.edu>
Thu, 18 May 2006 17:08:41 +0000 (17:08 +0000)
committerBen Pfaff <blp@cs.stanford.edu>
Thu, 18 May 2006 17:08:41 +0000 (17:08 +0000)
threads.
Suggested by Godmar Back.

TODO
src/tests/threads/Make.tests
src/tests/threads/Rubric.mlfqs
src/tests/threads/mlfqs-block.c [new file with mode: 0644]
src/tests/threads/mlfqs-block.ck [new file with mode: 0644]
src/tests/threads/tests.c
src/tests/threads/tests.h

diff --git a/TODO b/TODO
index 737f9af26227388ed3510825290a22f94bff7055..a4e3e31c080d3a2d5f0a004ec08f10e1d05bc540 100644 (file)
--- a/TODO
+++ b/TODO
@@ -26,22 +26,6 @@ Add a system call "get_kernel_memory_information".  User programs
 could engage in a variety of activities and notice leaks by checking
 the kernel memory statistics.
 
-From: "Godmar Back" <godmar@gmail.com>
-
-For reasons I don't currently understand, some of our students seem
-hesitant to include each thread in a second "all-threads" list and are
-looking for ways to implement the advanced scheduler without one.
-
-Currently, I believe, all tests for the mlfqs are such that all
-threads are either ready or sleeping in timer_sleep(). This allows for
-an incorrect implementation in which recent-cpu and priorities are
-updated only for those threads that are on the alarm list or the ready
-list.
-
-The todo item would be a test where a thread is blocked on a
-semaphore, lock or condition variable and have its recent_cpu decay to
-zero, and check that it's scheduled right after the unlock/up/signal.
-
 From: "Godmar Back" <godmar@gmail.com>
 Subject: set_priority & donation - a TODO item
 To: "Ben Pfaff" <blp@cs.stanford.edu>
index 0b6d532eddc103714a4ddeba437753e5fd296814..3b6bfd7cf9db0b49bd28ebf11244f2094e006a6f 100644 (file)
@@ -8,7 +8,7 @@ priority-donate-multiple priority-donate-multiple2                      \
 priority-donate-nest priority-donate-sema priority-fifo                        \
 priority-preempt priority-sema priority-condvar mlfqs-load-1           \
 mlfqs-load-60 mlfqs-load-avg mlfqs-recent-1 mlfqs-fair-2 mlfqs-fair-20 \
-mlfqs-nice-2 mlfqs-nice-10)
+mlfqs-nice-2 mlfqs-nice-10 mlfqs-block)
 
 # Sources for tests.
 tests/threads_SRC  = tests/threads/tests.c
@@ -32,6 +32,7 @@ tests/threads_SRC += tests/threads/mlfqs-load-60.c
 tests/threads_SRC += tests/threads/mlfqs-load-avg.c
 tests/threads_SRC += tests/threads/mlfqs-recent-1.c
 tests/threads_SRC += tests/threads/mlfqs-fair.c
+tests/threads_SRC += tests/threads/mlfqs-block.c
 
 MLFQS_OUTPUTS =                                \
 tests/threads/mlfqs-load-1.output              \
@@ -41,7 +42,8 @@ tests/threads/mlfqs-recent-1.output           \
 tests/threads/mlfqs-fair-2.output              \
 tests/threads/mlfqs-fair-20.output             \
 tests/threads/mlfqs-nice-2.output              \
-tests/threads/mlfqs-nice-10.output
+tests/threads/mlfqs-nice-10.output             \
+tests/threads/mlfqs-block.output
 
 $(MLFQS_OUTPUTS): KERNELFLAGS += -mlfqs
 $(MLFQS_OUTPUTS): TIMEOUT = 240
index b238a5746514a6b6d788e6407ec969115e91066d..f2600916205eccba338346f243b1c2eb9939bf71 100644 (file)
@@ -10,3 +10,5 @@ Functionality of advanced scheduler:
 
 4      mlfqs-nice-2
 2      mlfqs-nice-10
+
+5      mlfqs-block
diff --git a/src/tests/threads/mlfqs-block.c b/src/tests/threads/mlfqs-block.c
new file mode 100644 (file)
index 0000000..93ed5ec
--- /dev/null
@@ -0,0 +1,64 @@
+/* Checks that recent_cpu and priorities are updated for blocked
+   threads.
+
+   The main thread sleeps for 25 seconds, spins for 5 seconds,
+   then releases a lock.  The "block" thread spins for 20 seconds
+   then attempts to acquire the lock, which will block for 10
+   seconds (until the main thread releases it).  If recent_cpu
+   decays properly while the "block" thread sleeps, then the
+   block thread should be immediately scheduled when the main
+   thread releases the lock,. */
+
+#include <stdio.h>
+#include "tests/threads/tests.h"
+#include "threads/init.h"
+#include "threads/malloc.h"
+#include "threads/synch.h"
+#include "threads/thread.h"
+#include "devices/timer.h"
+
+static void block_thread (void *lock_);
+
+void
+test_mlfqs_block (void) 
+{
+  int64_t start_time;
+  struct lock lock;
+  
+  ASSERT (enable_mlfqs);
+
+  msg ("Main thread acquiring lock.");
+  lock_init (&lock);
+  lock_acquire (&lock);
+  
+  msg ("Main thread creating block thread, sleeping 25 seconds...");
+  thread_create ("block", PRI_DEFAULT, block_thread, &lock);
+  timer_sleep (25 * TIMER_FREQ);
+
+  msg ("Main thread spinning for 5 seconds...");
+  start_time = timer_ticks ();
+  while (timer_elapsed (start_time) < 5 * TIMER_FREQ)
+    continue;
+
+  msg ("Main thread releasing lock.");
+  lock_release (&lock);
+
+  msg ("Block thread should have already acquired lock.");
+}
+
+static void
+block_thread (void *lock_) 
+{
+  struct lock *lock = lock_;
+  int64_t start_time;
+
+  msg ("Block thread spinning for 20 seconds...");
+  start_time = timer_ticks ();
+  while (timer_elapsed (start_time) < 20 * TIMER_FREQ)
+    continue;
+
+  msg ("Block thread acquiring lock...");
+  lock_acquire (lock);
+
+  msg ("...got it.");
+}
diff --git a/src/tests/threads/mlfqs-block.ck b/src/tests/threads/mlfqs-block.ck
new file mode 100644 (file)
index 0000000..e3b883a
--- /dev/null
@@ -0,0 +1,16 @@
+# -*- perl -*-
+use strict;
+use warnings;
+use tests::tests;
+check_expected ([<<'EOF']);
+(mlfqs-block) begin
+(mlfqs-block) Main thread acquiring lock.
+(mlfqs-block) Main thread creating block thread, sleeping 25 seconds...
+(mlfqs-block) Block thread spinning for 20 seconds...
+(mlfqs-block) Block thread acquiring lock...
+(mlfqs-block) Main thread spinning for 5 seconds...
+(mlfqs-block) Main thread releasing lock.
+(mlfqs-block) ...got it.
+(mlfqs-block) Block thread should have already acquired lock.
+(mlfqs-block) end
+EOF
index ca99eb6624bde55cf2da798890ceaac9aaf71814..b5153728cc195b426699c237aedf9fccaf79abab 100644 (file)
@@ -35,6 +35,7 @@ static const struct test tests[] =
     {"mlfqs-fair-20", test_mlfqs_fair_20},
     {"mlfqs-nice-2", test_mlfqs_nice_2},
     {"mlfqs-nice-10", test_mlfqs_nice_10},
+    {"mlfqs-block", test_mlfqs_block},
   };
 
 static const char *test_name;
index ed9fbac28b0d69826ac9d2cdf4162eb5bb6ffd16..1fe839ea847ad16a69b5d01a51f7a7127b6a558b 100644 (file)
@@ -29,6 +29,7 @@ extern test_func test_mlfqs_fair_2;
 extern test_func test_mlfqs_fair_20;
 extern test_func test_mlfqs_nice_2;
 extern test_func test_mlfqs_nice_10;
+extern test_func test_mlfqs_block;
 
 void msg (const char *, ...);
 void fail (const char *, ...);