From 781c2687a8e8835ad34d7e472a80959a0d28c03a Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Thu, 18 May 2006 19:37:03 +0000 Subject: [PATCH] Test interaction between priority donation and thread_set_priority(). Suggestion from Godmar Back. --- TODO | 18 -------- doc/threads.texi | 8 ++-- src/tests/threads/Make.tests | 9 ++-- src/tests/threads/priority-donate-lower.c | 51 ++++++++++++++++++++++ src/tests/threads/priority-donate-lower.ck | 15 +++++++ src/tests/threads/tests.c | 1 + src/tests/threads/tests.h | 1 + 7 files changed, 78 insertions(+), 25 deletions(-) create mode 100644 src/tests/threads/priority-donate-lower.c create mode 100644 src/tests/threads/priority-donate-lower.ck diff --git a/TODO b/TODO index ccc9362..080eb60 100644 --- a/TODO +++ b/TODO @@ -21,22 +21,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" -Subject: set_priority & donation - a TODO item -To: "Ben Pfaff" -Date: Mon, 20 Feb 2006 22:20:26 -0500 - -Ben, - -it seems that there are currently no tests that check the proper -behavior of thread_set_priority() when called by a thread that is -running under priority donation. The proper behavior, I assume, is to -temporarily drop the donation if the set priority is higher, and to -reassume the donation should the thread subsequently set its own -priority again to a level that's lower than a still active donation. - - - Godmar - From: Godmar Back Subject: on caching in project 4 To: Ben Pfaff @@ -111,8 +95,6 @@ via Godmar Back: - Add extra credit: - . Low-level x86 stuff, like paged page tables. - . Specifics on how to implement sbrk, malloc. . Other good ideas. diff --git a/doc/threads.texi b/doc/threads.texi index f5e6058..eeb17ee 100644 --- a/doc/threads.texi +++ b/doc/threads.texi @@ -714,9 +714,11 @@ preempting whatever thread is currently running. @item How does @func{thread_set_priority} affect a thread receiving donations? -It should do something sensible, but no particular behavior is -required. None of the test cases call @func{thread_set_priority} from a -thread while it is receiving a priority donation. +It sets the thread's base priority. The thread's effective priority +becomes the higher of the newly set priority or the highest donated +priority. When the donations are released, the thread's priority +becomes the one set through the function call. This behavior is checked +by the @code{priority-donate-lower} test. @item Calling @func{printf} in @func{sema_up} or @func{sema_down} reboots! diff --git a/src/tests/threads/Make.tests b/src/tests/threads/Make.tests index 3b6bfd7..f1e239e 100644 --- a/src/tests/threads/Make.tests +++ b/src/tests/threads/Make.tests @@ -5,10 +5,10 @@ tests/threads_TESTS = $(addprefix tests/threads/,alarm-single \ alarm-multiple alarm-simultaneous alarm-priority alarm-zero \ alarm-negative priority-change priority-donate-one \ 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-block) +priority-donate-nest priority-donate-sema priority-donate-lower \ +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-block) # Sources for tests. tests/threads_SRC = tests/threads/tests.c @@ -23,6 +23,7 @@ tests/threads_SRC += tests/threads/priority-donate-multiple.c tests/threads_SRC += tests/threads/priority-donate-multiple2.c tests/threads_SRC += tests/threads/priority-donate-nest.c tests/threads_SRC += tests/threads/priority-donate-sema.c +tests/threads_SRC += tests/threads/priority-donate-lower.c tests/threads_SRC += tests/threads/priority-fifo.c tests/threads_SRC += tests/threads/priority-preempt.c tests/threads_SRC += tests/threads/priority-sema.c diff --git a/src/tests/threads/priority-donate-lower.c b/src/tests/threads/priority-donate-lower.c new file mode 100644 index 0000000..3f63db8 --- /dev/null +++ b/src/tests/threads/priority-donate-lower.c @@ -0,0 +1,51 @@ +/* The main thread acquires a lock. Then it creates a + higher-priority thread that blocks acquiring the lock, causing + it to donate their priorities to the main thread. The main + thread attempts to lower its priority, which should not take + effect until the donation is released. */ + +#include +#include "tests/threads/tests.h" +#include "threads/init.h" +#include "threads/synch.h" +#include "threads/thread.h" + +static thread_func acquire_thread_func; + +void +test_priority_donate_lower (void) +{ + struct lock lock; + + /* This test does not work with the MLFQS. */ + ASSERT (!enable_mlfqs); + + /* Make sure our priority is the default. */ + ASSERT (thread_get_priority () == PRI_DEFAULT); + + lock_init (&lock); + lock_acquire (&lock); + thread_create ("acquire", PRI_DEFAULT + 10, acquire_thread_func, &lock); + msg ("Main thread should have priority %d. Actual priority: %d.", + PRI_DEFAULT + 10, thread_get_priority ()); + + msg ("Lowering base priority..."); + thread_set_priority (PRI_DEFAULT - 10); + msg ("Main thread should have priority %d. Actual priority: %d.", + PRI_DEFAULT + 10, thread_get_priority ()); + lock_release (&lock); + msg ("acquire must already have finished."); + msg ("Main thread should have priority %d. Actual priority: %d.", + PRI_DEFAULT - 10, thread_get_priority ()); +} + +static void +acquire_thread_func (void *lock_) +{ + struct lock *lock = lock_; + + lock_acquire (lock); + msg ("acquire: got the lock"); + lock_release (lock); + msg ("acquire: done"); +} diff --git a/src/tests/threads/priority-donate-lower.ck b/src/tests/threads/priority-donate-lower.ck new file mode 100644 index 0000000..b009fd8 --- /dev/null +++ b/src/tests/threads/priority-donate-lower.ck @@ -0,0 +1,15 @@ +# -*- perl -*- +use strict; +use warnings; +use tests::tests; +check_expected ([<<'EOF']); +(priority-donate-lower) begin +(priority-donate-lower) Main thread should have priority 41. Actual priority: 41. +(priority-donate-lower) Lowering base priority... +(priority-donate-lower) Main thread should have priority 41. Actual priority: 41. +(priority-donate-lower) acquire: got the lock +(priority-donate-lower) acquire: done +(priority-donate-lower) acquire must already have finished. +(priority-donate-lower) Main thread should have priority 21. Actual priority: 21. +(priority-donate-lower) end +EOF diff --git a/src/tests/threads/tests.c b/src/tests/threads/tests.c index b515372..3f0327f 100644 --- a/src/tests/threads/tests.c +++ b/src/tests/threads/tests.c @@ -23,6 +23,7 @@ static const struct test tests[] = {"priority-donate-multiple2", test_priority_donate_multiple2}, {"priority-donate-nest", test_priority_donate_nest}, {"priority-donate-sema", test_priority_donate_sema}, + {"priority-donate-lower", test_priority_donate_lower}, {"priority-fifo", test_priority_fifo}, {"priority-preempt", test_priority_preempt}, {"priority-sema", test_priority_sema}, diff --git a/src/tests/threads/tests.h b/src/tests/threads/tests.h index 1fe839e..81e9663 100644 --- a/src/tests/threads/tests.h +++ b/src/tests/threads/tests.h @@ -17,6 +17,7 @@ extern test_func test_priority_donate_multiple; 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_fifo; extern test_func test_priority_preempt; extern test_func test_priority_sema; -- 2.30.2