Subversion Repositories HelenOS

Rev

Rev 153 | Rev 413 | Go to most recent revision | Show entire file | Ignore 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
}