- added priority-donate-chain test which tests 8-level deep nested donation
authorGodmar Back <godmar@gmail.com>
Sat, 6 Jan 2007 19:00:52 +0000 (19:00 +0000)
committerGodmar Back <godmar@gmail.com>
Sat, 6 Jan 2007 19:00:52 +0000 (19:00 +0000)
- adjusted weights for P1 Grading file

src/tests/threads/Grading
src/tests/threads/Make.tests
src/tests/threads/Rubric.priority
src/tests/threads/priority-donate-chain.c [new file with mode: 0644]
src/tests/threads/priority-donate-chain.ck [new file with mode: 0644]
src/tests/threads/tests.c
src/tests/threads/tests.h

index 88a4923b72c16a86013b4ae7904e7c70e31df4af..c9be35f379dfc8241b489eb28966617629cdbd76 100644 (file)
@@ -1,6 +1,6 @@
 # Percentage of the testing point total designated for each set of
 # tests.
 
-33.3%  tests/threads/Rubric.alarm
-33.3%  tests/threads/Rubric.priority
-33.4%  tests/threads/Rubric.mlfqs
+20.0%  tests/threads/Rubric.alarm
+40.0%  tests/threads/Rubric.priority
+40.0%  tests/threads/Rubric.mlfqs
index 0a270e20e8885a79c242da362934a20b9dfd49f1..456903538990dedcdc15bfef32dc6e0112033ef1 100644 (file)
@@ -7,6 +7,7 @@ alarm-negative priority-change priority-donate-one                      \
 priority-donate-multiple priority-donate-multiple2                     \
 priority-donate-nest priority-donate-sema priority-donate-lower                \
 priority-fifo priority-preempt priority-sema priority-condvar          \
+priority-donate-chain                                                   \
 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-block)
 
@@ -28,6 +29,7 @@ tests/threads_SRC += tests/threads/priority-fifo.c
 tests/threads_SRC += tests/threads/priority-preempt.c
 tests/threads_SRC += tests/threads/priority-sema.c
 tests/threads_SRC += tests/threads/priority-condvar.c
+tests/threads_SRC += tests/threads/priority-donate-chain.c
 tests/threads_SRC += tests/threads/mlfqs-load-1.c
 tests/threads_SRC += tests/threads/mlfqs-load-60.c
 tests/threads_SRC += tests/threads/mlfqs-load-avg.c
index e8ee82ce1919b96350ec1a261247377c8abb9f19..652bc99eff1f34d1c40e34259af31291d4069d85 100644 (file)
@@ -1,13 +1,15 @@
 Functionality of priority scheduler:
+3      priority-change
 3      priority-preempt
+
+3      priority-fifo
+3      priority-sema
+3      priority-condvar
+
 3      priority-donate-one
 3      priority-donate-multiple
 3      priority-donate-multiple2
 3      priority-donate-nest
+5      priority-donate-chain
 3      priority-donate-sema
 3      priority-donate-lower
-3      priority-change
-
-3      priority-fifo
-3      priority-sema
-3      priority-condvar
diff --git a/src/tests/threads/priority-donate-chain.c b/src/tests/threads/priority-donate-chain.c
new file mode 100644 (file)
index 0000000..3ffabca
--- /dev/null
@@ -0,0 +1,114 @@
+/* The main thread set its priority to PRI_MIN and creates 7 threads 
+   (thread 1..7) with priorities PRI_MIN + 3, 6, 9, 12, ...
+   The main thread initializes 8 locks: lock 0..7 and acquires lock 0.
+
+   When thread[i] starts, it first acquires lock[i] (unless i == 7.)
+   Subsequently, thread[i] attempts to acquire lock[i-1], which is held by
+   thread[i-1], except for lock[0], which is held by the main thread.
+   Because the lock is held, thread[i] donates its priority to thread[i-1],
+   which donates to thread[i-2], and so on until the main thread
+   receives the donation.
+
+   After threads[1..7] have been created and are blocked on locks[0..7],
+   the main thread releases lock[0], unblocking thread[1], and being
+   preempted by it.
+   Thread[1] then completes acquiring lock[0], then releases lock[0],
+   then releases lock[1], unblocking thread[2], etc.
+   Thread[7] finally acquires & releases lock[7] and exits, allowing 
+   thread[6], then thread[5] etc. to run and exit until finally the 
+   main thread exits.
+
+   In addition, interloper threads are created at priority levels
+   p = PRI_MIN + 2, 5, 8, 11, ... which should not be run until the 
+   corresponding thread with priority p + 1 has finished.
+  
+   Written by Godmar Back <gback@cs.vt.edu> */ 
+
+#include <stdio.h>
+#include "tests/threads/tests.h"
+#include "threads/init.h"
+#include "threads/synch.h"
+#include "threads/thread.h"
+
+#define NESTING_DEPTH 8
+
+struct lock_pair
+  {
+    struct lock *second;
+    struct lock *first;
+  };
+
+static thread_func donor_thread_func;
+static thread_func interloper_thread_func;
+
+void
+test_priority_donate_chain (void) 
+{
+  int i;  
+  struct lock locks[NESTING_DEPTH - 1];
+  struct lock_pair lock_pairs[NESTING_DEPTH];
+
+  /* This test does not work with the MLFQS. */
+  ASSERT (!thread_mlfqs);
+
+  thread_set_priority (PRI_MIN);
+
+  for (i = 0; i < NESTING_DEPTH - 1; i++)
+    lock_init (&locks[i]);
+
+  lock_acquire (&locks[0]);
+  msg ("%s got lock.", thread_name ());
+
+  for (i = 1; i < NESTING_DEPTH; i++)
+    {
+      char name[16];
+      int thread_priority;
+
+      snprintf (name, sizeof name, "thread %d", i);
+      thread_priority = PRI_MIN + i * 3;
+      lock_pairs[i].first = i < NESTING_DEPTH - 1 ? locks + i: NULL;
+      lock_pairs[i].second = locks + i - 1;
+
+      thread_create (name, thread_priority, donor_thread_func, lock_pairs + i);
+      msg ("%s should have priority %d.  Actual priority: %d.",
+          thread_name (), thread_priority, thread_get_priority ());
+
+      snprintf (name, sizeof name, "interloper %d", i);
+      thread_create (name, thread_priority - 1, interloper_thread_func, NULL);
+    }
+
+  lock_release (&locks[0]);
+  msg ("%s finishing with priority %d.", thread_name (),
+                                         thread_get_priority ());
+}
+
+static void
+donor_thread_func (void *locks_) 
+{
+  struct lock_pair *locks = locks_;
+
+  if (locks->first)
+    lock_acquire (locks->first);
+
+  lock_acquire (locks->second);
+  msg ("%s got lock", thread_name ());
+
+  lock_release (locks->second);
+  msg ("%s should have priority %d. Actual priority: %d", 
+        thread_name (), (NESTING_DEPTH - 1) * 3,
+        thread_get_priority ());
+
+  if (locks->first)
+    lock_release (locks->first);
+
+  msg ("%s finishing with priority %d.", thread_name (),
+                                         thread_get_priority ());
+}
+
+static void
+interloper_thread_func (void *arg_ UNUSED)
+{
+  msg ("%s finished.", thread_name ());
+}
+
+// vim: sw=2
diff --git a/src/tests/threads/priority-donate-chain.ck b/src/tests/threads/priority-donate-chain.ck
new file mode 100644 (file)
index 0000000..213e649
--- /dev/null
@@ -0,0 +1,46 @@
+# -*- perl -*-
+use strict;
+use warnings;
+use tests::tests;
+check_expected ([<<'EOF']);
+(priority-donate-chain) begin
+(priority-donate-chain) main got lock.
+(priority-donate-chain) main should have priority 3.  Actual priority: 3.
+(priority-donate-chain) main should have priority 6.  Actual priority: 6.
+(priority-donate-chain) main should have priority 9.  Actual priority: 9.
+(priority-donate-chain) main should have priority 12.  Actual priority: 12.
+(priority-donate-chain) main should have priority 15.  Actual priority: 15.
+(priority-donate-chain) main should have priority 18.  Actual priority: 18.
+(priority-donate-chain) main should have priority 21.  Actual priority: 21.
+(priority-donate-chain) thread 1 got lock
+(priority-donate-chain) thread 1 should have priority 21. Actual priority: 21
+(priority-donate-chain) thread 2 got lock
+(priority-donate-chain) thread 2 should have priority 21. Actual priority: 21
+(priority-donate-chain) thread 3 got lock
+(priority-donate-chain) thread 3 should have priority 21. Actual priority: 21
+(priority-donate-chain) thread 4 got lock
+(priority-donate-chain) thread 4 should have priority 21. Actual priority: 21
+(priority-donate-chain) thread 5 got lock
+(priority-donate-chain) thread 5 should have priority 21. Actual priority: 21
+(priority-donate-chain) thread 6 got lock
+(priority-donate-chain) thread 6 should have priority 21. Actual priority: 21
+(priority-donate-chain) thread 7 got lock
+(priority-donate-chain) thread 7 should have priority 21. Actual priority: 21
+(priority-donate-chain) thread 7 finishing with priority 21.
+(priority-donate-chain) interloper 7 finished.
+(priority-donate-chain) thread 6 finishing with priority 18.
+(priority-donate-chain) interloper 6 finished.
+(priority-donate-chain) thread 5 finishing with priority 15.
+(priority-donate-chain) interloper 5 finished.
+(priority-donate-chain) thread 4 finishing with priority 12.
+(priority-donate-chain) interloper 4 finished.
+(priority-donate-chain) thread 3 finishing with priority 9.
+(priority-donate-chain) interloper 3 finished.
+(priority-donate-chain) thread 2 finishing with priority 6.
+(priority-donate-chain) interloper 2 finished.
+(priority-donate-chain) thread 1 finishing with priority 3.
+(priority-donate-chain) interloper 1 finished.
+(priority-donate-chain) main finishing with priority 0.
+(priority-donate-chain) end
+EOF
+pass;
index 3f0327f9f277c588db820f736e7eb5b6d7192edd..af15aee1e4a0c4911acb750ddd586659d402285b 100644 (file)
@@ -24,6 +24,7 @@ static const struct test tests[] =
     {"priority-donate-nest", test_priority_donate_nest},
     {"priority-donate-sema", test_priority_donate_sema},
     {"priority-donate-lower", test_priority_donate_lower},
+    {"priority-donate-chain", test_priority_donate_chain},
     {"priority-fifo", test_priority_fifo},
     {"priority-preempt", test_priority_preempt},
     {"priority-sema", test_priority_sema},
index 81e966315553126616f9a71a22d73a59a756bd81..cd9d4895409fbb0f5f36533c4a5e8af8c3fbafad 100644 (file)
@@ -18,6 +18,7 @@ extern test_func test_priority_donate_multiple2;
 extern test_func test_priority_donate_sema;
 extern test_func test_priority_donate_nest;
 extern test_func test_priority_donate_lower;
+extern test_func test_priority_donate_chain;
 extern test_func test_priority_fifo;
 extern test_func test_priority_preempt;
 extern test_func test_priority_sema;