Subversion Repositories HelenOS-historic

Rev

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