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