1 #include <minix/mthread.h> 2 #include "global.h" 3 4 /*===========================================================================* 5 * mthread_rwlock_init * 6 *===========================================================================*/ mthread_rwlock_init(rwlock)7int mthread_rwlock_init(rwlock) 8 mthread_rwlock_t *rwlock; /* The rwlock to be initialized */ 9 { 10 /* Initialize a readers/writer lock. */ 11 int r; 12 13 if (!rwlock) 14 return EINVAL; 15 16 rwlock->writer = NO_THREAD; 17 rwlock->readers = 0; 18 19 r = mthread_mutex_init(&rwlock->queue, NULL); 20 if (r != 0) 21 return r; 22 23 r = mthread_event_init(&rwlock->drain); 24 if (r != 0) 25 mthread_mutex_destroy(&rwlock->queue); 26 27 return r; 28 } 29 30 /*===========================================================================* 31 * mthread_rwlock_destroy * 32 *===========================================================================*/ mthread_rwlock_destroy(rwlock)33int mthread_rwlock_destroy(rwlock) 34 mthread_rwlock_t *rwlock; /* The rwlock to be destroyed */ 35 { 36 /* Destroy a readers/writer lock. */ 37 int r; 38 39 if (!rwlock) 40 return EINVAL; 41 42 assert(rwlock->writer == NO_THREAD); 43 assert(rwlock->readers == 0); 44 45 r = mthread_event_destroy(&rwlock->drain); 46 if (r != 0) 47 return r; 48 49 return mthread_mutex_destroy(&rwlock->queue); 50 } 51 52 /*===========================================================================* 53 * mthread_rwlock_rdlock * 54 *===========================================================================*/ mthread_rwlock_rdlock(rwlock)55int mthread_rwlock_rdlock(rwlock) 56 mthread_rwlock_t *rwlock; /* The rwlock to be read locked */ 57 { 58 /* Acquire a reader lock. */ 59 int r; 60 61 if (!rwlock) 62 return EINVAL; 63 64 r = mthread_mutex_lock(&rwlock->queue); 65 if (r != 0) 66 return r; 67 68 r = mthread_mutex_unlock(&rwlock->queue); 69 if (r != 0) 70 return r; 71 72 rwlock->readers++; 73 74 return 0; 75 } 76 77 /*===========================================================================* 78 * mthread_rwlock_wrlock * 79 *===========================================================================*/ mthread_rwlock_wrlock(rwlock)80int mthread_rwlock_wrlock(rwlock) 81 mthread_rwlock_t *rwlock; /* The rwlock to be write locked */ 82 { 83 /* Acquire a writer lock. */ 84 int r; 85 86 if (!rwlock) 87 return EINVAL; 88 89 r = mthread_mutex_lock(&rwlock->queue); 90 if (r != 0) 91 return r; 92 93 rwlock->writer = current_thread; 94 95 if (rwlock->readers > 0) 96 r = mthread_event_wait(&rwlock->drain); 97 98 if (r == 0) 99 assert(rwlock->readers == 0); 100 101 return r; 102 } 103 104 /*===========================================================================* 105 * mthread_rwlock_unlock * 106 *===========================================================================*/ mthread_rwlock_unlock(rwlock)107int mthread_rwlock_unlock(rwlock) 108 mthread_rwlock_t *rwlock; /* The rwlock to be unlocked */ 109 { 110 /* Release a lock. */ 111 int r; 112 113 r = 0; 114 if (!rwlock) 115 return EINVAL; 116 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); 122 123 rwlock->readers--; 124 125 if (rwlock->readers == 0 && rwlock->writer != NO_THREAD) 126 r = mthread_event_fire(&rwlock->drain); 127 } 128 129 return r; 130 } 131 132 /* pthread compatibility layer. */ 133 __weak_alias(pthread_rwlock_destroy, mthread_rwlock_destroy) 134 __weak_alias(pthread_rwlock_rdlock, mthread_rwlock_rdlock) 135 __weak_alias(pthread_rwlock_wrlock, mthread_rwlock_wrlock) 136 __weak_alias(pthread_rwlock_unlock, mthread_rwlock_unlock) 137 138