From ac1525683728d7b3ab644e729e6658d435914d85 Mon Sep 17 00:00:00 2001 From: manuel Date: Fri, 11 May 2012 15:10:44 +0200 Subject: add new test for priority donation with conditions --- tests/threads/priority-donate-condvar.c | 97 +++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 tests/threads/priority-donate-condvar.c (limited to 'tests/threads/priority-donate-condvar.c') diff --git a/tests/threads/priority-donate-condvar.c b/tests/threads/priority-donate-condvar.c new file mode 100644 index 0000000..321a58a --- /dev/null +++ b/tests/threads/priority-donate-condvar.c @@ -0,0 +1,97 @@ +/* Basically that's the same test as priority-donate-sema but using + conditions instead of semaphores. + + Low priority thread L acquires a lock, then blocks waiting for + the condition. Medium priority thread M then blocks waiting for + the same condition. Next, high priority thread H attempts to + acquire the lock, donating its priority to L. + + Next, the main thread signals the condition, waking up L. L + releases the lock, which wakes up H. H signals the condition, + waking up M. H terminates, then M, then L, and finally the + main thread. + + Written by Manuel Mausz . */ + +#include +#include "tests/threads/tests.h" +#include "threads/init.h" +#include "threads/synch.h" +#include "threads/thread.h" + +struct lock_and_cond + { + struct lock lock; + struct lock lockc; + struct condition cond; + }; + +static thread_func l_thread_func; +static thread_func m_thread_func; +static thread_func h_thread_func; + +void +test_priority_donate_condvar (void) +{ + struct lock_and_cond ls; + + /* This test does not work with the MLFQS. */ + ASSERT (!thread_mlfqs); + + /* Make sure our priority is the default. */ + ASSERT (thread_get_priority () == PRI_DEFAULT); + + lock_init (&ls.lock); + lock_init (&ls.lockc); + cond_init (&ls.cond); + thread_create ("low", PRI_DEFAULT + 1, l_thread_func, &ls); + thread_create ("med", PRI_DEFAULT + 3, m_thread_func, &ls); + thread_create ("high", PRI_DEFAULT + 5, h_thread_func, &ls); + lock_acquire (&ls.lockc); + msg ("Signaling..."); + cond_signal (&ls.cond, &ls.lockc); + lock_release (&ls.lockc); + msg ("Main thread finished."); +} + +static void +l_thread_func (void *ls_) +{ + struct lock_and_cond *ls = ls_; + + lock_acquire (&ls->lock); + msg ("Thread L acquired lock."); + lock_acquire (&ls->lockc); + cond_wait (&ls->cond, &ls->lockc); + lock_release (&ls->lockc); + msg ("Thread L woke up."); + lock_release (&ls->lock); + msg ("Thread L finished."); +} + +static void +m_thread_func (void *ls_) +{ + struct lock_and_cond *ls = ls_; + + lock_acquire (&ls->lockc); + cond_wait (&ls->cond, &ls->lockc); + lock_release (&ls->lockc); + msg ("Thread M finished."); +} + +static void +h_thread_func (void *ls_) +{ + struct lock_and_cond *ls = ls_; + + lock_acquire (&ls->lock); + msg ("Thread H acquired lock."); + + lock_acquire (&ls->lockc); + msg ("Signaling..."); + cond_signal (&ls->cond, &ls->lockc); + lock_release (&ls->lockc); + lock_release (&ls->lock); + msg ("Thread H finished."); +} -- cgit v1.2.3