mirror of
https://github.com/MariaDB/server.git
synced 2025-01-23 23:34:34 +01:00
fec844aca8
Contains also: MDEV-10549 mysqld: sql/handler.cc:2692: int handler::ha_index_first(uchar*): Assertion `table_share->tmp_table != NO_TMP_TABLE || m_lock_type != 2' failed. (branch bb-10.2-jan) Unlike MySQL, InnoDB still uses THR_LOCK in MariaDB MDEV-10548 Some of the debug sync waits do not work with InnoDB 5.7 (branch bb-10.2-jan) enable tests that were fixed in MDEV-10549 MDEV-10548 Some of the debug sync waits do not work with InnoDB 5.7 (branch bb-10.2-jan) fix main.innodb_mysql_sync - re-enable online alter for partitioned innodb tables
224 lines
6.3 KiB
Text
224 lines
6.3 KiB
Text
/*****************************************************************************
|
|
|
|
Copyright (c) 2013, 2016, Oracle and/or its affiliates. All Rights Reserved.
|
|
|
|
This program is free software; you can redistribute it and/or modify it under
|
|
the terms of the GNU General Public License as published by the Free Software
|
|
Foundation; version 2 of the License.
|
|
|
|
This program is distributed in the hope that it will be useful, but WITHOUT
|
|
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.,
|
|
51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
|
|
|
|
*****************************************************************************/
|
|
|
|
/**************************************************//**
|
|
@file include/os0atomics.ic
|
|
The interface to the operating system synchronization primitives.
|
|
|
|
Created 2012-09-23 Sunny Bains (Split from include/os0sync.ic)
|
|
*******************************************************/
|
|
|
|
#ifdef _WIN32
|
|
#include <winbase.h>
|
|
|
|
/* Use inline functions to make 64 and 32 bit versions of windows atomic
|
|
functions so that typecasts are evaluated at compile time. Take advantage
|
|
that lint is either __int64 or long int and windows atomic functions work
|
|
on __int64 and LONG */
|
|
|
|
/**********************************************************//**
|
|
Atomic compare and exchange of unsigned integers.
|
|
@return value found before the exchange.
|
|
If it is not equal to old_value the exchange did not happen. */
|
|
UNIV_INLINE
|
|
lint
|
|
win_cmp_and_xchg_lint(
|
|
/*==================*/
|
|
volatile lint* ptr, /*!< in/out: source/destination */
|
|
lint new_val, /*!< in: exchange value */
|
|
lint old_val) /*!< in: value to compare to */
|
|
{
|
|
# ifdef _WIN64
|
|
return(InterlockedCompareExchange64(ptr, new_val, old_val));
|
|
# else
|
|
return(InterlockedCompareExchange(ptr, new_val, old_val));
|
|
# endif /* _WIN64 */
|
|
}
|
|
|
|
/**********************************************************//**
|
|
Atomic addition of signed integers.
|
|
@return Initial value of the variable pointed to by ptr */
|
|
UNIV_INLINE
|
|
lint
|
|
win_xchg_and_add(
|
|
/*=============*/
|
|
volatile lint* ptr, /*!< in/out: address of destination */
|
|
lint val) /*!< in: number to be added */
|
|
{
|
|
#ifdef _WIN64
|
|
return(InterlockedExchangeAdd64(ptr, val));
|
|
#else
|
|
return(InterlockedExchangeAdd(ptr, val));
|
|
#endif /* _WIN64 */
|
|
}
|
|
|
|
/**********************************************************//**
|
|
Atomic compare and exchange of unsigned integers.
|
|
@return value found before the exchange.
|
|
If it is not equal to old_value the exchange did not happen. */
|
|
UNIV_INLINE
|
|
ulint
|
|
win_cmp_and_xchg_ulint(
|
|
/*===================*/
|
|
volatile ulint* ptr, /*!< in/out: source/destination */
|
|
ulint new_val, /*!< in: exchange value */
|
|
ulint old_val) /*!< in: value to compare to */
|
|
{
|
|
return((ulint) win_cmp_and_xchg_lint(
|
|
(volatile lint*) ptr,
|
|
(lint) new_val,
|
|
(lint) old_val));
|
|
}
|
|
|
|
/**********************************************************//**
|
|
Atomic compare and exchange of 32-bit unsigned integers.
|
|
@return value found before the exchange.
|
|
If it is not equal to old_value the exchange did not happen. */
|
|
UNIV_INLINE
|
|
DWORD
|
|
win_cmp_and_xchg_dword(
|
|
/*===================*/
|
|
volatile DWORD* ptr, /*!< in/out: source/destination */
|
|
DWORD new_val, /*!< in: exchange value */
|
|
DWORD old_val) /*!< in: value to compare to */
|
|
{
|
|
ut_ad(sizeof(DWORD) == sizeof(LONG)); /* We assume this. */
|
|
return(InterlockedCompareExchange(
|
|
(volatile LONG*) ptr,
|
|
(LONG) new_val,
|
|
(LONG) old_val));
|
|
}
|
|
|
|
/** Do an atomic test and set.
|
|
@param[in,out] ptr Memory location to set
|
|
@param[in] new_val new value
|
|
@return old value of memory location. */
|
|
UNIV_INLINE
|
|
lock_word_t
|
|
os_atomic_test_and_set(
|
|
volatile lock_word_t* ptr,
|
|
lock_word_t new_val)
|
|
{
|
|
return(InterlockedExchange(ptr, new_val));
|
|
}
|
|
|
|
/** Do an atomic compare and set
|
|
@param[in,out] ptr Memory location to set
|
|
@param[in] old_val old value to compare
|
|
@param[in] new_val new value to set
|
|
@return the value of ptr before the operation. */
|
|
UNIV_INLINE
|
|
lock_word_t
|
|
os_atomic_val_compare_and_swap(
|
|
volatile lock_word_t* ptr,
|
|
lock_word_t old_val,
|
|
lock_word_t new_val)
|
|
{
|
|
return(static_cast<lock_word_t>(win_cmp_and_xchg_lint(
|
|
reinterpret_cast<volatile lint*>(ptr),
|
|
static_cast<lint>(new_val),
|
|
static_cast<lint>(old_val))));
|
|
}
|
|
|
|
#elif defined(HAVE_IB_GCC_ATOMIC_COMPARE_EXCHANGE)
|
|
|
|
/** Do an atomic test and set.
|
|
@param[in,out] ptr Memory location to set
|
|
@param[in] new_val new value
|
|
@return old value of memory location. */
|
|
UNIV_INLINE
|
|
lock_word_t
|
|
os_atomic_test_and_set(
|
|
volatile lock_word_t* ptr,
|
|
lock_word_t new_val)
|
|
{
|
|
lock_word_t ret;
|
|
|
|
/* Silence a compiler warning about unused ptr. */
|
|
(void) ptr;
|
|
|
|
#if defined(__powerpc__) || defined(__aarch64__)
|
|
__atomic_exchange(ptr, &new_val, &ret, __ATOMIC_SEQ_CST);
|
|
#else
|
|
__atomic_exchange(ptr, &new_val, &ret, __ATOMIC_RELEASE);
|
|
#endif
|
|
|
|
return(ret);
|
|
}
|
|
|
|
/** Do an atomic compare and set
|
|
@param[in,out] ptr Memory location to set
|
|
@param[in] old_val old value to compare
|
|
@param[in] new_val new value to set
|
|
@return the value of ptr before the operation. */
|
|
UNIV_INLINE
|
|
lock_word_t
|
|
os_atomic_val_compare_and_swap(
|
|
volatile lock_word_t* ptr,
|
|
lock_word_t old_val,
|
|
lock_word_t new_val)
|
|
{
|
|
/* Silence a compiler warning about unused ptr. */
|
|
(void) ptr;
|
|
|
|
#if defined(__powerpc__) || defined(__aarch64__)
|
|
__atomic_compare_exchange(ptr, &old_val, &new_val, false,
|
|
__ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
|
|
#else
|
|
__atomic_compare_exchange(ptr, &old_val, &new_val, false,
|
|
__ATOMIC_RELEASE, __ATOMIC_ACQUIRE);
|
|
#endif
|
|
|
|
return(old_val);
|
|
}
|
|
|
|
#elif defined(IB_STRONG_MEMORY_MODEL)
|
|
|
|
/** Do an atomic test and set.
|
|
@param[in,out] ptr Memory location to set
|
|
@param[in] new_val new value
|
|
@return old value of memory location. */
|
|
UNIV_INLINE
|
|
lock_word_t
|
|
os_atomic_test_and_set(
|
|
volatile lock_word_t* ptr,
|
|
lock_word_t new_val)
|
|
{
|
|
return(__sync_lock_test_and_set(ptr, new_val));
|
|
}
|
|
|
|
/** Do an atomic compare and set
|
|
@param[in,out] ptr Memory location to set
|
|
@param[in] old_val old value to compare
|
|
@param[in] new_val new value to set
|
|
@return the value of ptr before the operation. */
|
|
UNIV_INLINE
|
|
lock_word_t
|
|
os_atomic_val_compare_and_swap(
|
|
volatile lock_word_t* ptr,
|
|
lock_word_t old_val,
|
|
lock_word_t new_val)
|
|
{
|
|
return(__sync_val_compare_and_swap(ptr, old_val, new_val));
|
|
}
|
|
|
|
#else
|
|
|
|
#error "Unsupported platform"
|
|
|
|
#endif /* _WIN32 */
|