*rwl = malloc(sizeof(**rwl)); \
isc__rwlock_init(*rwl, rq, wq); \
}
-#define isc_rwlock_lock(rwl, type) isc___rwlock_lock(*rwl, type)
+#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_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_downgrade(rwl) isc__rwlock_downgrade(*rwl)
#define isc_rwlock_destroy(rwl) \
{ \
isc___rwlock_destroy(*rwl); \
typedef struct isc_rwlock 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_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_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)
+#define isc_rwlock_downgrade(rwl) isc__rwlock_downgrade(rwl)
+#define isc_rwlock_destroy(rwl) isc__rwlock_destroy(rwl)
#endif /* ISC_TRACK_PTHREADS_OBJECTS */
typedef struct isc_rwlock 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_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_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)
+#define isc_rwlock_downgrade(rwl) isc__rwlock_downgrade(rwl)
+#define isc_rwlock_destroy(rwl) isc__rwlock_destroy(rwl)
#endif /* USE_PTHREAD_RWLOCK */
ERRNO_CHECK(isc___rwlock_init, _ret); \
}
+#define isc__rwlock_lock(rwl, type) \
+ { \
+ int _ret = isc___rwlock_lock(rwl, type); \
+ ERRNO_CHECK(isc___rwlock_lock, _ret); \
+ }
+
+#define isc__rwlock_unlock(rwl, type) \
+ { \
+ int _ret = isc___rwlock_unlock(rwl, type); \
+ ERRNO_CHECK(isc___rwlock_unlock, _ret); \
+ }
+
+#define isc__rwlock_downgrade(rwl) \
+ { \
+ int _ret = isc___rwlock_downgrade(rwl); \
+ ERRNO_CHECK(isc___rwlock_downgrade, _ret); \
+ }
+
+#define isc__rwlock_destroy(rwl) \
+ { \
+ int _ret = isc___rwlock_destroy(rwl); \
+ ERRNO_CHECK(isc___rwlock_destroy, _ret); \
+ }
+
int
isc___rwlock_init(isc__rwlock_t *rwl, unsigned int read_quota,
unsigned int write_quota);
-void
+int
isc___rwlock_lock(isc__rwlock_t *rwl, isc_rwlocktype_t type);
isc_result_t
isc___rwlock_trylock(isc__rwlock_t *rwl, isc_rwlocktype_t type);
-void
+int
isc___rwlock_unlock(isc__rwlock_t *rwl, isc_rwlocktype_t type);
isc_result_t
isc___rwlock_tryupgrade(isc__rwlock_t *rwl);
-void
+int
isc___rwlock_downgrade(isc__rwlock_t *rwl);
-void
+int
isc___rwlock_destroy(isc__rwlock_t *rwl);
ISC_LANG_ENDDECLS
return (ret);
}
-void
+int
isc___rwlock_lock(isc__rwlock_t *rwl, isc_rwlocktype_t type) {
+ int ret;
+
switch (type) {
case isc_rwlocktype_read:
- RUNTIME_CHECK(pthread_rwlock_rdlock(&rwl->rwlock) == 0);
- break;
+ return (pthread_rwlock_rdlock(&rwl->rwlock));
case isc_rwlocktype_write:
while (true) {
- RUNTIME_CHECK(pthread_rwlock_wrlock(&rwl->rwlock) == 0);
+ ret = pthread_rwlock_wrlock(&rwl->rwlock);
+ if (ret != 0) {
+ return (ret);
+ }
/* Unlock if in middle of downgrade operation */
if (atomic_load_acquire(&rwl->downgrade)) {
- RUNTIME_CHECK(pthread_rwlock_unlock(
- &rwl->rwlock) == 0);
+ ret = pthread_rwlock_unlock(&rwl->rwlock);
+ if (ret != 0) {
+ return (ret);
+ }
while (atomic_load_acquire(&rwl->downgrade)) {
}
continue;
}
break;
}
- break;
+ return (0);
default:
UNREACHABLE();
}
}
}
-void
+int
isc___rwlock_unlock(isc__rwlock_t *rwl, isc_rwlocktype_t type) {
UNUSED(type);
- RUNTIME_CHECK(pthread_rwlock_unlock(&rwl->rwlock) == 0);
+ return (pthread_rwlock_unlock(&rwl->rwlock));
}
isc_result_t
return (ISC_R_LOCKBUSY);
}
-void
+int
isc___rwlock_downgrade(isc__rwlock_t *rwl) {
+ int ret;
+
atomic_store_release(&rwl->downgrade, true);
- RUNTIME_CHECK(pthread_rwlock_unlock(&rwl->rwlock) == 0);
- RUNTIME_CHECK(pthread_rwlock_rdlock(&rwl->rwlock) == 0);
+
+ 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);
}
-void
+int
isc___rwlock_destroy(isc__rwlock_t *rwl) {
- pthread_rwlock_destroy(&rwl->rwlock);
+ return (pthread_rwlock_destroy(&rwl->rwlock));
}
#else /* if USE_PTHREAD_RWLOCK */
return (0);
}
-void
+int
isc___rwlock_destroy(isc__rwlock_t *rwl) {
REQUIRE(VALID_RWLOCK(rwl));
isc_condition_destroy(&rwl->readable);
isc_condition_destroy(&rwl->writeable);
isc_mutex_destroy(&rwl->lock);
+
+ return (0);
}
/*
#endif /* ifdef ISC_RWLOCK_TRACE */
}
-void
+int
isc___rwlock_lock(isc__rwlock_t *rwl, isc_rwlocktype_t type) {
int32_t cnt = 0;
int32_t spins = atomic_load_acquire(&rwl->spins) * 2 + 10;
} while (isc_rwlock_trylock(rwl, type) != ISC_R_SUCCESS);
atomic_fetch_add_release(&rwl->spins, (cnt - spins) / 8);
+
+ return (0);
}
isc_result_t
return (ISC_R_SUCCESS);
}
-void
+int
isc___rwlock_downgrade(isc__rwlock_t *rwl) {
int32_t prev_readers;
BROADCAST(&rwl->readable);
}
UNLOCK(&rwl->lock);
+
+ return (0);
}
-void
+int
isc___rwlock_unlock(isc__rwlock_t *rwl, isc_rwlocktype_t type) {
int32_t prev_cnt;
#ifdef ISC_RWLOCK_TRACE
print_lock("postunlock", rwl, type);
#endif /* ifdef ISC_RWLOCK_TRACE */
+
+ return (0);
}
#endif /* USE_PTHREAD_RWLOCK */