diff options
Diffstat (limited to 'tests/threads/priority-donate-sema.c')
| -rw-r--r-- | tests/threads/priority-donate-sema.c | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/tests/threads/priority-donate-sema.c b/tests/threads/priority-donate-sema.c new file mode 100644 index 0000000..b33cb72 --- /dev/null +++ b/tests/threads/priority-donate-sema.c | |||
| @@ -0,0 +1,82 @@ | |||
| 1 | /* Low priority thread L acquires a lock, then blocks downing a | ||
| 2 | semaphore. Medium priority thread M then blocks waiting on | ||
| 3 | the same semaphore. Next, high priority thread H attempts to | ||
| 4 | acquire the lock, donating its priority to L. | ||
| 5 | |||
| 6 | Next, the main thread ups the semaphore, waking up L. L | ||
| 7 | releases the lock, which wakes up H. H "up"s the semaphore, | ||
| 8 | waking up M. H terminates, then M, then L, and finally the | ||
| 9 | main thread. | ||
| 10 | |||
| 11 | Written by Godmar Back <gback@cs.vt.edu>. */ | ||
| 12 | |||
| 13 | #include <stdio.h> | ||
| 14 | #include "tests/threads/tests.h" | ||
| 15 | #include "threads/init.h" | ||
| 16 | #include "threads/synch.h" | ||
| 17 | #include "threads/thread.h" | ||
| 18 | |||
| 19 | struct lock_and_sema | ||
| 20 | { | ||
| 21 | struct lock lock; | ||
| 22 | struct semaphore sema; | ||
| 23 | }; | ||
| 24 | |||
| 25 | static thread_func l_thread_func; | ||
| 26 | static thread_func m_thread_func; | ||
| 27 | static thread_func h_thread_func; | ||
| 28 | |||
| 29 | void | ||
| 30 | test_priority_donate_sema (void) | ||
| 31 | { | ||
| 32 | struct lock_and_sema ls; | ||
| 33 | |||
| 34 | /* This test does not work with the MLFQS. */ | ||
| 35 | ASSERT (!thread_mlfqs); | ||
| 36 | |||
| 37 | /* Make sure our priority is the default. */ | ||
| 38 | ASSERT (thread_get_priority () == PRI_DEFAULT); | ||
| 39 | |||
| 40 | lock_init (&ls.lock); | ||
| 41 | sema_init (&ls.sema, 0); | ||
| 42 | thread_create ("low", PRI_DEFAULT + 1, l_thread_func, &ls); | ||
| 43 | thread_create ("med", PRI_DEFAULT + 3, m_thread_func, &ls); | ||
| 44 | thread_create ("high", PRI_DEFAULT + 5, h_thread_func, &ls); | ||
| 45 | sema_up (&ls.sema); | ||
| 46 | msg ("Main thread finished."); | ||
| 47 | } | ||
| 48 | |||
| 49 | static void | ||
| 50 | l_thread_func (void *ls_) | ||
| 51 | { | ||
| 52 | struct lock_and_sema *ls = ls_; | ||
| 53 | |||
| 54 | lock_acquire (&ls->lock); | ||
| 55 | msg ("Thread L acquired lock."); | ||
| 56 | sema_down (&ls->sema); | ||
| 57 | msg ("Thread L downed semaphore."); | ||
| 58 | lock_release (&ls->lock); | ||
| 59 | msg ("Thread L finished."); | ||
| 60 | } | ||
| 61 | |||
| 62 | static void | ||
| 63 | m_thread_func (void *ls_) | ||
| 64 | { | ||
| 65 | struct lock_and_sema *ls = ls_; | ||
| 66 | |||
| 67 | sema_down (&ls->sema); | ||
| 68 | msg ("Thread M finished."); | ||
| 69 | } | ||
| 70 | |||
| 71 | static void | ||
| 72 | h_thread_func (void *ls_) | ||
| 73 | { | ||
| 74 | struct lock_and_sema *ls = ls_; | ||
| 75 | |||
| 76 | lock_acquire (&ls->lock); | ||
| 77 | msg ("Thread H acquired lock."); | ||
| 78 | |||
| 79 | sema_up (&ls->sema); | ||
| 80 | lock_release (&ls->lock); | ||
| 81 | msg ("Thread H finished."); | ||
| 82 | } | ||
