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 | ||