82 lines
1.9 KiB
C
Executable file
82 lines
1.9 KiB
C
Executable file
/* 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.");
|
|
}
|