summaryrefslogtreecommitdiff
path: root/storage/xtradb/include/sync0rw.ic
diff options
context:
space:
mode:
authorunknown <knielsen@knielsen-hq.org>2009-11-13 22:26:08 +0100
committerunknown <knielsen@knielsen-hq.org>2009-11-13 22:26:08 +0100
commit898f6f48b79d1f2c334fb559225b2b0fade5ea93 (patch)
tree84df8eecd942b650f172cbd67050ee8984c0d52b /storage/xtradb/include/sync0rw.ic
parent275c0a7f96502b33f763fb9388dcc1c289e4792b (diff)
parent2bde0c5e6d31583e5197e3b513f572a693161f62 (diff)
downloadmariadb-git-898f6f48b79d1f2c334fb559225b2b0fade5ea93.tar.gz
Merge XtraDB 8 into MariaDB.
Diffstat (limited to 'storage/xtradb/include/sync0rw.ic')
-rw-r--r--storage/xtradb/include/sync0rw.ic209
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 */