/* 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
#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;
#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) ? \
#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)
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)
#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)