Compare commits

...

3 Commits

Author SHA1 Message Date
Ondřej Surý
b13b985a47 Disable thread sanitizer in problematic functions 2018-12-19 14:34:10 +01:00
Ondřej Surý
1b4fb20f5a Implement isc_rwlock_downgrade using pthreads and single atomic_bool 2018-12-19 14:34:10 +01:00
Ondřej Surý
cb2aeff9d2 Use simple pthread_rwlock in place of our custom adaptive rwlock 2018-12-19 14:30:56 +01:00
7 changed files with 126 additions and 13 deletions

View File

@@ -309,6 +309,9 @@
/* Have PTHREAD_PRIO_INHERIT. */
#undef HAVE_PTHREAD_PRIO_INHERIT
/* Define to 1 if you have the `pthread_rwlock_rdlock' function. */
#undef HAVE_PTHREAD_RWLOCK_RDLOCK
/* Define to 1 if you have the `pthread_setaffinity_np' function. */
#undef HAVE_PTHREAD_SETAFFINITY_NP

15
configure vendored
View File

@@ -15309,12 +15309,17 @@ $as_echo "no" >&6; }
esac
#
# If PIC is disabled, shared libraries must also be
#
if test "$pic_mode" = "no"; then :
enable_shared="no"
for ac_func in pthread_rwlock_rdlock
do :
ac_fn_c_check_func "$LINENO" "pthread_rwlock_rdlock" "ac_cv_func_pthread_rwlock_rdlock"
if test "x$ac_cv_func_pthread_rwlock_rdlock" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_PTHREAD_RWLOCK_RDLOCK 1
_ACEOF
fi
done
CRYPTO=OpenSSL

View File

@@ -705,11 +705,7 @@ case $use_libtool in
esac
AC_SUBST(INSTALL_LIBRARY)
#
# If PIC is disabled, shared libraries must also be
#
AS_IF([test "$pic_mode" = "no"],
[enable_shared="no"])
AC_CHECK_FUNCS([pthread_rwlock_rdlock])
CRYPTO=OpenSSL

View File

@@ -14,6 +14,7 @@
#define ISC_RWLOCK_H 1
#include <inttypes.h>
#include <pthread.h>
/*! \file isc/rwlock.h */
@@ -31,11 +32,20 @@ typedef enum {
isc_rwlocktype_write
} isc_rwlocktype_t;
#if HAVE_PTHREAD_RWLOCK_RDLOCK
struct isc_rwlock {
pthread_rwlock_t rwlock;
atomic_bool downgrade;
};
#else /* HAVE_PTHREAD_RWLOCK_RDLOCK */
struct isc_rwlock {
/* Unlocked. */
unsigned int magic;
isc_mutex_t lock;
int32_t spins;
int32_t spins;
/*
* When some atomic instructions with hardware assistance are
@@ -68,6 +78,8 @@ struct isc_rwlock {
};
#endif /* HAVE_PTHREAD_RWLOCK_RDLOCK */
isc_result_t
isc_rwlock_init(isc_rwlock_t *rwl, unsigned int read_quota,
unsigned int write_quota);

View File

@@ -26,6 +26,101 @@
#include <isc/rwlock.h>
#include <isc/util.h>
#if HAVE_PTHREAD_RWLOCK_RDLOCK
#include <errno.h>
#include <pthread.h>
isc_result_t
isc_rwlock_init(isc_rwlock_t *rwl, unsigned int read_quota,
unsigned int write_quota)
{
UNUSED(read_quota);
UNUSED(write_quota);
REQUIRE(pthread_rwlock_init(&rwl->rwlock, NULL) == 0);
atomic_init(&rwl->downgrade, false);
return (ISC_R_SUCCESS);
}
isc_result_t
isc_rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
switch (type) {
case isc_rwlocktype_read:
REQUIRE(pthread_rwlock_rdlock(&rwl->rwlock) == 0);
break;
case isc_rwlocktype_write:
while (true) {
REQUIRE(pthread_rwlock_wrlock(&rwl->rwlock) == 0);
/* Unlock if in middle of downgrade operation */
if (atomic_load(&rwl->downgrade)) {
isc_rwlock_unlock(rwl, type);
while (atomic_load(&rwl->downgrade));
continue;
}
break;
}
break;
default:
INSIST(0);
ISC_UNREACHABLE();
}
return (ISC_R_SUCCESS);
}
isc_result_t
isc_rwlock_trylock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
int ret = 0;
switch (type) {
case isc_rwlocktype_read:
ret = pthread_rwlock_tryrdlock(&rwl->rwlock);
break;
case isc_rwlocktype_write:
ret = pthread_rwlock_trywrlock(&rwl->rwlock);
if ((ret == 0) && atomic_load(&rwl->downgrade)) {
isc_rwlock_unlock(rwl, type);
return (ISC_R_LOCKBUSY);
}
break;
default: INSIST(0);
}
switch (ret) {
case 0: return (ISC_R_SUCCESS);
case EBUSY: return (ISC_R_LOCKBUSY);
case EAGAIN: return (ISC_R_LOCKBUSY);
default: INSIST(0); ISC_UNREACHABLE();
}
}
isc_result_t
isc_rwlock_unlock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
UNUSED(type);
REQUIRE(pthread_rwlock_unlock(&rwl->rwlock) == 0);
return (ISC_R_SUCCESS);
}
isc_result_t
isc_rwlock_tryupgrade(isc_rwlock_t *rwl) {
isc_rwlock_unlock(rwl, isc_rwlocktype_read);
return (isc_rwlock_trylock(rwl, isc_rwlocktype_write));
}
void
isc_rwlock_downgrade(isc_rwlock_t *rwl) {
atomic_store(&rwl->downgrade, true);
isc_rwlock_unlock(rwl, isc_rwlocktype_write);
isc_rwlock_lock(rwl, isc_rwlocktype_read);
atomic_store(&rwl->downgrade, false);
}
void
isc_rwlock_destroy(isc_rwlock_t *rwl) {
pthread_rwlock_destroy(&rwl->rwlock);
}
#else
#define RWLOCK_MAGIC ISC_MAGIC('R', 'W', 'L', 'k')
#define VALID_RWLOCK(rwl) ISC_MAGIC_VALID(rwl, RWLOCK_MAGIC)
@@ -558,3 +653,5 @@ isc_rwlock_unlock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
return (ISC_R_SUCCESS);
}
#endif /* HAVE_PTHREAD_RWLOCK_RDLOCK */

View File

@@ -959,7 +959,7 @@ push_readyq(isc__taskmgr_t *manager, isc__task_t *task, int c) {
}
static void
dispatch(isc__taskmgr_t *manager, unsigned int threadid) {
dispatch(isc__taskmgr_t *manager, unsigned int threadid) __attribute__((no_sanitize("thread"))) {
isc__task_t *task;
REQUIRE(VALID_MANAGER(manager));

View File

@@ -869,7 +869,7 @@ unwatch_fd(isc__socketthread_t *thread, int fd, int msg) {
* on a fd provided
*/
static void
wakeup_socket(isc__socketthread_t *thread, int fd, int msg) {
wakeup_socket(isc__socketthread_t *thread, int fd, int msg) __attribute__((no_sanitize("thread"))) {
isc_result_t result;
int lockid = FDLOCK_ID(fd);