/* [<][>][^][v][top][bottom][index][help] */
1 /*
2 * Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
3 * The President and Fellows of Harvard College.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the University nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30 #ifndef _SYNCH_H_
31 #define _SYNCH_H_
32
33 /*
34 * Header file for synchronization primitives.
35 */
36
37
38 #include <spinlock.h>
39
40 /*
41 * Dijkstra-style semaphore.
42 *
43 * The name field is for easier debugging. A copy of the name is made
44 * internally.
45 */
46 struct semaphore {
47 char *sem_name;
48 struct wchan *sem_wchan;
49 struct spinlock sem_lock;
50 volatile int sem_count;
51 };
52
53 struct semaphore *sem_create(const char *name, int initial_count);
54 void sem_destroy(struct semaphore *);
55
56 /*
57 * Operations (both atomic):
58 * P (proberen): decrement count. If the count is 0, block until
59 * the count is 1 again before decrementing.
60 * V (verhogen): increment count.
61 */
62 void P(struct semaphore *);
63 void V(struct semaphore *);
64
65
66 /*
67 * Simple lock for mutual exclusion.
68 *
69 * When the lock is created, no thread should be holding it. Likewise,
70 * when the lock is destroyed, no thread should be holding it.
71 *
72 * The name field is for easier debugging. A copy of the name is
73 * (should be) made internally.
74 */
75 struct lock {
76 char *lk_name;
77 // add what you need here
78 // (don't forget to mark things volatile as needed)
79 };
80
81 struct lock *lock_create(const char *name);
82 void lock_acquire(struct lock *);
83
84 /*
85 * Operations:
86 * lock_acquire - Get the lock. Only one thread can hold the lock at the
87 * same time.
88 * lock_release - Free the lock. Only the thread holding the lock may do
89 * this.
90 * lock_do_i_hold - Return true if the current thread holds the lock;
91 * false otherwise.
92 *
93 * These operations must be atomic. You get to write them.
94 */
95 void lock_release(struct lock *);
96 bool lock_do_i_hold(struct lock *);
97 void lock_destroy(struct lock *);
98
99
100 /*
101 * Condition variable.
102 *
103 * Note that the "variable" is a bit of a misnomer: a CV is normally used
104 * to wait until a variable meets a particular condition, but there's no
105 * actual variable, as such, in the CV.
106 *
107 * These CVs are expected to support Mesa semantics, that is, no
108 * guarantees are made about scheduling.
109 *
110 * The name field is for easier debugging. A copy of the name is
111 * (should be) made internally.
112 */
113
114 struct cv {
115 char *cv_name;
116 // add what you need here
117 // (don't forget to mark things volatile as needed)
118 };
119
120 struct cv *cv_create(const char *name);
121 void cv_destroy(struct cv *);
122
123 /*
124 * Operations:
125 * cv_wait - Release the supplied lock, go to sleep, and, after
126 * waking up again, re-acquire the lock.
127 * cv_signal - Wake up one thread that's sleeping on this CV.
128 * cv_broadcast - Wake up all threads sleeping on this CV.
129 *
130 * For all three operations, the current thread must hold the lock passed
131 * in. Note that under normal circumstances the same lock should be used
132 * on all operations with any particular CV.
133 *
134 * These operations must be atomic. You get to write them.
135 */
136 void cv_wait(struct cv *cv, struct lock *lock);
137 void cv_signal(struct cv *cv, struct lock *lock);
138 void cv_broadcast(struct cv *cv, struct lock *lock);
139
140
141 #endif /* _SYNCH_H_ */