Rev 552 | Rev 623 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 552 | Rev 557 | ||
---|---|---|---|
Line 24... | Line 24... | ||
24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
27 | */ |
27 | */ |
28 | 28 | ||
29 | - | ||
- | 29 | /** Reader/Writer locks |
|
30 | /* |
30 | * |
31 | * Reader/Writer locks |
31 | * A reader/writer lock can be held by multiple readers at a time. |
- | 32 | * Or it can be exclusively held by a sole writer at a time. |
|
32 | */ |
33 | */ |
33 | 34 | ||
34 | /* |
35 | /* |
35 | * These locks are not recursive. |
36 | * These locks are not recursive. |
36 | * Neither readers nor writers will suffer starvation. |
37 | * Neither readers nor writers will suffer starvation. |
Line 73... | Line 74... | ||
73 | * Initialize reader/writer lock. |
74 | * Initialize reader/writer lock. |
74 | * |
75 | * |
75 | * @param rwl Reader/Writer lock. |
76 | * @param rwl Reader/Writer lock. |
76 | */ |
77 | */ |
77 | void rwlock_initialize(rwlock_t *rwl) { |
78 | void rwlock_initialize(rwlock_t *rwl) { |
78 | spinlock_initialize(&rwl->lock, "rwlock"); |
79 | spinlock_initialize(&rwl->lock, "rwlock_t"); |
79 | mutex_initialize(&rwl->exclusive); |
80 | mutex_initialize(&rwl->exclusive); |
80 | rwl->readers_in = 0; |
81 | rwl->readers_in = 0; |
81 | } |
82 | } |
82 | 83 | ||
83 | /** Acquire reader/writer lock for reading |
84 | /** Acquire reader/writer lock for reading |
Line 216... | Line 217... | ||
216 | * rwl->lock is held.) |
217 | * rwl->lock is held.) |
217 | */ |
218 | */ |
218 | interrupts_restore(ipl); |
219 | interrupts_restore(ipl); |
219 | break; |
220 | break; |
220 | case ESYNCH_OK_ATOMIC: |
221 | case ESYNCH_OK_ATOMIC: |
221 | panic("_mutex_lock_timeout()==ESYNCH_OK_ATOMIC"); |
222 | panic("_mutex_lock_timeout()==ESYNCH_OK_ATOMIC\n"); |
222 | break; |
223 | break; |
223 | dafault: |
224 | dafault: |
224 | panic("invalid ESYNCH"); |
225 | panic("invalid ESYNCH\n"); |
225 | break; |
226 | break; |
226 | } |
227 | } |
227 | return rc; |
228 | return rc; |
228 | } |
229 | } |
229 | 230 | ||
Line 281... | Line 282... | ||
281 | spinlock_unlock(&rwl->lock); |
282 | spinlock_unlock(&rwl->lock); |
282 | interrupts_restore(ipl); |
283 | interrupts_restore(ipl); |
283 | } |
284 | } |
284 | 285 | ||
285 | 286 | ||
286 | /** Direct handoff |
287 | /** Direct handoff of reader/writer lock ownership. |
287 | * |
288 | * |
288 | * Direct handoff of reader/writer lock ownership |
289 | * Direct handoff of reader/writer lock ownership |
289 | * to waiting readers or a writer. |
290 | * to waiting readers or a writer. |
290 | * |
291 | * |
291 | * Must be called with rwl->lock locked. |
292 | * Must be called with rwl->lock locked. |
Line 304... | Line 305... | ||
304 | */ |
305 | */ |
305 | void let_others_in(rwlock_t *rwl, int readers_only) |
306 | void let_others_in(rwlock_t *rwl, int readers_only) |
306 | { |
307 | { |
307 | rwlock_type_t type = RWLOCK_NONE; |
308 | rwlock_type_t type = RWLOCK_NONE; |
308 | thread_t *t = NULL; |
309 | thread_t *t = NULL; |
309 | int one_more = 1; |
310 | bool one_more = true; |
310 | 311 | ||
311 | spinlock_lock(&rwl->exclusive.sem.wq.lock); |
312 | spinlock_lock(&rwl->exclusive.sem.wq.lock); |
312 | 313 | ||
313 | if (!list_empty(&rwl->exclusive.sem.wq.head)) |
314 | if (!list_empty(&rwl->exclusive.sem.wq.head)) |
314 | t = list_get_instance(rwl->exclusive.sem.wq.head.next, thread_t, wq_link); |
315 | t = list_get_instance(rwl->exclusive.sem.wq.head.next, thread_t, wq_link); |
Line 350... | Line 351... | ||
350 | if (!list_empty(&rwl->exclusive.sem.wq.head)) { |
351 | if (!list_empty(&rwl->exclusive.sem.wq.head)) { |
351 | t = list_get_instance(rwl->exclusive.sem.wq.head.next, thread_t, wq_link); |
352 | t = list_get_instance(rwl->exclusive.sem.wq.head.next, thread_t, wq_link); |
352 | if (t) { |
353 | if (t) { |
353 | spinlock_lock(&t->lock); |
354 | spinlock_lock(&t->lock); |
354 | if (t->rwlock_holder_type != RWLOCK_READER) |
355 | if (t->rwlock_holder_type != RWLOCK_READER) |
355 | one_more = 0; |
356 | one_more = false; |
356 | spinlock_unlock(&t->lock); |
357 | spinlock_unlock(&t->lock); |
357 | } |
358 | } |
358 | } |
359 | } |
359 | } while ((type == RWLOCK_READER) && t && one_more); |
360 | } while ((type == RWLOCK_READER) && t && one_more); |
360 | 361 |