diff options
author | unknown <knielsen@knielsen-hq.org> | 2009-11-13 22:26:08 +0100 |
---|---|---|
committer | unknown <knielsen@knielsen-hq.org> | 2009-11-13 22:26:08 +0100 |
commit | 898f6f48b79d1f2c334fb559225b2b0fade5ea93 (patch) | |
tree | 84df8eecd942b650f172cbd67050ee8984c0d52b /storage/xtradb/include/sync0rw.ic | |
parent | 275c0a7f96502b33f763fb9388dcc1c289e4792b (diff) | |
parent | 2bde0c5e6d31583e5197e3b513f572a693161f62 (diff) | |
download | mariadb-git-898f6f48b79d1f2c334fb559225b2b0fade5ea93.tar.gz |
Merge XtraDB 8 into MariaDB.
Diffstat (limited to 'storage/xtradb/include/sync0rw.ic')
-rw-r--r-- | storage/xtradb/include/sync0rw.ic | 209 |
1 files changed, 99 insertions, 110 deletions
diff --git a/storage/xtradb/include/sync0rw.ic b/storage/xtradb/include/sync0rw.ic index 9e7e4dc9bd8..7116f1b7c9b 100644 --- a/storage/xtradb/include/sync0rw.ic +++ b/storage/xtradb/include/sync0rw.ic @@ -23,13 +23,14 @@ Place, Suite 330, Boston, MA 02111-1307 USA *****************************************************************************/ -/****************************************************** +/**************************************************//** +@file include/sync0rw.ic The read-write lock (for threads) Created 9/11/1995 Heikki Tuuri *******************************************************/ -/********************************************************************** +/******************************************************************//** Lock an rw-lock in shared mode for the current thread. If the rw-lock is locked in exclusive mode, or there is an exclusive lock request waiting, the function spins a preset time (controlled by SYNC_SPIN_ROUNDS), @@ -38,47 +39,47 @@ UNIV_INTERN void rw_lock_s_lock_spin( /*================*/ - rw_lock_t* lock, /* in: pointer to rw-lock */ - ulint pass, /* in: pass value; != 0, if the lock will + rw_lock_t* lock, /*!< in: pointer to rw-lock */ + ulint pass, /*!< in: pass value; != 0, if the lock will be passed to another thread to unlock */ - const char* file_name,/* in: file name where lock requested */ - ulint line); /* in: line where requested */ + const char* file_name,/*!< in: file name where lock requested */ + ulint line); /*!< in: line where requested */ #ifdef UNIV_SYNC_DEBUG -/********************************************************************** +/******************************************************************//** Inserts the debug information for an rw-lock. */ UNIV_INTERN void rw_lock_add_debug_info( /*===================*/ - rw_lock_t* lock, /* in: rw-lock */ - ulint pass, /* in: pass value */ - ulint lock_type, /* in: lock type */ - const char* file_name, /* in: file where requested */ - ulint line); /* in: line where requested */ -/********************************************************************** + rw_lock_t* lock, /*!< in: rw-lock */ + ulint pass, /*!< in: pass value */ + ulint lock_type, /*!< in: lock type */ + const char* file_name, /*!< in: file where requested */ + ulint line); /*!< in: line where requested */ +/******************************************************************//** Removes a debug information struct for an rw-lock. */ UNIV_INTERN void rw_lock_remove_debug_info( /*======================*/ - rw_lock_t* lock, /* in: rw-lock */ - ulint pass, /* in: pass value */ - ulint lock_type); /* in: lock type */ + rw_lock_t* lock, /*!< in: rw-lock */ + ulint pass, /*!< in: pass value */ + ulint lock_type); /*!< in: lock type */ #endif /* UNIV_SYNC_DEBUG */ -/************************************************************************ -Accessor functions for rw lock. */ +/********************************************************************//** +Check if there are threads waiting for the rw-lock. +@return 1 if waiters, 0 otherwise */ UNIV_INLINE ulint rw_lock_get_waiters( /*================*/ - /* out: 1 if waiters, 0 otherwise */ - rw_lock_t* lock) /* in: rw-lock */ + const rw_lock_t* lock) /*!< in: rw-lock */ { return(lock->waiters); } -/************************************************************************ +/********************************************************************//** Sets lock->waiters to 1. It is not an error if lock->waiters is already 1. On platforms where ATOMIC builtins are used this function enforces a memory barrier. */ @@ -86,16 +87,16 @@ UNIV_INLINE void rw_lock_set_waiter_flag( /*====================*/ - rw_lock_t* lock) /* in: rw-lock */ + rw_lock_t* lock) /*!< in/out: rw-lock */ { #ifdef INNODB_RW_LOCKS_USE_ATOMICS - os_compare_and_swap(&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 */ } -/************************************************************************ +/********************************************************************//** Resets lock->waiters to 0. It is not an error if lock->waiters is already 0. On platforms where ATOMIC builtins are used this function enforces a memory barrier. */ @@ -103,26 +104,27 @@ UNIV_INLINE void rw_lock_reset_waiter_flag( /*======================*/ - rw_lock_t* lock) /* in: rw-lock */ + rw_lock_t* lock) /*!< in/out: rw-lock */ { #ifdef INNODB_RW_LOCKS_USE_ATOMICS - os_compare_and_swap(&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 */ } -/********************************************************************** +/******************************************************************//** Returns the write-status of the lock - this function made more sense -with the old rw_lock implementation. */ +with the old rw_lock implementation. +@return RW_LOCK_NOT_LOCKED, RW_LOCK_EX, RW_LOCK_WAIT_EX */ UNIV_INLINE ulint rw_lock_get_writer( /*===============*/ - rw_lock_t* lock) + const rw_lock_t* lock) /*!< in: rw-lock */ { lint lock_word = lock->lock_word; - if(lock_word > 0) { + if (lock_word > 0) { /* return NOT_LOCKED in s-lock state, like the writer member of the old lock implementation. */ return(RW_LOCK_NOT_LOCKED); @@ -134,16 +136,17 @@ rw_lock_get_writer( } } -/********************************************************************** -Returns number of readers. */ +/******************************************************************//** +Returns the number of readers. +@return number of readers */ UNIV_INLINE ulint rw_lock_get_reader_count( /*=====================*/ - rw_lock_t* lock) + const rw_lock_t* lock) /*!< in: rw-lock */ { lint lock_word = lock->lock_word; - if(lock_word > 0) { + if (lock_word > 0) { /* s-locked, no x-waiters */ return(X_LOCK_DECR - lock_word); } else if (lock_word < 0 && lock_word > -X_LOCK_DECR) { @@ -164,85 +167,74 @@ rw_lock_get_mutex( } #endif -/********************************************************************** +/******************************************************************//** Returns the value of writer_count for the lock. Does not reserve the lock -mutex, so the caller must be sure it is not changed during the call. */ +mutex, so the caller must be sure it is not changed during the call. +@return value of writer_count */ UNIV_INLINE ulint rw_lock_get_x_lock_count( /*=====================*/ - /* out: value of writer_count */ - rw_lock_t* lock) /* in: rw-lock */ + const rw_lock_t* lock) /*!< in: rw-lock */ { lint lock_copy = lock->lock_word; /* If there is a reader, lock_word is not divisible by X_LOCK_DECR */ - if(lock_copy > 0 || (-lock_copy) % X_LOCK_DECR != 0) { + if (lock_copy > 0 || (-lock_copy) % X_LOCK_DECR != 0) { return(0); } return(((-lock_copy) / X_LOCK_DECR) + 1); } -/********************************************************************** +/******************************************************************//** Two different implementations for decrementing the lock_word of a rw_lock: one for systems supporting atomic operations, one for others. This does does not support recusive x-locks: they should be handled by the caller and need not be atomic since they are performed by the current lock holder. -Returns true if the decrement was made, false if not. */ +Returns true if the decrement was made, false if not. +@return TRUE if decr occurs */ UNIV_INLINE ibool rw_lock_lock_word_decr( /*===================*/ - /* out: TRUE if decr occurs */ - rw_lock_t* lock, /* in: rw-lock */ - ulint amount) /* in: amount of decrement */ + rw_lock_t* lock, /*!< in/out: rw-lock */ + ulint amount) /*!< in: amount to decrement */ { - #ifdef INNODB_RW_LOCKS_USE_ATOMICS - lint local_lock_word = lock->lock_word; while (local_lock_word > 0) { - if(os_compare_and_swap(&(lock->lock_word), - local_lock_word, - local_lock_word - amount)) { + if (os_compare_and_swap_lint(&lock->lock_word, + local_lock_word, + local_lock_word - amount)) { return(TRUE); } local_lock_word = lock->lock_word; } return(FALSE); - #else /* INNODB_RW_LOCKS_USE_ATOMICS */ - ibool success = FALSE; mutex_enter(&(lock->mutex)); - if(lock->lock_word > 0) { + if (lock->lock_word > 0) { lock->lock_word -= amount; success = TRUE; } mutex_exit(&(lock->mutex)); return(success); - #endif /* INNODB_RW_LOCKS_USE_ATOMICS */ } -/********************************************************************** -Two different implementations for incrementing the lock_word of a rw_lock: -one for systems supporting atomic operations, one for others. -Returns the value of lock_word after increment. */ +/******************************************************************//** +Increments lock_word the specified amount and returns new value. +@return lock->lock_word after increment */ UNIV_INLINE lint rw_lock_lock_word_incr( /*===================*/ - /* out: lock->lock_word after increment */ - rw_lock_t* lock, /* in: rw-lock */ - ulint amount) /* in: amount of increment */ + rw_lock_t* lock, /*!< in/out: rw-lock */ + ulint amount) /*!< in: amount of increment */ { - #ifdef INNODB_RW_LOCKS_USE_ATOMICS - - return(os_atomic_increment(&(lock->lock_word), amount)); - + return(os_atomic_increment_lint(&lock->lock_word, amount)); #else /* INNODB_RW_LOCKS_USE_ATOMICS */ - lint local_lock_word; mutex_enter(&(lock->mutex)); @@ -253,11 +245,10 @@ rw_lock_lock_word_incr( mutex_exit(&(lock->mutex)); return(local_lock_word); - #endif /* INNODB_RW_LOCKS_USE_ATOMICS */ } -/********************************************************************** +/******************************************************************//** This function sets the lock->writer_thread and lock->recursive fields. For platforms where we are using atomic builtins instead of lock->mutex it sets the lock->writer_thread field using atomics to ensure memory @@ -270,8 +261,8 @@ UNIV_INLINE void rw_lock_set_writer_id_and_recursion_flag( /*=====================================*/ - rw_lock_t* lock, /* in/out: lock to work on */ - ibool recursive) /* in: TRUE if recursion + rw_lock_t* lock, /*!< in/out: lock to work on */ + ibool recursive) /*!< in: TRUE if recursion allowed */ { os_thread_id_t curr_thread = os_thread_get_curr_id(); @@ -287,8 +278,8 @@ rw_lock_set_writer_id_and_recursion_flag( UNIV_MEM_VALID(&lock->writer_thread, sizeof lock->writer_thread); local_thread = lock->writer_thread; - success = os_compare_and_swap(&lock->writer_thread, - local_thread, curr_thread); + success = os_compare_and_swap_thread_id( + &lock->writer_thread, local_thread, curr_thread); ut_a(success); lock->recursive = recursive; @@ -302,20 +293,20 @@ rw_lock_set_writer_id_and_recursion_flag( #endif /* INNODB_RW_LOCKS_USE_ATOMICS */ } -/********************************************************************** +/******************************************************************//** Low-level function which tries to lock an rw-lock in s-mode. Performs no -spinning. */ +spinning. +@return TRUE if success */ UNIV_INLINE ibool rw_lock_s_lock_low( /*===============*/ - /* out: TRUE if success */ - rw_lock_t* lock, /* in: pointer to rw-lock */ + rw_lock_t* lock, /*!< in: pointer to rw-lock */ ulint pass __attribute__((unused)), - /* in: pass value; != 0, if the lock will be + /*!< in: pass value; != 0, if the lock will be passed to another thread to unlock */ - const char* file_name, /* in: file name where lock requested */ - ulint line) /* in: line where requested */ + 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)) { @@ -334,7 +325,7 @@ rw_lock_s_lock_low( return(TRUE); /* locking succeeded */ } -/********************************************************************** +/******************************************************************//** Low-level function which locks an rw-lock in s-mode when we know that it is possible and none else is currently accessing the rw-lock structure. Then we can do the locking without reserving the mutex. */ @@ -342,9 +333,9 @@ UNIV_INLINE void rw_lock_s_lock_direct( /*==================*/ - rw_lock_t* lock, /* in: pointer to rw-lock */ - const char* file_name, /* in: file name where requested */ - ulint line) /* in: line where lock requested */ + rw_lock_t* lock, /*!< in/out: rw-lock */ + const char* file_name, /*!< in: file name where requested */ + ulint line) /*!< in: line where lock requested */ { ut_ad(lock->lock_word == X_LOCK_DECR); @@ -359,7 +350,7 @@ rw_lock_s_lock_direct( #endif } -/********************************************************************** +/******************************************************************//** Low-level function which locks an rw-lock in x-mode when we know that it is not locked and none else is currently accessing the rw-lock structure. Then we can do the locking without reserving the mutex. */ @@ -367,9 +358,9 @@ UNIV_INLINE void rw_lock_x_lock_direct( /*==================*/ - rw_lock_t* lock, /* in: pointer to rw-lock */ - const char* file_name, /* in: file name where requested */ - ulint line) /* in: line where lock requested */ + rw_lock_t* lock, /*!< in/out: rw-lock */ + const char* file_name, /*!< in: file name where requested */ + ulint line) /*!< in: line where lock requested */ { ut_ad(rw_lock_validate(lock)); ut_ad(lock->lock_word == X_LOCK_DECR); @@ -386,7 +377,7 @@ rw_lock_x_lock_direct( #endif } -/********************************************************************** +/******************************************************************//** NOTE! Use the corresponding macro, not directly this function! Lock an rw-lock in shared mode for the current thread. If the rw-lock is locked in exclusive mode, or there is an exclusive lock request waiting, the @@ -396,11 +387,11 @@ UNIV_INLINE void rw_lock_s_lock_func( /*================*/ - rw_lock_t* lock, /* in: pointer to rw-lock */ - ulint pass, /* in: pass value; != 0, if the lock will + rw_lock_t* lock, /*!< in: pointer to rw-lock */ + ulint pass, /*!< in: pass value; != 0, if the lock will be passed to another thread to unlock */ - const char* file_name,/* in: file name where lock requested */ - ulint line) /* in: line where requested */ + const char* file_name,/*!< in: file name where lock requested */ + ulint line) /*!< in: line where requested */ { /* NOTE: As we do not know the thread ids for threads which have s-locked a latch, and s-lockers will be served only after waiting @@ -430,25 +421,25 @@ rw_lock_s_lock_func( } } -/********************************************************************** +/******************************************************************//** NOTE! Use the corresponding macro, not directly this function! Lock an rw-lock in exclusive mode for the current thread if the lock can be -obtained immediately. */ +obtained immediately. +@return TRUE if success */ UNIV_INLINE ibool rw_lock_x_lock_func_nowait( /*=======================*/ - /* out: TRUE if success */ - rw_lock_t* lock, /* in: pointer to rw-lock */ - const char* file_name,/* in: file name where lock requested */ - ulint line) /* in: line where requested */ + rw_lock_t* lock, /*!< in: pointer to rw-lock */ + const char* file_name,/*!< in: file name where lock requested */ + ulint line) /*!< in: line where requested */ { os_thread_id_t curr_thread = os_thread_get_curr_id(); ibool success; #ifdef INNODB_RW_LOCKS_USE_ATOMICS - success = os_compare_and_swap(&(lock->lock_word), X_LOCK_DECR, 0); + success = os_compare_and_swap_lint(&lock->lock_word, X_LOCK_DECR, 0); #else success = FALSE; @@ -488,18 +479,17 @@ rw_lock_x_lock_func_nowait( return(TRUE); } -/********************************************************************** +/******************************************************************//** Releases a shared mode lock. */ UNIV_INLINE void rw_lock_s_unlock_func( /*==================*/ - rw_lock_t* lock /* in: rw-lock */ #ifdef UNIV_SYNC_DEBUG - ,ulint pass /* in: pass value; != 0, if the lock may have + ulint pass, /*!< in: pass value; != 0, if the lock may have been passed to another thread to unlock */ #endif - ) + rw_lock_t* lock) /*!< in/out: rw-lock */ { ut_ad((lock->lock_word % X_LOCK_DECR) != 0); @@ -525,14 +515,14 @@ rw_lock_s_unlock_func( #endif } -/********************************************************************** +/******************************************************************//** 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: rw-lock */ + rw_lock_t* lock) /*!< in/out: rw-lock */ { ut_ad(lock->lock_word < X_LOCK_DECR); @@ -550,18 +540,17 @@ rw_lock_s_unlock_direct( #endif } -/********************************************************************** +/******************************************************************//** Releases an exclusive mode lock. */ UNIV_INLINE void rw_lock_x_unlock_func( /*==================*/ - rw_lock_t* lock /* in: rw-lock */ #ifdef UNIV_SYNC_DEBUG - ,ulint pass /* in: pass value; != 0, if the lock may have + ulint pass, /*!< in: pass value; != 0, if the lock may have been passed to another thread to unlock */ #endif - ) + rw_lock_t* lock) /*!< in/out: rw-lock */ { ut_ad((lock->lock_word % X_LOCK_DECR) == 0); @@ -600,14 +589,14 @@ 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: rw-lock */ + rw_lock_t* lock) /*!< in/out: rw-lock */ { /* Reset the exclusive lock if this thread no longer has an x-mode lock */ |