From: Witold Kręcicki Date: Tue, 13 Nov 2018 23:03:30 +0000 (+0000) Subject: Add an option to have 64-byte (cache line) aligned mutexes. X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=refs%2Fheads%2Fwpk-aligned-mutexes;p=thirdparty%2Fbind9.git Add an option to have 64-byte (cache line) aligned mutexes. --- diff --git a/lib/isc/pthreads/condition.c b/lib/isc/pthreads/condition.c index 4a9fa9499a4..a80ac97dc66 100644 --- a/lib/isc/pthreads/condition.c +++ b/lib/isc/pthreads/condition.c @@ -53,7 +53,7 @@ isc_condition_waituntil(isc_condition_t *c, isc_mutex_t *m, isc_time_t *t) { ts.tv_nsec = (long)isc_time_nanoseconds(t); do { -#if ISC_MUTEX_PROFILE +#if ISC_MUTEX_STRUCT presult = pthread_cond_timedwait(c, &m->mutex, &ts); #else presult = pthread_cond_timedwait(c, m, &ts); diff --git a/lib/isc/pthreads/include/isc/condition.h b/lib/isc/pthreads/include/isc/condition.h index 28338c7fdf8..22ddcad57ec 100644 --- a/lib/isc/pthreads/include/isc/condition.h +++ b/lib/isc/pthreads/include/isc/condition.h @@ -26,7 +26,7 @@ typedef pthread_cond_t isc_condition_t; ((pthread_cond_init((cp), NULL) == 0) ? \ ISC_R_SUCCESS : ISC_R_UNEXPECTED) -#if ISC_MUTEX_PROFILE +#if ISC_MUTEX_STRUCT #define isc_condition_wait(cp, mp) \ ((pthread_cond_wait((cp), &((mp)->mutex)) == 0) ? \ ISC_R_SUCCESS : ISC_R_UNEXPECTED) diff --git a/lib/isc/pthreads/include/isc/mutex.h b/lib/isc/pthreads/include/isc/mutex.h index 6c34a69c470..1851253904e 100644 --- a/lib/isc/pthreads/include/isc/mutex.h +++ b/lib/isc/pthreads/include/isc/mutex.h @@ -37,6 +37,15 @@ extern pthread_mutexattr_t isc__mutex_attrs; /* XXX We could do fancier error handling... */ +/*! + * Define ISC_MUTEX_STRUCT to turn on padding of isc_mutex_t to cache + * line size, so that no two mutexes are ever in the same cache line. + * We assume that cache line is 64bytes here. + */ +#ifndef ISC_MUTEX_STRUCT +#define ISC_MUTEX_STRUCT 1 +#endif +#define ISC_MUTEX_STRUCT_PAD (64-sizeof(pthread_mutex_t)-sizeof(void*)) /*! * Define ISC_MUTEX_PROFILE to turn on profiling of mutexes by line. When * enabled, isc_mutex_stats() can be used to print a table showing the @@ -48,11 +57,16 @@ extern pthread_mutexattr_t isc__mutex_attrs; #endif #if ISC_MUTEX_PROFILE +#define ISC_MUTEX_STRUCT 1 +#endif + +#if ISC_MUTEX_STRUCT typedef struct isc_mutexstats isc_mutexstats_t; typedef struct { pthread_mutex_t mutex; /*%< The actual mutex. */ isc_mutexstats_t * stats; /*%< Mutex statistics. */ + char pad[ISC_MUTEX_STRUCT_PAD]; } isc_mutex_t; #else typedef pthread_mutex_t isc_mutex_t; @@ -76,6 +90,10 @@ isc_result_t isc__mutex_init(isc_mutex_t *mp, const char *file, unsigned int lin #if ISC_MUTEX_PROFILE #define isc_mutex_lock(mp) \ isc_mutex_lock_profile((mp), __FILE__, __LINE__) +#elif ISC_MUTEX_STRUCT +#define isc_mutex_lock(mp) \ + ((pthread_mutex_lock(&(mp)->mutex) == 0) ? \ + ISC_R_SUCCESS : ISC_R_UNEXPECTED) #else #define isc_mutex_lock(mp) \ ((pthread_mutex_lock((mp)) == 0) ? \ @@ -85,13 +103,17 @@ isc_result_t isc__mutex_init(isc_mutex_t *mp, const char *file, unsigned int lin #if ISC_MUTEX_PROFILE #define isc_mutex_unlock(mp) \ isc_mutex_unlock_profile((mp), __FILE__, __LINE__) +#elif ISC_MUTEX_STRUCT +#define isc_mutex_unlock(mp) \ + ((pthread_mutex_unlock(&(mp)->mutex) == 0) ? \ + ISC_R_SUCCESS : ISC_R_UNEXPECTED) #else #define isc_mutex_unlock(mp) \ ((pthread_mutex_unlock((mp)) == 0) ? \ ISC_R_SUCCESS : ISC_R_UNEXPECTED) #endif -#if ISC_MUTEX_PROFILE +#if ISC_MUTEX_STRUCT #define isc_mutex_trylock(mp) \ ((pthread_mutex_trylock((&(mp)->mutex)) == 0) ? \ ISC_R_SUCCESS : ISC_R_LOCKBUSY) @@ -101,7 +123,7 @@ isc_result_t isc__mutex_init(isc_mutex_t *mp, const char *file, unsigned int lin ISC_R_SUCCESS : ISC_R_LOCKBUSY) #endif -#if ISC_MUTEX_PROFILE +#if ISC_MUTEX_STRUCT #define isc_mutex_destroy(mp) \ ((pthread_mutex_destroy((&(mp)->mutex)) == 0) ? \ ISC_R_SUCCESS : ISC_R_UNEXPECTED) diff --git a/lib/isc/pthreads/mutex.c b/lib/isc/pthreads/mutex.c index 76bac089b69..cef71d505d3 100644 --- a/lib/isc/pthreads/mutex.c +++ b/lib/isc/pthreads/mutex.c @@ -284,10 +284,17 @@ isc__mutex_init(isc_mutex_t *mp, const char *file, unsigned int line) { #ifdef HAVE_PTHREAD_MUTEX_ADAPTIVE_NP result = isc_once_do(&once_attr, initialize_attr); RUNTIME_CHECK(result == ISC_R_SUCCESS); - +#ifdef ISC_MUTEX_STRUCT + err = pthread_mutex_init(&mp->mutex, &attr); +#else err = pthread_mutex_init(mp, &attr); +#endif #else /* HAVE_PTHREAD_MUTEX_ADAPTIVE_NP */ +#ifdef ISC_MUTEX_STRUCT + err = pthread_mutex_init(&mp->mutex, ISC__MUTEX_ATTRS); +#else err = pthread_mutex_init(mp, ISC__MUTEX_ATTRS); +#endif #endif /* HAVE_PTHREAD_MUTEX_ADAPTIVE_NP */ if (err == ENOMEM)