commit dfc4ad349414b5c840eb245f66b09a436887ef97
parent 3ec1004731beb8400a4bf07417e8b6d5e5294e36
Author: oblique <psyberbits@gmail.com>
Date: Wed, 3 Apr 2013 11:56:59 +0300
move readers-writer lock to rwlock.h
Diffstat:
A | include/rwlock.h | | | 154 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
M | include/semaphore.h | | | 148 | ------------------------------------------------------------------------------- |
2 files changed, 154 insertions(+), 148 deletions(-)
diff --git a/include/rwlock.h b/include/rwlock.h
@@ -0,0 +1,154 @@
+#ifndef __RWLOCK_H
+#define __RWLOCK_H
+
+#include <inttypes.h>
+#include <semaphore.h>
+
+/* readers-writer lock
+ * implemented with 'Passing the Baton' technique
+ *
+ * rules:
+ * 1) if we have an awakened writer or writers in the queue then
+ * a new reader will be added in readers' queue.
+ * 2) if all awakened readers are done then we awake a writer,
+ * even if we have readers in the queue.
+ * 3) if the awakened writer and all writers in the queue are done
+ * then we awake all the readers. */
+typedef struct {
+ mutex_t lock;
+ mutex_t writer_wait;
+ mutex_t reader_wait;
+ u32 nr_writers;
+ u32 nr_readers;
+ u32 nr_writers_queue;
+ u32 nr_readers_queue;
+} rwlock_t;
+
+#define RWLOCK_INIT { \
+ MUTEX_INIT, \
+ MUTEX_INIT_LOCKED, \
+ MUTEX_INIT_LOCKED, \
+ 0, \
+ 0, \
+ 0, \
+ 0 \
+}
+
+static inline void
+rwlock_init(rwlock_t *rwl)
+{
+ mutex_init(&rwl->lock);
+ mutex_init(&rwl->writer_wait);
+ mutex_lock(&rwl->writer_wait);
+ mutex_init(&rwl->reader_wait);
+ mutex_lock(&rwl->reader_wait);
+ rwl->nr_writers = 0;
+ rwl->nr_readers = 0;
+ rwl->nr_writers_queue = 0;
+ rwl->nr_readers_queue = 0;
+}
+
+static inline void
+rwlock_rdlock(rwlock_t *rwl)
+{
+ mutex_lock(&rwl->lock);
+ /* if we have awakened writer or writers in the queue then wait */
+ if (rwl->nr_writers > 0 || rwl->nr_writers_queue > 0) {
+ rwl->nr_readers_queue++;
+ mutex_unlock(&rwl->lock);
+ /* wait */
+ mutex_lock(&rwl->reader_wait);
+ }
+
+ rwl->nr_readers++;
+
+ /* if there is at least one reader in the queue,
+ * awake it (i.e. awake the next reader) */
+ if (rwl->nr_readers_queue > 0) {
+ rwl->nr_readers_queue--;
+ mutex_unlock(&rwl->reader_wait);
+ } else {
+ mutex_unlock(&rwl->lock);
+ }
+}
+
+/* returns 1 if managed to lock
+ * returns 0 if not */
+static inline int
+rwlock_tryrdlock(rwlock_t *rwl)
+{
+ mutex_lock(&rwl->lock);
+ /* if we have awakened writer or writers in the queue then we can't lock */
+ if (rwl->nr_writers > 0 || rwl->nr_writers_queue > 0) {
+ mutex_unlock(&rwl->lock);
+ return 0;
+ }
+
+ rwl->nr_readers++;
+ mutex_unlock(&rwl->lock);
+ return 1;
+}
+
+static inline void
+rwlock_wrlock(rwlock_t *rwl)
+{
+ mutex_lock(&rwl->lock);
+ /* if we have an awakened writer or awakened readers then wait */
+ if (rwl->nr_writers > 0 || rwl->nr_readers > 0) {
+ rwl->nr_writers_queue++;
+ mutex_unlock(&rwl->lock);
+ /* wait */
+ mutex_lock(&rwl->writer_wait);
+ }
+
+ rwl->nr_writers++;
+ mutex_unlock(&rwl->lock);
+}
+
+/* returns 1 if managed to lock
+ * returns 0 if not */
+static inline int
+rwlock_trywrlock(rwlock_t *rwl)
+{
+ mutex_lock(&rwl->lock);
+ /* if we have an awakened writer or awakened readers then we can't lock */
+ if (rwl->nr_writers > 0 || rwl->nr_readers > 0) {
+ mutex_unlock(&rwl->lock);
+ return 0;
+ }
+
+ rwl->nr_writers++;
+ mutex_unlock(&rwl->lock);
+ return 1;
+}
+
+static inline void
+rwlock_unlock(rwlock_t *rwl)
+{
+ mutex_lock(&rwl->lock);
+
+ /* a reader is done */
+ if (rwl->nr_readers > 0) {
+ rwl->nr_readers--;
+ /* a writer is done */
+ } else if (rwl->nr_writers > 0) {
+ rwl->nr_writers--;
+ }
+
+ /* if all awakened readers are done and we have writers in the queue
+ * then awake a writer */
+ if (rwl->nr_readers == 0 && rwl->nr_writers_queue > 0) {
+ rwl->nr_writers_queue--;
+ mutex_unlock(&rwl->writer_wait);
+ /* if the awakened writer and all writers from the queue are done
+ * then awake a reader */
+ } else if (rwl->nr_writers == 0 && rwl->nr_writers_queue == 0 &&
+ rwl->nr_readers_queue > 0) {
+ rwl->nr_readers_queue--;
+ mutex_unlock(&rwl->reader_wait);
+ } else {
+ mutex_unlock(&rwl->lock);
+ }
+}
+
+#endif /* __RWLOCK_H */
diff --git a/include/semaphore.h b/include/semaphore.h
@@ -109,152 +109,4 @@ mutex_unlock(mutex_t *mut)
semaphore_done(&mut->sem);
}
-
-/* readers-writer lock
- * implemented with 'Passing the Baton' technique
- *
- * rules:
- * 1) if we have an awakened writer or writers in the queue then
- * a new reader will be added in readers' queue.
- * 2) if all awakened readers are done then we awake a writer,
- * even if we have readers in the queue.
- * 3) if the awakened writer and all writers in the queue are done
- * then we awake all the readers. */
-typedef struct {
- mutex_t lock;
- mutex_t writer_wait;
- mutex_t reader_wait;
- u32 nr_writers;
- u32 nr_readers;
- u32 nr_writers_queue;
- u32 nr_readers_queue;
-} rwlock_t;
-
-#define RWLOCK_INIT { \
- MUTEX_INIT, \
- MUTEX_INIT_LOCKED, \
- MUTEX_INIT_LOCKED, \
- 0, \
- 0, \
- 0, \
- 0 \
-}
-
-static inline void
-rwlock_init(rwlock_t *rwl)
-{
- mutex_init(&rwl->lock);
- mutex_init(&rwl->writer_wait);
- mutex_lock(&rwl->writer_wait);
- mutex_init(&rwl->reader_wait);
- mutex_lock(&rwl->reader_wait);
- rwl->nr_writers = 0;
- rwl->nr_readers = 0;
- rwl->nr_writers_queue = 0;
- rwl->nr_readers_queue = 0;
-}
-
-static inline void
-rwlock_rdlock(rwlock_t *rwl)
-{
- mutex_lock(&rwl->lock);
- /* if we have awakened writer or writers in the queue then wait */
- if (rwl->nr_writers > 0 || rwl->nr_writers_queue > 0) {
- rwl->nr_readers_queue++;
- mutex_unlock(&rwl->lock);
- /* wait */
- mutex_lock(&rwl->reader_wait);
- }
-
- rwl->nr_readers++;
-
- /* if there is at least one reader in the queue,
- * awake it (i.e. awake the next reader) */
- if (rwl->nr_readers_queue > 0) {
- rwl->nr_readers_queue--;
- mutex_unlock(&rwl->reader_wait);
- } else {
- mutex_unlock(&rwl->lock);
- }
-}
-
-/* returns 1 if managed to lock
- * returns 0 if not */
-static inline int
-rwlock_tryrdlock(rwlock_t *rwl)
-{
- mutex_lock(&rwl->lock);
- /* if we have awakened writer or writers in the queue then we can't lock */
- if (rwl->nr_writers > 0 || rwl->nr_writers_queue > 0) {
- mutex_unlock(&rwl->lock);
- return 0;
- }
-
- rwl->nr_readers++;
- mutex_unlock(&rwl->lock);
- return 1;
-}
-
-static inline void
-rwlock_wrlock(rwlock_t *rwl)
-{
- mutex_lock(&rwl->lock);
- /* if we have an awakened writer or awakened readers then wait */
- if (rwl->nr_writers > 0 || rwl->nr_readers > 0) {
- rwl->nr_writers_queue++;
- mutex_unlock(&rwl->lock);
- /* wait */
- mutex_lock(&rwl->writer_wait);
- }
-
- rwl->nr_writers++;
- mutex_unlock(&rwl->lock);
-}
-
-/* returns 1 if managed to lock
- * returns 0 if not */
-static inline int
-rwlock_trywrlock(rwlock_t *rwl)
-{
- mutex_lock(&rwl->lock);
- /* if we have an awakened writer or awakened readers then we can't lock */
- if (rwl->nr_writers > 0 || rwl->nr_readers > 0) {
- mutex_unlock(&rwl->lock);
- return 0;
- }
-
- rwl->nr_writers++;
- mutex_unlock(&rwl->lock);
- return 1;
-}
-
-static inline void
-rwlock_unlock(rwlock_t *rwl)
-{
- mutex_lock(&rwl->lock);
-
- /* a reader is done */
- if (rwl->nr_readers > 0) {
- rwl->nr_readers--;
- /* a writer is done */
- } else if (rwl->nr_writers > 0) {
- rwl->nr_writers--;
- }
-
- /* if all awakened readers are done and we have writers in the queue
- * then awake a writer */
- if (rwl->nr_readers == 0 && rwl->nr_writers_queue > 0) {
- rwl->nr_writers_queue--;
- mutex_unlock(&rwl->writer_wait);
- /* if the awakened writer and all writers from the queue are done
- * then awake a reader */
- } else if (rwl->nr_writers == 0 && rwl->nr_writers_queue == 0 &&
- rwl->nr_readers_queue > 0) {
- rwl->nr_readers_queue--;
- mutex_unlock(&rwl->reader_wait);
- } else {
- mutex_unlock(&rwl->lock);
- }
-}
-
#endif /* __SEMAPHORE_H */