83 lines
1.9 KiB
C
83 lines
1.9 KiB
C
|
/* Low priority thread L acquires a lock, then blocks downing a
|
||
|
semaphore. Medium priority thread M then blocks waiting on
|
||
|
the same semaphore. Next, high priority thread H attempts to
|
||
|
acquire the lock, donating its priority to L.
|
||
|
|
||
|
Next, the main thread ups the semaphore, waking up L. L
|
||
|
releases the lock, which wakes up H. H "up"s the semaphore,
|
||
|
waking up M. H terminates, then M, then L, and finally the
|
||
|
main thread.
|
||
|
|
||
|
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"
|
||
|
|
||
|
struct lock_and_sema
|
||
|
{
|
||
|
struct lock lock;
|
||
|
struct semaphore sema;
|
||
|
};
|
||
|
|
||
|
static thread_func l_thread_func;
|
||
|
static thread_func m_thread_func;
|
||
|
static thread_func h_thread_func;
|
||
|
|
||
|
void
|
||
|
test_priority_donate_sema (void)
|
||
|
{
|
||
|
struct lock_and_sema 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);
|
||
|
sema_init (&ls.sema, 0);
|
||
|
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);
|
||
|
sema_up (&ls.sema);
|
||
|
msg ("Main thread finished.");
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
l_thread_func (void *ls_)
|
||
|
{
|
||
|
struct lock_and_sema *ls = ls_;
|
||
|
|
||
|
lock_acquire (&ls->lock);
|
||
|
msg ("Thread L acquired lock.");
|
||
|
sema_down (&ls->sema);
|
||
|
msg ("Thread L downed semaphore.");
|
||
|
lock_release (&ls->lock);
|
||
|
msg ("Thread L finished.");
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
m_thread_func (void *ls_)
|
||
|
{
|
||
|
struct lock_and_sema *ls = ls_;
|
||
|
|
||
|
sema_down (&ls->sema);
|
||
|
msg ("Thread M finished.");
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
h_thread_func (void *ls_)
|
||
|
{
|
||
|
struct lock_and_sema *ls = ls_;
|
||
|
|
||
|
lock_acquire (&ls->lock);
|
||
|
msg ("Thread H acquired lock.");
|
||
|
|
||
|
sema_up (&ls->sema);
|
||
|
lock_release (&ls->lock);
|
||
|
msg ("Thread H finished.");
|
||
|
}
|