Rev 153 | Rev 413 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 153 | Rev 385 | ||
---|---|---|---|
Line 48... | Line 48... | ||
48 | * previously blocked on the exclusive mutex. Thus it is save |
48 | * previously blocked on the exclusive mutex. Thus it is save |
49 | * to store the rwlock type in the thread structure, because |
49 | * to store the rwlock type in the thread structure, because |
50 | * each thread can block on only one rwlock at a time. |
50 | * each thread can block on only one rwlock at a time. |
51 | */ |
51 | */ |
52 | 52 | ||
53 | #include <synch/synch.h> |
- | |
54 | #include <synch/rwlock.h> |
53 | #include <synch/rwlock.h> |
55 | #include <synch/spinlock.h> |
54 | #include <synch/spinlock.h> |
56 | #include <synch/mutex.h> |
55 | #include <synch/mutex.h> |
57 | #include <synch/waitq.h> |
56 | #include <synch/waitq.h> |
58 | - | ||
- | 57 | #include <synch/synch.h> |
|
59 | #include <list.h> |
58 | #include <list.h> |
60 | #include <typedefs.h> |
59 | #include <typedefs.h> |
61 | #include <arch/asm.h> |
60 | #include <arch/asm.h> |
62 | #include <arch.h> |
61 | #include <arch.h> |
63 | #include <proc/thread.h> |
62 | #include <proc/thread.h> |
Line 67... | Line 66... | ||
67 | #define ALLOW_READERS_ONLY 1 |
66 | #define ALLOW_READERS_ONLY 1 |
68 | 67 | ||
69 | static void let_others_in(rwlock_t *rwl, int readers_only); |
68 | static void let_others_in(rwlock_t *rwl, int readers_only); |
70 | static void release_spinlock(void *arg); |
69 | static void release_spinlock(void *arg); |
71 | 70 | ||
- | 71 | /** Initialize reader/writer lock |
|
- | 72 | * |
|
- | 73 | * Initialize reader/writer lock. |
|
- | 74 | * |
|
- | 75 | * @param rwl Reader/Writer lock. |
|
- | 76 | */ |
|
72 | void rwlock_initialize(rwlock_t *rwl) { |
77 | void rwlock_initialize(rwlock_t *rwl) { |
73 | spinlock_initialize(&rwl->lock); |
78 | spinlock_initialize(&rwl->lock); |
74 | mutex_initialize(&rwl->exclusive); |
79 | mutex_initialize(&rwl->exclusive); |
75 | rwl->readers_in = 0; |
80 | rwl->readers_in = 0; |
76 | } |
81 | } |
77 | 82 | ||
- | 83 | /** Acquire reader/writer lock for reading |
|
- | 84 | * |
|
- | 85 | * Acquire reader/writer lock for reading. |
|
- | 86 | * Timeout and willingness to block may be specified. |
|
- | 87 | * |
|
- | 88 | * @param rwl Reader/Writer lock. |
|
- | 89 | * @param usec Timeout in microseconds. |
|
- | 90 | * @param trylock Switches between blocking and non-blocking mode. |
|
- | 91 | * |
|
- | 92 | * For exact description of possible combinations of |
|
- | 93 | * 'usec' and 'trylock', see comment for waitq_sleep_timeout(). |
|
- | 94 | * |
|
- | 95 | * @return See comment for waitq_sleep_timeout(). |
|
- | 96 | */ |
|
78 | int _rwlock_write_lock_timeout(rwlock_t *rwl, __u32 usec, int trylock) |
97 | int _rwlock_write_lock_timeout(rwlock_t *rwl, __u32 usec, int trylock) |
79 | { |
98 | { |
80 | pri_t pri; |
99 | pri_t pri; |
81 | int rc; |
100 | int rc; |
82 | 101 | ||
Line 113... | Line 132... | ||
113 | } |
132 | } |
114 | 133 | ||
115 | return rc; |
134 | return rc; |
116 | } |
135 | } |
117 | 136 | ||
- | 137 | /** Acquire reader/writer lock for writing |
|
- | 138 | * |
|
- | 139 | * Acquire reader/writer lock for writing. |
|
- | 140 | * Timeout and willingness to block may be specified. |
|
- | 141 | * |
|
- | 142 | * @param rwl Reader/Writer lock. |
|
- | 143 | * @param usec Timeout in microseconds. |
|
- | 144 | * @param trylock Switches between blocking and non-blocking mode. |
|
- | 145 | * |
|
- | 146 | * For exact description of possible combinations of |
|
- | 147 | * 'usec' and 'trylock', see comment for waitq_sleep_timeout(). |
|
- | 148 | * |
|
- | 149 | * @return See comment for waitq_sleep_timeout(). |
|
- | 150 | */ |
|
118 | int _rwlock_read_lock_timeout(rwlock_t *rwl, __u32 usec, int trylock) |
151 | int _rwlock_read_lock_timeout(rwlock_t *rwl, __u32 usec, int trylock) |
119 | { |
152 | { |
120 | int rc; |
153 | int rc; |
121 | pri_t pri; |
154 | pri_t pri; |
122 | 155 | ||
Line 206... | Line 239... | ||
206 | cpu_priority_restore(pri); |
239 | cpu_priority_restore(pri); |
207 | 240 | ||
208 | return ESYNCH_OK_ATOMIC; |
241 | return ESYNCH_OK_ATOMIC; |
209 | } |
242 | } |
210 | 243 | ||
- | 244 | /** Release reader/writer lock held by writer |
|
- | 245 | * |
|
- | 246 | * Release reader/writer lock held by writer. |
|
- | 247 | * Handoff reader/writer lock ownership directly |
|
- | 248 | * to waiting readers or a writer. |
|
- | 249 | * |
|
- | 250 | * @param rwl Reader/Writer lock. |
|
- | 251 | */ |
|
211 | void rwlock_write_unlock(rwlock_t *rwl) |
252 | void rwlock_write_unlock(rwlock_t *rwl) |
212 | { |
253 | { |
213 | pri_t pri; |
254 | pri_t pri; |
214 | 255 | ||
215 | pri = cpu_priority_high(); |
256 | pri = cpu_priority_high(); |
Line 218... | Line 259... | ||
218 | spinlock_unlock(&rwl->lock); |
259 | spinlock_unlock(&rwl->lock); |
219 | cpu_priority_restore(pri); |
260 | cpu_priority_restore(pri); |
220 | 261 | ||
221 | } |
262 | } |
222 | 263 | ||
- | 264 | /** Release reader/writer lock held by reader |
|
- | 265 | * |
|
- | 266 | * Release reader/writer lock held by reader. |
|
- | 267 | * Handoff reader/writer lock ownership directly |
|
- | 268 | * to a waiting writer or don't do anything if more |
|
- | 269 | * readers poses the lock. |
|
- | 270 | * |
|
- | 271 | * @param rwl Reader/Writer lock. |
|
- | 272 | */ |
|
223 | void rwlock_read_unlock(rwlock_t *rwl) |
273 | void rwlock_read_unlock(rwlock_t *rwl) |
224 | { |
274 | { |
225 | pri_t pri; |
275 | pri_t pri; |
226 | 276 | ||
227 | pri = cpu_priority_high(); |
277 | pri = cpu_priority_high(); |
Line 231... | Line 281... | ||
231 | spinlock_unlock(&rwl->lock); |
281 | spinlock_unlock(&rwl->lock); |
232 | cpu_priority_restore(pri); |
282 | cpu_priority_restore(pri); |
233 | } |
283 | } |
234 | 284 | ||
235 | 285 | ||
- | 286 | /** Direct handoff |
|
236 | /* |
287 | * |
- | 288 | * Direct handoff of reader/writer lock ownership |
|
- | 289 | * to waiting readers or a writer. |
|
- | 290 | * |
|
237 | * Must be called with rwl->lock locked. |
291 | * Must be called with rwl->lock locked. |
238 | * Must be called with cpu_priority_high'ed. |
292 | * Must be called with cpu_priority_high'ed. |
239 | */ |
293 | * |
- | 294 | * @param rwl Reader/Writer lock. |
|
- | 295 | * @param readers_only See the description below. |
|
240 | /* |
296 | * |
241 | * If readers_only is false: (unlock scenario) |
297 | * If readers_only is false: (unlock scenario) |
242 | * Let the first sleeper on 'exclusive' mutex in, no matter |
298 | * Let the first sleeper on 'exclusive' mutex in, no matter |
243 | * whether it is a reader or a writer. If there are more leading |
299 | * whether it is a reader or a writer. If there are more leading |
244 | * readers in line, let each of them in. |
300 | * readers in line, let each of them in. |
245 | * |
301 | * |
Line 303... | Line 359... | ||
303 | } while ((type == RWLOCK_READER) && t && one_more); |
359 | } while ((type == RWLOCK_READER) && t && one_more); |
304 | 360 | ||
305 | spinlock_unlock(&rwl->exclusive.sem.wq.lock); |
361 | spinlock_unlock(&rwl->exclusive.sem.wq.lock); |
306 | } |
362 | } |
307 | 363 | ||
- | 364 | /** Release spinlock callback |
|
- | 365 | * |
|
- | 366 | * This is a callback function invoked from the scheduler. |
|
- | 367 | * The callback is registered in _rwlock_read_lock_timeout(). |
|
- | 368 | * |
|
- | 369 | * @param arg Spinlock. |
|
- | 370 | */ |
|
308 | void release_spinlock(void *arg) |
371 | void release_spinlock(void *arg) |
309 | { |
372 | { |
310 | spinlock_unlock((spinlock_t *) arg); |
373 | spinlock_unlock((spinlock_t *) arg); |
311 | } |
374 | } |