List:Commits« Previous MessageNext Message »
From:Dmitry Lenev Date:September 3 2010 11:06am
Subject:bzr commit into mysql-5.5-runtime branch (dlenev:3132) Bug#56405
View as plain text  
#At file:///home/dlenev/src/bzr/mysql-5.5-rt-exp2/ based on revid:jon.hauglid@stripped

 3132 Dmitry Lenev	2010-09-03
      Alternative draft fix Bug #56405 "Deadlock in the MDL deadlock
      detector".
      
      Changed rwlock which prefers reader to disallow situation
      in which lock can be owned by reader and there are readers
      waiting.
      
      The intent behing this commit is to study performance
      implications of such approach to fixing this bug.

    modified:
      include/my_pthread.h
      mysys/thr_rwlock.c
=== modified file 'include/my_pthread.h'
--- a/include/my_pthread.h	2010-08-10 21:12:01 +0000
+++ b/include/my_pthread.h	2010-09-03 11:05:39 +0000
@@ -612,7 +612,9 @@ int my_pthread_fastmutex_lock(my_pthread
   Required by some algorithms in order to provide correctness.
 */
 
-#if defined(HAVE_PTHREAD_RWLOCK_RDLOCK) && defined(HAVE_PTHREAD_RWLOCKATTR_SETKIND_NP)
+#define USE_MY_PR_LOCK 1
+
+#if defined(HAVE_PTHREAD_RWLOCK_RDLOCK) && defined(HAVE_PTHREAD_RWLOCKATTR_SETKIND_NP) && !defined(USE_MY_PR_LOCK)
 /*
   On systems which have a way to specify that readers should
   be preferred through attribute mechanism (e.g. Linux) we use
@@ -655,7 +657,8 @@ typedef struct st_my_rw_lock_t {
 	pthread_cond_t	readers;	/* waiting readers		*/
 	pthread_cond_t	writers;	/* waiting writers		*/
 	int		state;		/* -1:writer,0:free,>0:readers	*/
-	int             waiters;        /* number of waiting writers	*/
+	int             read_waiters;   /* number of waiting readers	*/
+	int             write_waiters;  /* number of waiting writers	*/
 	my_bool         prefer_readers;
 #ifdef SAFE_MUTEX
         pthread_t       write_thread;

=== modified file 'mysys/thr_rwlock.c'
--- a/mysys/thr_rwlock.c	2010-08-12 13:50:23 +0000
+++ b/mysys/thr_rwlock.c	2010-09-03 11:05:39 +0000
@@ -70,7 +70,8 @@ int my_rw_init(my_rw_lock_t *rwp, my_boo
   pthread_condattr_destroy(&cond_attr);
 
   rwp->state	= 0;
-  rwp->waiters	= 0;
+  rwp->read_waiters= 0;
+  rwp->write_waiters= 0;
 #ifdef SAFE_MUTEX
   rwp->write_thread   = 0;
 #endif
@@ -94,12 +95,14 @@ int my_rw_destroy(my_rw_lock_t *rwp)
 int my_rw_rdlock(my_rw_lock_t *rwp)
 {
   pthread_mutex_lock(&rwp->lock);
+  rwp->read_waiters++;
 
   /* active or queued writers */
   while (( rwp->state < 0 ) ||
-         (rwp->waiters && ! rwp->prefer_readers))
+         (rwp->write_waiters && ! rwp->prefer_readers))
     pthread_cond_wait( &rwp->readers, &rwp->lock);
 
+  rwp->read_waiters--;
   rwp->state++;
   pthread_mutex_unlock(&rwp->lock);
   return(0);
@@ -110,7 +113,7 @@ int my_rw_tryrdlock(my_rw_lock_t *rwp)
   int res;
   pthread_mutex_lock(&rwp->lock);
   if ((rwp->state < 0 ) ||
-      (rwp->waiters && ! rwp->prefer_readers))
+      (rwp->write_waiters && ! rwp->prefer_readers))
     res= EBUSY;					/* Can't get lock */
   else
   {
@@ -125,14 +128,14 @@ int my_rw_tryrdlock(my_rw_lock_t *rwp)
 int my_rw_wrlock(my_rw_lock_t *rwp)
 {
   pthread_mutex_lock(&rwp->lock);
-  rwp->waiters++;				/* another writer queued */
+  rwp->write_waiters++;				/* another writer queued */
 
   my_rw_lock_assert_not_write_owner(rwp);
 
   while (rwp->state)
     pthread_cond_wait(&rwp->writers, &rwp->lock);
   rwp->state	= -1;
-  rwp->waiters--;
+  rwp->write_waiters--;
 #ifdef SAFE_MUTEX
   rwp->write_thread= pthread_self();
 #endif
@@ -163,7 +166,8 @@ int my_rw_trywrlock(my_rw_lock_t *rwp)
 int my_rw_unlock(my_rw_lock_t *rwp)
 {
   DBUG_PRINT("rw_unlock",
-	     ("state: %d waiters: %d", rwp->state, rwp->waiters));
+	     ("state: %d write_waiters: %d read_waiters: %d",
+              rwp->state, rwp->write_waiters, rwp->read_waiters));
   pthread_mutex_lock(&rwp->lock);
 
   DBUG_ASSERT(rwp->state != 0);
@@ -176,16 +180,21 @@ int my_rw_unlock(my_rw_lock_t *rwp)
     rwp->write_thread= 0;
 #endif
 
-    if ( rwp->waiters )		/* writers queued */
+    if ( rwp->write_waiters  &&	/* writers queued */
+        (!rwp->read_waiters || !rwp->prefer_readers))
       pthread_cond_signal( &rwp->writers );
-    else
+    else if (rwp->read_waiters)
       pthread_cond_broadcast( &rwp->readers );
   }
   else
   {
     if ( --rwp->state == 0 &&   /* no more readers */
-        rwp->waiters)
+        rwp->write_waiters)
       pthread_cond_signal( &rwp->writers );
+    /*
+      If there are waiting readers they should have
+      been already waken up.
+    */
   }
 
   pthread_mutex_unlock( &rwp->lock );


Attachment: [text/bzr-bundle] bzr/dlenev@mysql.com-20100903110539-dgal46rlk7nsy3u5.bundle
Thread
bzr commit into mysql-5.5-runtime branch (dlenev:3132) Bug#56405Dmitry Lenev3 Sep