summaryrefslogtreecommitdiff
path: root/storage/innobase/include/sync0rw.ic
diff options
context:
space:
mode:
Diffstat (limited to 'storage/innobase/include/sync0rw.ic')
-rw-r--r--storage/innobase/include/sync0rw.ic234
1 files changed, 90 insertions, 144 deletions
diff --git a/storage/innobase/include/sync0rw.ic b/storage/innobase/include/sync0rw.ic
index a5a7cda14f9..eab89e2619e 100644
--- a/storage/innobase/include/sync0rw.ic
+++ b/storage/innobase/include/sync0rw.ic
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
+Copyright (c) 1995, 2011, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
Portions of this file contain modifications contributed and copyrighted by
@@ -18,8 +18,8 @@ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
-this program; if not, write to the Free Software Foundation, Inc., 59 Temple
-Place, Suite 330, Boston, MA 02111-1307 USA
+this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
*****************************************************************************/
@@ -90,7 +90,7 @@ rw_lock_set_waiter_flag(
rw_lock_t* lock) /*!< in/out: rw-lock */
{
#ifdef INNODB_RW_LOCKS_USE_ATOMICS
- (void) os_compare_and_swap_ulint(&lock->waiters, 0, 1);
+ os_compare_and_swap_ulint(&lock->waiters, 0, 1);
#else /* INNODB_RW_LOCKS_USE_ATOMICS */
lock->waiters = 1;
#endif /* INNODB_RW_LOCKS_USE_ATOMICS */
@@ -107,7 +107,7 @@ rw_lock_reset_waiter_flag(
rw_lock_t* lock) /*!< in/out: rw-lock */
{
#ifdef INNODB_RW_LOCKS_USE_ATOMICS
- (void) os_compare_and_swap_ulint(&lock->waiters, 1, 0);
+ os_compare_and_swap_ulint(&lock->waiters, 1, 0);
#else /* INNODB_RW_LOCKS_USE_ATOMICS */
lock->waiters = 0;
#endif /* INNODB_RW_LOCKS_USE_ATOMICS */
@@ -131,7 +131,7 @@ rw_lock_get_writer(
} else if (((-lock_word) % X_LOCK_DECR) == 0) {
return(RW_LOCK_EX);
} else {
- ut_ad(lock_word > -X_LOCK_DECR);
+ ut_ad(lock_word > -X_LOCK_DECR);
return(RW_LOCK_WAIT_EX);
}
}
@@ -200,7 +200,7 @@ rw_lock_lock_word_decr(
ulint amount) /*!< in: amount to decrement */
{
#ifdef INNODB_RW_LOCKS_USE_ATOMICS
- lint local_lock_word = lock->lock_word;
+ lint local_lock_word = lock->lock_word;
while (local_lock_word > 0) {
if (os_compare_and_swap_lint(&lock->lock_word,
local_lock_word,
@@ -244,7 +244,7 @@ rw_lock_lock_word_incr(
mutex_exit(&(lock->mutex));
- return(local_lock_word);
+ return(local_lock_word);
#endif /* INNODB_RW_LOCKS_USE_ATOMICS */
}
@@ -308,7 +308,6 @@ rw_lock_s_lock_low(
const char* file_name, /*!< in: file name where lock requested */
ulint line) /*!< in: line where requested */
{
- /* TODO: study performance of UNIV_LIKELY branch prediction hints. */
if (!rw_lock_lock_word_decr(lock, 1)) {
/* Locking did not succeed */
return(FALSE);
@@ -318,7 +317,7 @@ rw_lock_s_lock_low(
rw_lock_add_debug_info(lock, pass, RW_LOCK_SHARED, file_name, line);
#endif
/* These debugging values are not set safely: they may be incorrect
- or even refer to a line that is invalid for the file name. */
+ or even refer to a line that is invalid for the file name. */
lock->last_s_file_name = file_name;
lock->last_s_line = line;
@@ -409,7 +408,6 @@ rw_lock_s_lock_func(
ut_ad(!rw_lock_own(lock, RW_LOCK_EX));
#endif /* UNIV_SYNC_DEBUG */
- /* TODO: study performance of UNIV_LIKELY branch prediction hints. */
if (rw_lock_s_lock_low(lock, pass, file_name, line)) {
return; /* Success */
@@ -462,8 +460,12 @@ rw_lock_x_lock_func_nowait(
there is an exclusive writer and this is the writer thread. */
lock->lock_word -= X_LOCK_DECR;
+ /* Recursive x-locks must be multiples of X_LOCK_DECR. */
ut_ad(((-lock->lock_word) % X_LOCK_DECR) == 0);
+ /* Watch for too many recursive locks */
+ ut_ad(lock->lock_word < 0);
+
} else {
/* Failure */
return(FALSE);
@@ -502,10 +504,10 @@ rw_lock_s_unlock_func(
if (rw_lock_lock_word_incr(lock, 1) == 0) {
/* wait_ex waiter exists. It may not be asleep, but we signal
- anyway. We do not wake other waiters, because they can't
- exist without wait_ex waiter and wait_ex waiter goes first.*/
+ anyway. We do not wake other waiters, because they can't
+ exist without wait_ex waiter and wait_ex waiter goes first.*/
os_event_set(lock->wait_ex_event);
- sync_array_object_signalled(sync_primary_wait_array);
+ sync_array_object_signalled();
}
@@ -517,31 +519,6 @@ rw_lock_s_unlock_func(
}
/******************************************************************//**
-Releases a shared mode lock when we know there are no waiters and none
-else will access the lock during the time this function is executed. */
-UNIV_INLINE
-void
-rw_lock_s_unlock_direct(
-/*====================*/
- rw_lock_t* lock) /*!< in/out: rw-lock */
-{
- ut_ad(lock->lock_word < X_LOCK_DECR);
-
-#ifdef UNIV_SYNC_DEBUG
- rw_lock_remove_debug_info(lock, 0, RW_LOCK_SHARED);
-#endif
-
- /* Decrease reader count by incrementing lock_word */
- lock->lock_word++;
-
- ut_ad(!lock->waiters);
- ut_ad(rw_lock_validate(lock));
-#ifdef UNIV_SYNC_PERF_STAT
- rw_s_exit_count++;
-#endif
-}
-
-/******************************************************************//**
Releases an exclusive mode lock. */
UNIV_INLINE
void
@@ -564,6 +541,8 @@ rw_lock_x_unlock_func(
if (lock->lock_word == 0) {
/* Last caller in a possible recursive chain. */
lock->recursive = FALSE;
+ UNIV_MEM_INVALID(&lock->writer_thread,
+ sizeof lock->writer_thread);
}
#ifdef UNIV_SYNC_DEBUG
@@ -572,12 +551,12 @@ rw_lock_x_unlock_func(
if (rw_lock_lock_word_incr(lock, X_LOCK_DECR) == X_LOCK_DECR) {
/* Lock is now free. May have to signal read/write waiters.
- We do not need to signal wait_ex waiters, since they cannot
- exist when there is a writer. */
+ We do not need to signal wait_ex waiters, since they cannot
+ exist when there is a writer. */
if (lock->waiters) {
rw_lock_reset_waiter_flag(lock);
os_event_set(lock->event);
- sync_array_object_signalled(sync_primary_wait_array);
+ sync_array_object_signalled();
}
}
@@ -588,38 +567,6 @@ rw_lock_x_unlock_func(
#endif
}
-/******************************************************************//**
-Releases an exclusive mode lock when we know there are no waiters, and
-none else will access the lock during the time this function is executed. */
-UNIV_INLINE
-void
-rw_lock_x_unlock_direct(
-/*====================*/
- rw_lock_t* lock) /*!< in/out: rw-lock */
-{
- /* Reset the exclusive lock if this thread no longer has an x-mode
- lock */
-
- ut_ad((lock->lock_word % X_LOCK_DECR) == 0);
-
-#ifdef UNIV_SYNC_DEBUG
- rw_lock_remove_debug_info(lock, 0, RW_LOCK_EX);
-#endif
-
- if (lock->lock_word == 0) {
- lock->recursive = FALSE;
- }
-
- lock->lock_word += X_LOCK_DECR;
-
- ut_ad(!lock->waiters);
- ut_ad(rw_lock_validate(lock));
-
-#ifdef UNIV_SYNC_PERF_STAT
- rw_x_exit_count++;
-#endif
-}
-
#ifdef UNIV_PFS_RWLOCK
/******************************************************************//**
@@ -643,9 +590,7 @@ pfs_rw_lock_create_func(
ulint cline) /*!< in: file line where created */
{
/* Initialize the rwlock for performance schema */
- lock->pfs_psi = (PSI_server && PFS_IS_INSTRUMENTED(key))
- ? PSI_server->init_rwlock(key, lock)
- : NULL;
+ lock->pfs_psi = PSI_CALL(init_rwlock)(key, lock);
/* The actual function to initialize an rwlock */
rw_lock_create_func(lock,
@@ -656,7 +601,7 @@ pfs_rw_lock_create_func(
cmutex_name,
# endif /* UNIV_DEBUG */
cfile_name,
- cline);
+ cline);
}
/******************************************************************//**
Performance schema instrumented wrap function for rw_lock_x_lock_func()
@@ -672,24 +617,23 @@ pfs_rw_lock_x_lock_func(
const char* file_name,/*!< in: file name where lock requested */
ulint line) /*!< in: line where requested */
{
- struct PSI_rwlock_locker* locker = NULL;
- PSI_rwlock_locker_state state;
+ if (lock->pfs_psi != NULL)
+ {
+ PSI_rwlock_locker* locker;
+ PSI_rwlock_locker_state state;
- /* Record the entry of rw x lock request in performance schema */
- if (UNIV_LIKELY(PSI_server && lock->pfs_psi)) {
- locker = PSI_server->get_thread_rwlock_locker(
- &state, lock->pfs_psi, PSI_RWLOCK_WRITELOCK);
-
- if (locker) {
- PSI_server->start_rwlock_wrwait(locker,
- file_name, line);
- }
- }
+ /* Record the entry of rw x lock request in performance schema */
+ locker = PSI_CALL(start_rwlock_wrwait)(
+ &state, lock->pfs_psi, PSI_RWLOCK_WRITELOCK, file_name, line);
- rw_lock_x_lock_func(lock, pass, file_name, line);
+ rw_lock_x_lock_func(lock, pass, file_name, line);
- if (locker) {
- PSI_server->end_rwlock_wrwait(locker, 0);
+ if (locker != NULL)
+ PSI_CALL(end_rwlock_wrwait)(locker, 0);
+ }
+ else
+ {
+ rw_lock_x_lock_func(lock, pass, file_name, line);
}
}
/******************************************************************//**
@@ -707,25 +651,25 @@ pfs_rw_lock_x_lock_func_nowait(
requested */
ulint line) /*!< in: line where requested */
{
- struct PSI_rwlock_locker* locker = NULL;
- PSI_rwlock_locker_state state;
ibool ret;
- /* Record the entry of rw x lock request in performance schema */
- if (UNIV_LIKELY(PSI_server && lock->pfs_psi)) {
- locker = PSI_server->get_thread_rwlock_locker(
- &state, lock->pfs_psi, PSI_RWLOCK_WRITELOCK);
+ if (lock->pfs_psi != NULL)
+ {
+ PSI_rwlock_locker* locker;
+ PSI_rwlock_locker_state state;
- if (locker) {
- PSI_server->start_rwlock_wrwait(locker,
- file_name, line);
- }
- }
+ /* Record the entry of rw x lock request in performance schema */
+ locker = PSI_CALL(start_rwlock_wrwait)(
+ &state, lock->pfs_psi, PSI_RWLOCK_WRITELOCK, file_name, line);
- ret = rw_lock_x_lock_func_nowait(lock, file_name, line);
+ ret = rw_lock_x_lock_func_nowait(lock, file_name, line);
- if (locker) {
- PSI_server->end_rwlock_wrwait(locker, 0);
+ if (locker != NULL)
+ PSI_CALL(end_rwlock_wrwait)(locker, ret);
+ }
+ else
+ {
+ ret = rw_lock_x_lock_func_nowait(lock, file_name, line);
}
return(ret);
@@ -740,8 +684,9 @@ pfs_rw_lock_free_func(
/*==================*/
rw_lock_t* lock) /*!< in: pointer to rw-lock */
{
- if (UNIV_LIKELY(PSI_server && lock->pfs_psi)) {
- PSI_server->destroy_rwlock(lock->pfs_psi);
+ if (lock->pfs_psi != NULL)
+ {
+ PSI_CALL(destroy_rwlock)(lock->pfs_psi);
lock->pfs_psi = NULL;
}
@@ -763,24 +708,26 @@ pfs_rw_lock_s_lock_func(
requested */
ulint line) /*!< in: line where requested */
{
- struct PSI_rwlock_locker* locker = NULL;
- PSI_rwlock_locker_state state;
-
- /* Instrumented to inform we are aquiring a shared rwlock */
- if (UNIV_LIKELY(PSI_server && lock->pfs_psi)) {
- locker = PSI_server->get_thread_rwlock_locker(
- &state, lock->pfs_psi, PSI_RWLOCK_READLOCK);
- if (locker) {
- PSI_server->start_rwlock_rdwait(locker,
- file_name, line);
- }
- }
+ if (lock->pfs_psi != NULL)
+ {
+ PSI_rwlock_locker* locker;
+ PSI_rwlock_locker_state state;
- rw_lock_s_lock_func(lock, pass, file_name, line);
+ /* Instrumented to inform we are aquiring a shared rwlock */
+ locker = PSI_CALL(start_rwlock_rdwait)(
+ &state, lock->pfs_psi, PSI_RWLOCK_READLOCK, file_name, line);
- if (locker) {
- PSI_server->end_rwlock_rdwait(locker, 0);
+ rw_lock_s_lock_func(lock, pass, file_name, line);
+
+ if (locker != NULL)
+ PSI_CALL(end_rwlock_rdwait)(locker, 0);
+ }
+ else
+ {
+ rw_lock_s_lock_func(lock, pass, file_name, line);
}
+
+ return;
}
/******************************************************************//**
Performance schema instrumented wrap function for rw_lock_s_lock_func()
@@ -798,24 +745,25 @@ pfs_rw_lock_s_lock_low(
const char* file_name, /*!< in: file name where lock requested */
ulint line) /*!< in: line where requested */
{
- struct PSI_rwlock_locker* locker = NULL;
- PSI_rwlock_locker_state state;
ibool ret;
- /* Instrumented to inform we are aquiring a shared rwlock */
- if (UNIV_LIKELY(PSI_server && lock->pfs_psi)) {
- locker = PSI_server->get_thread_rwlock_locker(
- &state, lock->pfs_psi, PSI_RWLOCK_READLOCK);
- if (locker) {
- PSI_server->start_rwlock_rdwait(locker,
- file_name, line);
- }
- }
+ if (lock->pfs_psi != NULL)
+ {
+ PSI_rwlock_locker* locker;
+ PSI_rwlock_locker_state state;
+
+ /* Instrumented to inform we are aquiring a shared rwlock */
+ locker = PSI_CALL(start_rwlock_rdwait)(
+ &state, lock->pfs_psi, PSI_RWLOCK_READLOCK, file_name, line);
- ret = rw_lock_s_lock_low(lock, pass, file_name, line);
+ ret = rw_lock_s_lock_low(lock, pass, file_name, line);
- if (locker) {
- PSI_server->end_rwlock_rdwait(locker, 0);
+ if (locker != NULL)
+ PSI_CALL(end_rwlock_rdwait)(locker, ret);
+ }
+ else
+ {
+ ret = rw_lock_s_lock_low(lock, pass, file_name, line);
}
return(ret);
@@ -837,9 +785,8 @@ pfs_rw_lock_x_unlock_func(
rw_lock_t* lock) /*!< in/out: rw-lock */
{
/* Inform performance schema we are unlocking the lock */
- if (UNIV_LIKELY(PSI_server && lock->pfs_psi)) {
- PSI_server->unlock_rwlock(lock->pfs_psi);
- }
+ if (lock->pfs_psi != NULL)
+ PSI_CALL(unlock_rwlock)(lock->pfs_psi);
rw_lock_x_unlock_func(
#ifdef UNIV_SYNC_DEBUG
@@ -864,9 +811,8 @@ pfs_rw_lock_s_unlock_func(
rw_lock_t* lock) /*!< in/out: rw-lock */
{
/* Inform performance schema we are unlocking the lock */
- if (UNIV_LIKELY(PSI_server && lock->pfs_psi)) {
- PSI_server->unlock_rwlock(lock->pfs_psi);
- }
+ if (lock->pfs_psi != NULL)
+ PSI_CALL(unlock_rwlock)(lock->pfs_psi);
rw_lock_s_unlock_func(
#ifdef UNIV_SYNC_DEBUG