List:Commits« Previous MessageNext Message »
From:Davi Arnaut Date:October 16 2008 12:23am
Subject:bzr push into mysql-5.1 branch (davi:2668 to 2669) Bug#38941
View as plain text  
 2669 Davi Arnaut	2008-10-15
      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 code was also misusing the value
      of the RAND_MAX macro, this macro represents the largest value
      that can be returned from the rand() function, not random().
      
      The solution is to use the quite simple Park-Miller random number
      generator. The initial seed is set to 1 because 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. Therefore, its use is
      not recommended unless it provides directly measurable results.
modified:
  include/my_pthread.h
  mysys/thr_mutex.c

 2668 Horst Hunger	2008-10-15 [merge]
      Merge to update the tree before a push.
modified:
  sql/sql_insert.cc

=== 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-15 22:21:00 +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-15 22:21:00 +0000
@@ -438,9 +438,33 @@ 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); 
 }
 
+/**
+  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;
@@ -458,8 +482,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 push into mysql-5.1 branch (davi:2668 to 2669) Bug#38941Davi Arnaut16 Oct