diff options
Diffstat (limited to 'mysys/thr_mutex.c')
-rw-r--r-- | mysys/thr_mutex.c | 113 |
1 files changed, 109 insertions, 4 deletions
diff --git a/mysys/thr_mutex.c b/mysys/thr_mutex.c index 53ee907e0a3..c7600b58c95 100644 --- a/mysys/thr_mutex.c +++ b/mysys/thr_mutex.c @@ -247,7 +247,7 @@ int safe_cond_wait(pthread_cond_t *cond, safe_mutex_t *mp, const char *file, { fprintf(stderr, "safe_mutex: Count was %d in thread 0x%lx when locking mutex at %s, line %d\n", - mp->count-1, my_thread_id(), file, line); + mp->count-1, my_thread_dbug_id(), file, line); fflush(stderr); abort(); } @@ -259,8 +259,8 @@ int safe_cond_wait(pthread_cond_t *cond, safe_mutex_t *mp, const char *file, int safe_cond_timedwait(pthread_cond_t *cond, safe_mutex_t *mp, - struct timespec *abstime, - const char *file, uint line) + const struct timespec *abstime, + const char *file, uint line) { int error; pthread_mutex_lock(&mp->global); @@ -285,7 +285,7 @@ int safe_cond_timedwait(pthread_cond_t *cond, safe_mutex_t *mp, { fprintf(stderr, "safe_mutex: Count was %d in thread 0x%lx when locking mutex at %s, line %d (error: %d (%d))\n", - mp->count-1, my_thread_id(), file, line, error, error); + mp->count-1, my_thread_dbug_id(), file, line, error, error); fflush(stderr); abort(); } @@ -391,3 +391,108 @@ void safe_mutex_end(FILE *file __attribute__((unused))) } #endif /* THREAD && SAFE_MUTEX */ + +#if defined(THREAD) && defined(MY_PTHREAD_FASTMUTEX) && !defined(SAFE_MUTEX) + +#include "mysys_priv.h" +#include "my_static.h" +#include <m_string.h> + +#include <m_ctype.h> +#include <hash.h> +#include <myisampack.h> +#include <mysys_err.h> +#include <my_sys.h> + +#undef pthread_mutex_t +#undef pthread_mutex_init +#undef pthread_mutex_lock +#undef pthread_mutex_trylock +#undef pthread_mutex_unlock +#undef pthread_mutex_destroy +#undef pthread_cond_wait +#undef pthread_cond_timedwait + +ulong mutex_delay(ulong delayloops) +{ + ulong i; + volatile ulong j; + + j = 0; + + for (i = 0; i < delayloops * 50; i++) + j += i; + + return(j); +} + +#define MY_PTHREAD_FASTMUTEX_SPINS 8 +#define MY_PTHREAD_FASTMUTEX_DELAY 4 + +static int cpu_count= 0; + +int my_pthread_fastmutex_init(my_pthread_fastmutex_t *mp, + const pthread_mutexattr_t *attr) +{ + if ((cpu_count > 1) && (attr == MY_MUTEX_INIT_FAST)) + mp->spins= MY_PTHREAD_FASTMUTEX_SPINS; + else + mp->spins= 0; + mp->rng_state= 1; + return pthread_mutex_init(&mp->mutex, attr); +} + +/** + Park-Miller random number generator. A simple linear congruential + generator that operates in multiplicative group of integers modulo n. + + x_{k+1} = (x_k g) mod n + + Popular pair of parameters: n = 2^32 − 5 = 4294967291 and g = 279470273. + The period of the generator is about 2^31. + Largest value that can be returned: 2147483646 (RAND_MAX) + + Reference: + + S. K. Park and K. W. Miller + "Random number generators: good ones are hard to find" + Commun. ACM, October 1988, Volume 31, No 10, pages 1192-1201. +*/ + +static double park_rng(my_pthread_fastmutex_t *mp) +{ + mp->rng_state= ((my_ulonglong)mp->rng_state * 279470273U) % 4294967291U; + return (mp->rng_state / 2147483647.0); +} + +int my_pthread_fastmutex_lock(my_pthread_fastmutex_t *mp) +{ + int res; + uint i; + uint maxdelay= MY_PTHREAD_FASTMUTEX_DELAY; + + for (i= 0; i < mp->spins; i++) + { + res= pthread_mutex_trylock(&mp->mutex); + + if (res == 0) + return 0; + + if (res != EBUSY) + return res; + + mutex_delay(maxdelay); + maxdelay += park_rng(mp) * MY_PTHREAD_FASTMUTEX_DELAY + 1; + } + return pthread_mutex_lock(&mp->mutex); +} + + +void fastmutex_global_init(void) +{ +#ifdef _SC_NPROCESSORS_CONF + cpu_count= sysconf(_SC_NPROCESSORS_CONF); +#endif +} + +#endif /* defined(THREAD) && defined(MY_PTHREAD_FASTMUTEX) && !defined(SAFE_MUTEX) */ |