version 1.20.2.1, 2007/11/06 23:11:43 |
version 1.20.2.2, 2008/01/09 01:36:38 |
Line 46 __RCSID("$NetBSD$"); |
|
Line 46 __RCSID("$NetBSD$"); |
|
|
|
#ifndef PTHREAD__HAVE_ATOMIC |
#ifndef PTHREAD__HAVE_ATOMIC |
|
|
|
int _pthread_rwlock_held_np(pthread_rwlock_t *); |
|
int _pthread_rwlock_rdheld_np(pthread_rwlock_t *); |
|
int _pthread_rwlock_wrheld_np(pthread_rwlock_t *); |
|
|
|
__weak_alias(pthread_mutex_held_np,_pthread_rwlock_held_np); |
|
__weak_alias(pthread_mutex_rdheld_np,_pthread_rwlock_rdheld_np); |
|
__weak_alias(pthread_mutex_wrheld_np,_pthread_rwlock_wrheld_np); |
|
|
__strong_alias(__libc_rwlock_init,pthread_rwlock_init) |
__strong_alias(__libc_rwlock_init,pthread_rwlock_init) |
__strong_alias(__libc_rwlock_rdlock,pthread_rwlock_rdlock) |
__strong_alias(__libc_rwlock_rdlock,pthread_rwlock_rdlock) |
__strong_alias(__libc_rwlock_wrlock,pthread_rwlock_wrlock) |
__strong_alias(__libc_rwlock_wrlock,pthread_rwlock_wrlock) |
Line 102 pthread_rwlock_rdlock(pthread_rwlock_t * |
|
Line 110 pthread_rwlock_rdlock(pthread_rwlock_t * |
|
#endif |
#endif |
self = pthread__self(); |
self = pthread__self(); |
|
|
pthread_spinlock(&rwlock->ptr_interlock); |
pthread__spinlock(self, &rwlock->ptr_interlock); |
#ifdef ERRORCHECK |
#ifdef ERRORCHECK |
if (rwlock->ptr_writer == self) { |
if (rwlock->ptr_writer == self) { |
pthread_spinunlock(&rwlock->ptr_interlock); |
pthread__spinunlock(self, &rwlock->ptr_interlock); |
return EDEADLK; |
return EDEADLK; |
} |
} |
#endif |
#endif |
Line 119 pthread_rwlock_rdlock(pthread_rwlock_t * |
|
Line 127 pthread_rwlock_rdlock(pthread_rwlock_t * |
|
PTQ_INSERT_TAIL(&rwlock->ptr_rblocked, self, pt_sleep); |
PTQ_INSERT_TAIL(&rwlock->ptr_rblocked, self, pt_sleep); |
self->pt_sleeponq = 1; |
self->pt_sleeponq = 1; |
self->pt_sleepobj = &rwlock->ptr_rblocked; |
self->pt_sleepobj = &rwlock->ptr_rblocked; |
pthread_spinunlock(&rwlock->ptr_interlock); |
pthread__spinunlock(self, &rwlock->ptr_interlock); |
(void)pthread__park(self, &rwlock->ptr_interlock, |
(void)pthread__park(self, &rwlock->ptr_interlock, |
&rwlock->ptr_rblocked, NULL, 0, &rwlock->ptr_rblocked); |
&rwlock->ptr_rblocked, NULL, 0, &rwlock->ptr_rblocked); |
pthread_spinlock(&rwlock->ptr_interlock); |
pthread__spinlock(self, &rwlock->ptr_interlock); |
} |
} |
|
|
rwlock->ptr_nreaders++; |
rwlock->ptr_nreaders++; |
pthread_spinunlock(&rwlock->ptr_interlock); |
pthread__spinunlock(self, &rwlock->ptr_interlock); |
|
|
return 0; |
return 0; |
} |
} |
Line 135 pthread_rwlock_rdlock(pthread_rwlock_t * |
|
Line 143 pthread_rwlock_rdlock(pthread_rwlock_t * |
|
int |
int |
pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock) |
pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock) |
{ |
{ |
|
pthread_t self; |
|
|
#ifdef ERRORCHECK |
#ifdef ERRORCHECK |
if ((rwlock == NULL) || (rwlock->ptr_magic != _PT_RWLOCK_MAGIC)) |
if ((rwlock == NULL) || (rwlock->ptr_magic != _PT_RWLOCK_MAGIC)) |
return EINVAL; |
return EINVAL; |
#endif |
#endif |
|
|
pthread_spinlock(&rwlock->ptr_interlock); |
self = pthread__self(); |
|
pthread__spinlock(self, &rwlock->ptr_interlock); |
/* |
/* |
* Don't get a readlock if there is a writer or if there are waiting |
* Don't get a readlock if there is a writer or if there are waiting |
* writers; i.e. prefer writers to readers. This strategy is dictated |
* writers; i.e. prefer writers to readers. This strategy is dictated |
Line 149 pthread_rwlock_tryrdlock(pthread_rwlock_ |
|
Line 159 pthread_rwlock_tryrdlock(pthread_rwlock_ |
|
*/ |
*/ |
if ((rwlock->ptr_writer != NULL) || |
if ((rwlock->ptr_writer != NULL) || |
(!PTQ_EMPTY(&rwlock->ptr_wblocked))) { |
(!PTQ_EMPTY(&rwlock->ptr_wblocked))) { |
pthread_spinunlock(&rwlock->ptr_interlock); |
pthread__spinunlock(self, &rwlock->ptr_interlock); |
return EBUSY; |
return EBUSY; |
} |
} |
|
|
rwlock->ptr_nreaders++; |
rwlock->ptr_nreaders++; |
pthread_spinunlock(&rwlock->ptr_interlock); |
pthread__spinunlock(self, &rwlock->ptr_interlock); |
|
|
return 0; |
return 0; |
} |
} |
Line 172 pthread_rwlock_wrlock(pthread_rwlock_t * |
|
Line 182 pthread_rwlock_wrlock(pthread_rwlock_t * |
|
#endif |
#endif |
self = pthread__self(); |
self = pthread__self(); |
|
|
pthread_spinlock(&rwlock->ptr_interlock); |
pthread__spinlock(self, &rwlock->ptr_interlock); |
#ifdef ERRORCHECK |
#ifdef ERRORCHECK |
if (rwlock->ptr_writer == self) { |
if (rwlock->ptr_writer == self) { |
pthread_spinunlock(&rwlock->ptr_interlock); |
pthread__spinunlock(self, &rwlock->ptr_interlock); |
return EDEADLK; |
return EDEADLK; |
} |
} |
#endif |
#endif |
Line 186 pthread_rwlock_wrlock(pthread_rwlock_t * |
|
Line 196 pthread_rwlock_wrlock(pthread_rwlock_t * |
|
while ((rwlock->ptr_nreaders > 0) || (rwlock->ptr_writer != NULL)) { |
while ((rwlock->ptr_nreaders > 0) || (rwlock->ptr_writer != NULL)) { |
#ifdef ERRORCHECK |
#ifdef ERRORCHECK |
if (pthread__started == 0) { |
if (pthread__started == 0) { |
pthread_spinunlock(&rwlock->ptr_interlock); |
pthread__spinunlock(self, &rwlock->ptr_interlock); |
return EDEADLK; |
return EDEADLK; |
} |
} |
#endif |
#endif |
PTQ_INSERT_TAIL(&rwlock->ptr_wblocked, self, pt_sleep); |
PTQ_INSERT_TAIL(&rwlock->ptr_wblocked, self, pt_sleep); |
self->pt_sleeponq = 1; |
self->pt_sleeponq = 1; |
self->pt_sleepobj = &rwlock->ptr_wblocked; |
self->pt_sleepobj = &rwlock->ptr_wblocked; |
pthread_spinunlock(&rwlock->ptr_interlock); |
pthread__spinunlock(self, &rwlock->ptr_interlock); |
(void)pthread__park(self, &rwlock->ptr_interlock, |
(void)pthread__park(self, &rwlock->ptr_interlock, |
&rwlock->ptr_wblocked, NULL, 0, &rwlock->ptr_wblocked); |
&rwlock->ptr_wblocked, NULL, 0, &rwlock->ptr_wblocked); |
pthread_spinlock(&rwlock->ptr_interlock); |
pthread__spinlock(self, &rwlock->ptr_interlock); |
} |
} |
|
|
rwlock->ptr_writer = self; |
rwlock->ptr_writer = self; |
pthread_spinunlock(&rwlock->ptr_interlock); |
pthread__spinunlock(self, &rwlock->ptr_interlock); |
|
|
return 0; |
return 0; |
} |
} |
Line 216 pthread_rwlock_trywrlock(pthread_rwlock_ |
|
Line 226 pthread_rwlock_trywrlock(pthread_rwlock_ |
|
#endif |
#endif |
self = pthread__self(); |
self = pthread__self(); |
|
|
pthread_spinlock(&rwlock->ptr_interlock); |
pthread__spinlock(self, &rwlock->ptr_interlock); |
/* |
/* |
* Prefer writers to readers here; permit writers even if there are |
* Prefer writers to readers here; permit writers even if there are |
* waiting readers. |
* waiting readers. |
*/ |
*/ |
if ((rwlock->ptr_nreaders > 0) || (rwlock->ptr_writer != NULL)) { |
if ((rwlock->ptr_nreaders > 0) || (rwlock->ptr_writer != NULL)) { |
pthread_spinunlock(&rwlock->ptr_interlock); |
pthread__spinunlock(self, &rwlock->ptr_interlock); |
return EBUSY; |
return EBUSY; |
} |
} |
|
|
rwlock->ptr_writer = self; |
rwlock->ptr_writer = self; |
pthread_spinunlock(&rwlock->ptr_interlock); |
pthread__spinunlock(self, &rwlock->ptr_interlock); |
|
|
return 0; |
return 0; |
} |
} |
Line 252 pthread_rwlock_timedrdlock(pthread_rwloc |
|
Line 262 pthread_rwlock_timedrdlock(pthread_rwloc |
|
return EINVAL; |
return EINVAL; |
|
|
self = pthread__self(); |
self = pthread__self(); |
pthread_spinlock(&rwlock->ptr_interlock); |
pthread__spinlock(self, &rwlock->ptr_interlock); |
#ifdef ERRORCHECK |
#ifdef ERRORCHECK |
if (rwlock->ptr_writer == self) { |
if (rwlock->ptr_writer == self) { |
pthread_spinunlock(&rwlock->ptr_interlock); |
pthread__spinunlock(self, &rwlock->ptr_interlock); |
return EDEADLK; |
return EDEADLK; |
} |
} |
#endif |
#endif |
Line 270 pthread_rwlock_timedrdlock(pthread_rwloc |
|
Line 280 pthread_rwlock_timedrdlock(pthread_rwloc |
|
PTQ_INSERT_TAIL(&rwlock->ptr_rblocked, self, pt_sleep); |
PTQ_INSERT_TAIL(&rwlock->ptr_rblocked, self, pt_sleep); |
self->pt_sleeponq = 1; |
self->pt_sleeponq = 1; |
self->pt_sleepobj = &rwlock->ptr_rblocked; |
self->pt_sleepobj = &rwlock->ptr_rblocked; |
pthread_spinunlock(&rwlock->ptr_interlock); |
pthread__spinunlock(self, &rwlock->ptr_interlock); |
retval = pthread__park(self, &rwlock->ptr_interlock, |
retval = pthread__park(self, &rwlock->ptr_interlock, |
&rwlock->ptr_rblocked, abs_timeout, 0, |
&rwlock->ptr_rblocked, abs_timeout, 0, |
&rwlock->ptr_rblocked); |
&rwlock->ptr_rblocked); |
pthread_spinlock(&rwlock->ptr_interlock); |
pthread__spinlock(self, &rwlock->ptr_interlock); |
} |
} |
|
|
/* One last chance to get the lock, in case it was released between |
/* One last chance to get the lock, in case it was released between |
Line 285 pthread_rwlock_timedrdlock(pthread_rwloc |
|
Line 295 pthread_rwlock_timedrdlock(pthread_rwloc |
|
rwlock->ptr_nreaders++; |
rwlock->ptr_nreaders++; |
retval = 0; |
retval = 0; |
} |
} |
pthread_spinunlock(&rwlock->ptr_interlock); |
pthread__spinunlock(self, &rwlock->ptr_interlock); |
|
|
return retval; |
return retval; |
} |
} |
Line 311 pthread_rwlock_timedwrlock(pthread_rwloc |
|
Line 321 pthread_rwlock_timedwrlock(pthread_rwloc |
|
return EINVAL; |
return EINVAL; |
|
|
self = pthread__self(); |
self = pthread__self(); |
pthread_spinlock(&rwlock->ptr_interlock); |
pthread__spinlock(self, &rwlock->ptr_interlock); |
#ifdef ERRORCHECK |
#ifdef ERRORCHECK |
if (rwlock->ptr_writer == self) { |
if (rwlock->ptr_writer == self) { |
pthread_spinunlock(&rwlock->ptr_interlock); |
pthread__spinunlock(self, &rwlock->ptr_interlock); |
return EDEADLK; |
return EDEADLK; |
} |
} |
#endif |
#endif |
Line 327 pthread_rwlock_timedwrlock(pthread_rwloc |
|
Line 337 pthread_rwlock_timedwrlock(pthread_rwloc |
|
((rwlock->ptr_nreaders > 0) || (rwlock->ptr_writer != NULL))) { |
((rwlock->ptr_nreaders > 0) || (rwlock->ptr_writer != NULL))) { |
#ifdef ERRORCHECK |
#ifdef ERRORCHECK |
if (pthread__started == 0) { |
if (pthread__started == 0) { |
pthread_spinunlock(&rwlock->ptr_interlock); |
pthread__spinunlock(self, &rwlock->ptr_interlock); |
return EDEADLK; |
return EDEADLK; |
} |
} |
#endif |
#endif |
PTQ_INSERT_TAIL(&rwlock->ptr_wblocked, self, pt_sleep); |
PTQ_INSERT_TAIL(&rwlock->ptr_wblocked, self, pt_sleep); |
self->pt_sleeponq = 1; |
self->pt_sleeponq = 1; |
self->pt_sleepobj = &rwlock->ptr_wblocked; |
self->pt_sleepobj = &rwlock->ptr_wblocked; |
pthread_spinunlock(&rwlock->ptr_interlock); |
pthread__spinunlock(self, &rwlock->ptr_interlock); |
retval = pthread__park(self, &rwlock->ptr_interlock, |
retval = pthread__park(self, &rwlock->ptr_interlock, |
&rwlock->ptr_wblocked, abs_timeout, 0, |
&rwlock->ptr_wblocked, abs_timeout, 0, |
&rwlock->ptr_wblocked); |
&rwlock->ptr_wblocked); |
pthread_spinlock(&rwlock->ptr_interlock); |
pthread__spinlock(self, &rwlock->ptr_interlock); |
} |
} |
|
|
if ((rwlock->ptr_nreaders == 0) && (rwlock->ptr_writer == NULL)) { |
if ((rwlock->ptr_nreaders == 0) && (rwlock->ptr_writer == NULL)) { |
rwlock->ptr_writer = self; |
rwlock->ptr_writer = self; |
retval = 0; |
retval = 0; |
} |
} |
pthread_spinunlock(&rwlock->ptr_interlock); |
pthread__spinunlock(self, &rwlock->ptr_interlock); |
|
|
return retval; |
return retval; |
} |
} |
Line 362 pthread_rwlock_unlock(pthread_rwlock_t * |
|
Line 372 pthread_rwlock_unlock(pthread_rwlock_t * |
|
writer = NULL; |
writer = NULL; |
self = pthread__self(); |
self = pthread__self(); |
|
|
pthread_spinlock(&rwlock->ptr_interlock); |
pthread__spinlock(self, &rwlock->ptr_interlock); |
if (rwlock->ptr_writer != NULL) { |
if (rwlock->ptr_writer != NULL) { |
/* Releasing a write lock. */ |
/* Releasing a write lock. */ |
#ifdef ERRORCHECK |
#ifdef ERRORCHECK |
if (rwlock->ptr_writer != self) { |
if (rwlock->ptr_writer != self) { |
pthread_spinunlock(&rwlock->ptr_interlock); |
pthread__spinunlock(self, &rwlock->ptr_interlock); |
return EPERM; |
return EPERM; |
} |
} |
#endif |
#endif |
Line 391 pthread_rwlock_unlock(pthread_rwlock_t * |
|
Line 401 pthread_rwlock_unlock(pthread_rwlock_t * |
|
} |
} |
#ifdef ERRORCHECK |
#ifdef ERRORCHECK |
} else { |
} else { |
pthread_spinunlock(&rwlock->ptr_interlock); |
pthread__spinunlock(self, &rwlock->ptr_interlock); |
return EPERM; |
return EPERM; |
#endif |
#endif |
} |
} |
Line 433 pthread_rwlockattr_destroy(pthread_rwloc |
|
Line 443 pthread_rwlockattr_destroy(pthread_rwloc |
|
return 0; |
return 0; |
} |
} |
|
|
|
int |
|
_pthread_rwlock_held_np(pthread_rwlock_t *ptr) |
|
{ |
|
|
|
return ptr->ptr_writer != NULL || ptr->ptr_nreaders != 0; |
|
} |
|
|
|
int |
|
_pthread_rwlock_rdheld_np(pthread_rwlock_t *ptr) |
|
{ |
|
|
|
return ptr->ptr_nreaders != 0; |
|
} |
|
|
|
int |
|
_pthread_rwlock_wrheld_np(pthread_rwlock_t *ptr) |
|
{ |
|
|
|
return ptr->ptr_writer != 0; |
|
} |
|
|
#endif /* !PTHREAD__HAVE_ATOMIC */ |
#endif /* !PTHREAD__HAVE_ATOMIC */ |