summaryrefslogtreecommitdiff
path: root/mysys/thr_mutex.c
diff options
context:
space:
mode:
Diffstat (limited to 'mysys/thr_mutex.c')
-rw-r--r--mysys/thr_mutex.c119
1 files changed, 113 insertions, 6 deletions
diff --git a/mysys/thr_mutex.c b/mysys/thr_mutex.c
index 53ee907e0a3..0a7b9a5c015 100644
--- a/mysys/thr_mutex.c
+++ b/mysys/thr_mutex.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 2000-2003 MySQL AB
+/*
+ Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -11,7 +12,8 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+*/
/* This makes a wrapper for mutex handling to make it easier to debug mutex */
@@ -247,7 +249,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 +261,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 +287,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 +393,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) */