CS318 - Pintos
Pintos source browser for JHU CS318 course
priority-donate-nest.c
Go to the documentation of this file.
1 /** Low-priority main thread L acquires lock A. Medium-priority
2  thread M then acquires lock B then blocks on acquiring lock A.
3  High-priority thread H then blocks on acquiring lock B. Thus,
4  thread H donates its priority to M, which in turn donates it
5  to thread L.
6 
7  Based on a test originally submitted for Stanford's CS 140 in
8  winter 1999 by Matt Franklin <startled@leland.stanford.edu>,
9  Greg Hutchins <gmh@leland.stanford.edu>, Yu Ping Hu
10  <yph@cs.stanford.edu>. Modified by arens. */
11 
12 #include <stdio.h>
13 #include "tests/threads/tests.h"
14 #include "threads/init.h"
15 #include "threads/synch.h"
16 #include "threads/thread.h"
17 
18 struct locks
19  {
20  struct lock *a;
21  struct lock *b;
22  };
23 
26 
27 void
29 {
30  struct lock a, b;
31  struct locks locks;
32 
33  /* This test does not work with the MLFQS. */
35 
36  /* Make sure our priority is the default. */
38 
39  lock_init (&a);
40  lock_init (&b);
41 
42  lock_acquire (&a);
43 
44  locks.a = &a;
45  locks.b = &b;
47  thread_yield ();
48  msg ("Low thread should have priority %d. Actual priority: %d.",
50 
52  thread_yield ();
53  msg ("Low thread should have priority %d. Actual priority: %d.",
55 
56  lock_release (&a);
57  thread_yield ();
58  msg ("Medium thread should just have finished.");
59  msg ("Low thread should have priority %d. Actual priority: %d.",
61 }
62 
63 static void
64 medium_thread_func (void *locks_)
65 {
66  struct locks *locks = locks_;
67 
68  lock_acquire (locks->b);
69  lock_acquire (locks->a);
70 
71  msg ("Medium thread should have priority %d. Actual priority: %d.",
73  msg ("Medium thread got the lock.");
74 
75  lock_release (locks->a);
76  thread_yield ();
77 
78  lock_release (locks->b);
79  thread_yield ();
80 
81  msg ("High thread should have just finished.");
82  msg ("Middle thread finished.");
83 }
84 
85 static void
86 high_thread_func (void *lock_)
87 {
88  struct lock *lock = lock_;
89 
91  msg ("High thread got the lock.");
93  msg ("High thread finished.");
94 }
lock_release
void lock_release(struct lock *lock)
Releases LOCK, which must be owned by the current thread.
Definition: synch.c:229
locks::b
struct lock * b
Definition: priority-donate-nest.c:21
lock_init
void lock_init(struct lock *lock)
Initializes LOCK.
Definition: synch.c:176
test_priority_donate_nest
void test_priority_donate_nest(void)
Definition: priority-donate-nest.c:28
thread_get_priority
int thread_get_priority(void)
Returns the current thread's priority.
Definition: thread.c:343
init.h
high_thread_func
static thread_func high_thread_func
Definition: priority-donate-nest.c:25
ASSERT
#define ASSERT(CONDITION)
This is outside the header guard so that debug.h may be included multiple times with different settin...
Definition: debug.h:31
medium_thread_func
static thread_func medium_thread_func
Definition: priority-donate-nest.c:24
locks
Low-priority main thread L acquires lock A.
Definition: priority-donate-nest.c:18
msg
void msg(const char *format,...)
Definition: lib.c:28
thread_mlfqs
bool thread_mlfqs
If false (default), use round-robin scheduler.
Definition: thread.c:60
thread_create
tid_t thread_create(const char *name, int priority, thread_func *function, void *aux)
Creates a new kernel thread named NAME with the given initial PRIORITY, which executes FUNCTION passi...
Definition: thread.c:166
tests.h
thread_func
void thread_func(void *aux)
Definition: thread.h:116
lock_acquire
void lock_acquire(struct lock *lock)
Acquires LOCK, sleeping until it becomes available if necessary.
Definition: synch.c:193
locks::a
struct lock * a
Definition: priority-donate-nest.c:20
thread.h
synch.h
thread_yield
void thread_yield(void)
Yields the CPU.
Definition: thread.c:302
lock
Lock.
Definition: synch.h:21
PRI_DEFAULT
#define PRI_DEFAULT
Default priority.
Definition: thread.h:24