import tput from NetBSD
[minix3.git] / lib / libmthread / rwlock.c
blobf06c41cb6b197cc3396a4ce469f371a0fb96cbb4
1 #include <minix/mthread.h>
2 #include "global.h"
4 /*===========================================================================*
5 * mthread_rwlock_init *
6 *===========================================================================*/
7 int mthread_rwlock_init(rwlock)
8 mthread_rwlock_t *rwlock; /* The rwlock to be initialized */
10 /* Initialize a readers/writer lock. */
11 int r;
13 if (!rwlock)
14 return EINVAL;
16 rwlock->writer = NO_THREAD;
17 rwlock->readers = 0;
19 r = mthread_mutex_init(&rwlock->queue, NULL);
20 if (r != 0)
21 return r;
23 r = mthread_event_init(&rwlock->drain);
24 if (r != 0)
25 mthread_mutex_destroy(&rwlock->queue);
27 return r;
30 /*===========================================================================*
31 * mthread_rwlock_destroy *
32 *===========================================================================*/
33 int mthread_rwlock_destroy(rwlock)
34 mthread_rwlock_t *rwlock; /* The rwlock to be destroyed */
36 /* Destroy a readers/writer lock. */
37 int r;
39 if (!rwlock)
40 return EINVAL;
42 assert(rwlock->writer == NO_THREAD);
43 assert(rwlock->readers == 0);
45 r = mthread_event_destroy(&rwlock->drain);
46 if (r != 0)
47 return r;
49 return mthread_mutex_destroy(&rwlock->queue);
52 /*===========================================================================*
53 * mthread_rwlock_rdlock *
54 *===========================================================================*/
55 int mthread_rwlock_rdlock(rwlock)
56 mthread_rwlock_t *rwlock; /* The rwlock to be read locked */
58 /* Acquire a reader lock. */
59 int r;
61 if (!rwlock)
62 return EINVAL;
64 r = mthread_mutex_lock(&rwlock->queue);
65 if (r != 0)
66 return r;
68 r = mthread_mutex_unlock(&rwlock->queue);
69 if (r != 0)
70 return r;
72 rwlock->readers++;
74 return 0;
77 /*===========================================================================*
78 * mthread_rwlock_wrlock *
79 *===========================================================================*/
80 int mthread_rwlock_wrlock(rwlock)
81 mthread_rwlock_t *rwlock; /* The rwlock to be write locked */
83 /* Acquire a writer lock. */
84 int r;
86 if (!rwlock)
87 return EINVAL;
89 r = mthread_mutex_lock(&rwlock->queue);
90 if (r != 0)
91 return r;
93 rwlock->writer = current_thread;
95 if (rwlock->readers > 0)
96 r = mthread_event_wait(&rwlock->drain);
98 if (r == 0)
99 assert(rwlock->readers == 0);
101 return r;
104 /*===========================================================================*
105 * mthread_rwlock_unlock *
106 *===========================================================================*/
107 int mthread_rwlock_unlock(rwlock)
108 mthread_rwlock_t *rwlock; /* The rwlock to be unlocked */
110 /* Release a lock. */
111 int r;
113 r = 0;
114 if (!rwlock)
115 return EINVAL;
117 if (rwlock->writer == current_thread) {
118 rwlock->writer = NO_THREAD;
119 r = mthread_mutex_unlock(&rwlock->queue);
120 } else {
121 assert(rwlock->readers > 0);
123 rwlock->readers--;
125 if (rwlock->readers == 0 && rwlock->writer != NO_THREAD)
126 r = mthread_event_fire(&rwlock->drain);
129 return r;