Commit 59b46046 authored by unknown's avatar unknown
Browse files

Fast mutexes implementation

(spin-loop inside pthread_mutex_lock).

thr_mutex.c:
  Added spinloop in mutex_lock
my_pthread.h:
  Added definition of my_pthread_fastmutex_t
configure.in:
  Added --with-fast-mutexes switch


configure.in:
  Added --with-fast-mutexes switch
include/my_pthread.h:
  Added definition of my_pthread_fastmutex_t
mysys/thr_mutex.c:
  Added spinloop in mutex_lock
parent a62aaaef
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -1574,6 +1574,20 @@ else
  CXXFLAGS="$OPTIMIZE_CXXFLAGS -DDBUG_OFF $CXXFLAGS"
fi

if test "$with_debug" = "no"
then
  AC_ARG_WITH([fast-mutexes],
              AC_HELP_STRING([--with-fast-mutexes], 
              [compile with fast mutexes (default is enabled)]),
              [with_fast_mutexes=$withval], [with_fast_mutexes=yes])
fi

if test "$with_fast_mutexes" = "yes"
then
  AC_DEFINE([MY_PTHREAD_FASTMUTEX], [1], 
            [Define to 1 if you want to use fast mutexes])
fi

# Force static compilation to avoid linking problems/get more speed
AC_ARG_WITH(mysqld-ldflags,
    [  --with-mysqld-ldflags   Extra linking arguments for mysqld],
+31 −0
Original line number Diff line number Diff line
@@ -547,6 +547,37 @@ void safe_mutex_end(FILE *file);
#define safe_mutex_assert_not_owner(mp)
#endif /* SAFE_MUTEX */

#if defined(MY_PTHREAD_FASTMUTEX) && !defined(SAFE_MUTEX)
typedef struct st_my_pthread_fastmutex_t
{
  pthread_mutex_t mutex;
  uint spins;
} my_pthread_fastmutex_t;

int my_pthread_fastmutex_init(my_pthread_fastmutex_t *mp, 
                              const pthread_mutexattr_t *attr);
int my_pthread_fastmutex_lock(my_pthread_fastmutex_t *mp);

#undef pthread_mutex_init
#undef pthread_mutex_lock
#undef pthread_mutex_unlock
#undef pthread_mutex_destroy
#undef pthread_mutex_wait
#undef pthread_mutex_timedwait
#undef pthread_mutex_t
#undef pthread_cond_wait
#undef pthread_cond_timedwait
#undef pthread_mutex_trylock
#define pthread_mutex_init(A,B) my_pthread_fastmutex_init((A),(B))
#define pthread_mutex_lock(A) my_pthread_fastmutex_lock(A)
#define pthread_mutex_unlock(A) pthread_mutex_unlock(&(A)->mutex)
#define pthread_mutex_destroy(A) pthread_mutex_destroy(&(A)->mutex)
#define pthread_cond_wait(A,B) pthread_cond_wait((A),&(B)->mutex)
#define pthread_cond_timedwait(A,B,C) pthread_cond_timedwait((A),&(B)->mutex,(C))
#define pthread_mutex_trylock(A) pthread_mutex_trylock(&(A)->mutex)
#define pthread_mutex_t my_pthread_fastmutex_t
#endif /* defined(MY_PTHREAD_FASTMUTEX) && !defined(SAFE_MUTEX) */

	/* READ-WRITE thread locking */

#ifdef HAVE_BROKEN_RWLOCK			/* For OpenUnix */
+77 −0
Original line number Diff line number Diff line
@@ -356,3 +356,80 @@ 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

int my_pthread_fastmutex_init(my_pthread_fastmutex_t *mp,
                              const pthread_mutexattr_t *attr)
{
  static int cpu_count= 0;
#ifdef _SC_NPROCESSORS_CONF
  if (!cpu_count && (attr == MY_MUTEX_INIT_FAST))
    cpu_count= sysconf(_SC_NPROCESSORS_CONF);
#endif
  
  if ((cpu_count > 1) && (attr == MY_MUTEX_INIT_FAST))
    mp->spins= MY_PTHREAD_FASTMUTEX_SPINS; 
  else
    mp->spins= 0;
  return pthread_mutex_init(&mp->mutex, attr); 
}

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 += ((double) random() / (double) RAND_MAX) * 
	        MY_PTHREAD_FASTMUTEX_DELAY + 1;
  }
  return pthread_mutex_lock(&mp->mutex);
}
#endif /* defined(THREAD) && defined(MY_PTHREAD_FASTMUTEX) && !defined(SAFE_MUTEX) */