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
3131 Jon Olav Hauglid 2010-09-01 [merge]
Merge from mysql-5.5-bugfixing to mysql-5.5-runtime.
removed:
include/mysql/plugin.h.pp
added:
include/mysql/plugin_audit.h.pp
include/mysql/plugin_ftparser.h.pp
mysql-test/include/ctype_filesort2.inc
mysql-test/r/handler_read_last.result
mysql-test/suite/perfschema/r/bad_option_3.result
mysql-test/suite/perfschema/r/bad_option_4.result
mysql-test/suite/perfschema/r/bad_option_5.result
mysql-test/suite/perfschema/r/short_option_1.result
mysql-test/suite/perfschema/r/short_option_2.result
mysql-test/suite/perfschema/t/bad_option_3.test
mysql-test/suite/perfschema/t/bad_option_4.test
mysql-test/suite/perfschema/t/bad_option_5.test
mysql-test/suite/perfschema/t/short_option_1-master.opt
mysql-test/suite/perfschema/t/short_option_1.test
mysql-test/suite/perfschema/t/short_option_2-master.opt
mysql-test/suite/perfschema/t/short_option_2.test
mysql-test/t/handler_read_last.test
modified:
Makefile.am
client/mysqldump.c
cmake/abi_check.cmake
cmake/do_abi_check.cmake
include/m_ctype.h
mysql-test/collections/default.experimental
mysql-test/extra/binlog_tests/binlog_insert_delayed.test
mysql-test/extra/rpl_tests/create_recursive_construct.inc
mysql-test/r/create.result
mysql-test/r/ctype_utf16.result
mysql-test/r/ctype_utf32.result
mysql-test/r/ctype_utf8mb4.result
mysql-test/r/insert_select.result
mysql-test/r/join.result
mysql-test/r/join_outer.result
mysql-test/r/mysqld--help-notwin.result
mysql-test/r/mysqld--help-win.result
mysql-test/r/null_key.result
mysql-test/r/partition.result
mysql-test/r/select.result
mysql-test/r/single_delete_update.result
mysql-test/r/subselect3.result
mysql-test/r/update.result
mysql-test/suite/binlog/r/binlog_row_binlog.result
mysql-test/suite/binlog/r/binlog_statement_insert_delayed.result
mysql-test/suite/binlog/r/binlog_stm_binlog.result
mysql-test/suite/binlog/r/binlog_unsafe.result
mysql-test/suite/binlog/t/binlog_unsafe.test
mysql-test/suite/perfschema/r/start_server_no_cond_class.result
mysql-test/suite/perfschema/r/start_server_no_cond_inst.result
mysql-test/suite/perfschema/r/start_server_no_file_class.result
mysql-test/suite/perfschema/r/start_server_no_file_inst.result
mysql-test/suite/perfschema/r/start_server_no_mutex_class.result
mysql-test/suite/perfschema/r/start_server_no_mutex_inst.result
mysql-test/suite/perfschema/r/start_server_no_rwlock_class.result
mysql-test/suite/perfschema/r/start_server_no_rwlock_inst.result
mysql-test/suite/perfschema/r/start_server_no_thread_class.result
mysql-test/suite/perfschema/r/start_server_no_thread_inst.result
mysql-test/suite/perfschema/r/start_server_off.result
mysql-test/suite/perfschema/r/start_server_on.result
mysql-test/t/ctype_utf16.test
mysql-test/t/ctype_utf32.test
mysql-test/t/ctype_utf8mb4.test
mysql-test/t/disabled.def
mysys/my_getopt.c
sql/mysqld.cc
sql/set_var.cc
sql/sql_insert.cc
sql/sql_lex.h
sql/sql_yacc.yy
sql/sys_vars.cc
storage/myisam/mi_key.c
storage/perfschema/pfs.cc
storage/perfschema/pfs_server.h
storage/perfschema/pfs_stat.h
strings/ctype-ucs2.c
strings/ctype-utf8.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 push into mysql-5.5-runtime branch (dlenev:3131 to 3132) Bug#56405 | Dmitry Lenev | 3 Sep |