#if USE_PTHREAD_RWLOCK
#include <pthread.h>
-struct isc_rwlock {
- pthread_rwlock_t rwlock;
- atomic_bool downgrade;
-};
-
#if ISC_TRACK_PTHREADS_OBJECTS
-typedef struct isc_rwlock *isc_rwlock_t;
-typedef struct isc_rwlock isc__rwlock_t;
+typedef pthread_rwlock_t *isc_rwlock_t;
+typedef pthread_rwlock_t isc__rwlock_t;
#define isc_rwlock_init(rwl, rq, wq) \
{ \
#define isc_rwlock_trylock(rwl, type) isc___rwlock_trylock(*rwl, type)
#define isc_rwlock_unlock(rwl, type) isc__rwlock_unlock(*rwl, type)
#define isc_rwlock_tryupgrade(rwl) isc___rwlock_tryupgrade(*rwl)
-#define isc_rwlock_downgrade(rwl) isc__rwlock_downgrade(*rwl)
#define isc_rwlock_destroy(rwl) \
{ \
isc___rwlock_destroy(*rwl); \
#else /* ISC_TRACK_PTHREADS_OBJECTS */
-typedef struct isc_rwlock isc_rwlock_t;
-typedef struct isc_rwlock isc__rwlock_t;
+typedef pthread_rwlock_t isc_rwlock_t;
+typedef pthread_rwlock_t isc__rwlock_t;
#define isc_rwlock_init(rwl, rq, wq) isc__rwlock_init(rwl, rq, wq)
#define isc_rwlock_lock(rwl, type) isc__rwlock_lock(rwl, type)
#define isc_rwlock_trylock(rwl, type) isc___rwlock_trylock(rwl, type)
#define isc_rwlock_unlock(rwl, type) isc__rwlock_unlock(rwl, type)
#define isc_rwlock_tryupgrade(rwl) isc___rwlock_tryupgrade(rwl)
-#define isc_rwlock_downgrade(rwl) isc__rwlock_downgrade(rwl)
#define isc_rwlock_destroy(rwl) isc__rwlock_destroy(rwl)
#endif /* ISC_TRACK_PTHREADS_OBJECTS */
#define isc_rwlock_trylock(rwl, type) isc___rwlock_trylock(rwl, type)
#define isc_rwlock_unlock(rwl, type) isc__rwlock_unlock(rwl, type)
#define isc_rwlock_tryupgrade(rwl) isc___rwlock_tryupgrade(rwl)
-#define isc_rwlock_downgrade(rwl) isc__rwlock_downgrade(rwl)
#define isc_rwlock_destroy(rwl) isc__rwlock_destroy(rwl)
#endif /* USE_PTHREAD_RWLOCK */
PTHREADS_RUNTIME_CHECK(isc___rwlock_unlock, _ret); \
}
-#define isc__rwlock_downgrade(rwl) \
- { \
- int _ret = isc___rwlock_downgrade(rwl); \
- PTHREADS_RUNTIME_CHECK(isc___rwlock_downgrade, _ret); \
- }
-
#define isc__rwlock_destroy(rwl) \
{ \
int _ret = isc___rwlock_destroy(rwl); \
isc_result_t
isc___rwlock_tryupgrade(isc__rwlock_t *rwl);
-int
-isc___rwlock_downgrade(isc__rwlock_t *rwl);
-
int
isc___rwlock_destroy(isc__rwlock_t *rwl);
UNUSED(read_quota);
UNUSED(write_quota);
- ret = pthread_rwlock_init(&rwl->rwlock, NULL);
-
- atomic_init(&rwl->downgrade, false);
+ ret = pthread_rwlock_init(rwl, NULL);
return (ret);
}
int
isc___rwlock_lock(isc__rwlock_t *rwl, isc_rwlocktype_t type) {
- int ret;
-
switch (type) {
case isc_rwlocktype_read:
- return (pthread_rwlock_rdlock(&rwl->rwlock));
+ return (pthread_rwlock_rdlock(rwl));
case isc_rwlocktype_write:
- while (true) {
- ret = pthread_rwlock_wrlock(&rwl->rwlock);
- if (ret != 0) {
- return (ret);
- }
- /* Unlock if in middle of downgrade operation */
- if (atomic_load_acquire(&rwl->downgrade)) {
- ret = pthread_rwlock_unlock(&rwl->rwlock);
- if (ret != 0) {
- return (ret);
- }
- while (atomic_load_acquire(&rwl->downgrade)) {
- }
- continue;
- }
- break;
- }
- return (0);
+ return (pthread_rwlock_wrlock(rwl));
default:
UNREACHABLE();
}
int ret = 0;
switch (type) {
case isc_rwlocktype_read:
- ret = pthread_rwlock_tryrdlock(&rwl->rwlock);
+ ret = pthread_rwlock_tryrdlock(rwl);
break;
case isc_rwlocktype_write:
- ret = pthread_rwlock_trywrlock(&rwl->rwlock);
- if ((ret == 0) && atomic_load_acquire(&rwl->downgrade)) {
- RUNTIME_CHECK(pthread_rwlock_unlock(&rwl->rwlock) == 0);
- return (ISC_R_LOCKBUSY);
- }
+ ret = pthread_rwlock_trywrlock(rwl);
break;
default:
UNREACHABLE();
int
isc___rwlock_unlock(isc__rwlock_t *rwl, isc_rwlocktype_t type) {
UNUSED(type);
- return (pthread_rwlock_unlock(&rwl->rwlock));
+ return (pthread_rwlock_unlock(rwl));
}
isc_result_t
return (ISC_R_LOCKBUSY);
}
-int
-isc___rwlock_downgrade(isc__rwlock_t *rwl) {
- int ret;
-
- atomic_store_release(&rwl->downgrade, true);
-
- ret = pthread_rwlock_unlock(&rwl->rwlock);
- if (ret != 0) {
- return (ret);
- }
-
- ret = pthread_rwlock_rdlock(&rwl->rwlock);
- if (ret != 0) {
- return (ret);
- }
-
- atomic_store_release(&rwl->downgrade, false);
-
- return (0);
-}
-
int
isc___rwlock_destroy(isc__rwlock_t *rwl) {
- return (pthread_rwlock_destroy(&rwl->rwlock));
+ return (pthread_rwlock_destroy(rwl));
}
#else /* if USE_PTHREAD_RWLOCK */
return (ISC_R_SUCCESS);
}
-int
-isc___rwlock_downgrade(isc__rwlock_t *rwl) {
- int32_t prev_readers;
-
- REQUIRE(VALID_RWLOCK(rwl));
-
- /* Become an active reader. */
- prev_readers = atomic_fetch_add_release(&rwl->cnt_and_flag,
- READER_INCR);
- /* We must have been a writer. */
- INSIST((prev_readers & WRITER_ACTIVE) != 0);
-
- /* Complete write */
- atomic_fetch_sub_release(&rwl->cnt_and_flag, WRITER_ACTIVE);
- atomic_fetch_add_release(&rwl->write_completions, 1);
-
- /* Resume other readers */
- LOCK(&rwl->lock);
- if (rwl->readers_waiting > 0) {
- BROADCAST(&rwl->readable);
- }
- UNLOCK(&rwl->lock);
-
- return (0);
-}
-
int
isc___rwlock_unlock(isc__rwlock_t *rwl, isc_rwlocktype_t type) {
int32_t prev_cnt;