List:Commits« Previous MessageNext Message »
From:Davi Arnaut Date:October 9 2008 12:17am
Subject:bzr commit into mysql-5.1 branch (davi:2770) Bug#38941
View as plain text  
# At a local mysql-5.1 repository of davi

 2770 Davi Arnaut	2008-10-08
      Bug#38941: fast mutexes in MySQL 5.1 have mutex contention when calling random()
      
      The problem is that MySQL's 'fast' mutex implementation uses the
      random() routine to determine the spin delay. Unfortunately, the
      routine interface is not thead-safe and some implementations (eg:
      glibc) might use a internal lock to protect the RNG state, causing
      excessive locking contention if lots of threads are spinning on
      a MySQL's 'fast' mutex.
      
      The solution is to use the quite simple Park–Miller random number
      generator with a initial seed set to 1 as the the previously used
      generator wasn't being seeded -- the initial seed is 1 if srandom()
      is not called.
      
      Futhermore, the 'fast' mutex implementation has several shortcomings
      and provides no measurable performance benefit. Since nowadays most
      platforms offer support for adaptive locks, MySQL's 'fast' mutex is
      going to be removed in MySQL 6.0.
modified:
  include/my_pthread.h
  mysys/thr_mutex.c

per-file messages:
  include/my_pthread.h
    Add field to keep the RNG state.
  mysys/thr_mutex.c
    Use a palliative per-mutex rng state to determine the spin delay.
    The RNG is not thread-safe but jumping a few sequences in the RNG
    is harmless.
=== modified file 'include/my_pthread.h'
--- a/include/my_pthread.h	2008-03-19 18:52:22 +0000
+++ b/include/my_pthread.h	2008-10-09 00:16:51 +0000
@@ -519,6 +519,7 @@ typedef struct st_my_pthread_fastmutex_t
 {
   pthread_mutex_t mutex;
   uint spins;
+  uint rng_state;
 } my_pthread_fastmutex_t;
 void fastmutex_global_init(void);
 

=== modified file 'mysys/thr_mutex.c'
--- a/mysys/thr_mutex.c	2007-10-09 12:48:49 +0000
+++ b/mysys/thr_mutex.c	2008-10-09 00:16:51 +0000
@@ -438,9 +438,16 @@ int my_pthread_fastmutex_init(my_pthread
     mp->spins= MY_PTHREAD_FASTMUTEX_SPINS; 
   else
     mp->spins= 0;
+  mp->rng_state= 1;
   return pthread_mutex_init(&mp->mutex, attr); 
 }
 
+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;
@@ -458,8 +465,7 @@ int my_pthread_fastmutex_lock(my_pthread
       return res;
 
     mutex_delay(maxdelay);
-    maxdelay += ((double) random() / (double) RAND_MAX) * 
-	        MY_PTHREAD_FASTMUTEX_DELAY + 1;
+    maxdelay += park_rng(mp) * MY_PTHREAD_FASTMUTEX_DELAY + 1;
   }
   return pthread_mutex_lock(&mp->mutex);
 }

Thread
bzr commit into mysql-5.1 branch (davi:2770) Bug#38941Davi Arnaut9 Oct
  • Re: bzr commit into mysql-5.1 branch (davi:2770) Bug#38941Konstantin Osipov14 Oct