Commit 6a150e26 authored by Sergey Vojtovich's avatar Sergey Vojtovich

MDEV-17441 - InnoDB transition to C++11 atomics

Almost trivial TTASEventMutex::m_lock_word transition. Since C++11 doesn't
seem to allow mixed (atomic and non-atomic) access to atomic variables,
we have to perform all accesses atomically.
parent 601f45fd
...@@ -380,7 +380,7 @@ struct TTASEventMutex { ...@@ -380,7 +380,7 @@ struct TTASEventMutex {
~TTASEventMutex() ~TTASEventMutex()
UNIV_NOTHROW UNIV_NOTHROW
{ {
ut_ad(m_lock_word == MUTEX_STATE_UNLOCKED); ut_ad(state() == MUTEX_STATE_UNLOCKED);
} }
/** Called when the mutex is "created". Note: Not from the constructor /** Called when the mutex is "created". Note: Not from the constructor
...@@ -389,7 +389,7 @@ struct TTASEventMutex { ...@@ -389,7 +389,7 @@ struct TTASEventMutex {
void init(latch_id_t id, const char*, uint32_t) UNIV_NOTHROW void init(latch_id_t id, const char*, uint32_t) UNIV_NOTHROW
{ {
ut_a(m_event == 0); ut_a(m_event == 0);
ut_a(m_lock_word == MUTEX_STATE_UNLOCKED); ut_ad(state() == MUTEX_STATE_UNLOCKED);
m_event = os_event_create(sync_latch_get_name(id)); m_event = os_event_create(sync_latch_get_name(id));
} }
...@@ -400,7 +400,7 @@ struct TTASEventMutex { ...@@ -400,7 +400,7 @@ struct TTASEventMutex {
void destroy() void destroy()
UNIV_NOTHROW UNIV_NOTHROW
{ {
ut_ad(m_lock_word == MUTEX_STATE_UNLOCKED); ut_ad(state() == MUTEX_STATE_UNLOCKED);
/* We have to free the event before InnoDB shuts down. */ /* We have to free the event before InnoDB shuts down. */
os_event_destroy(m_event); os_event_destroy(m_event);
...@@ -412,20 +412,20 @@ struct TTASEventMutex { ...@@ -412,20 +412,20 @@ struct TTASEventMutex {
bool try_lock() bool try_lock()
UNIV_NOTHROW UNIV_NOTHROW
{ {
int32 oldval = MUTEX_STATE_UNLOCKED; uint32_t oldval = MUTEX_STATE_UNLOCKED;
return(my_atomic_cas32_strong_explicit(&m_lock_word, &oldval, return m_lock_word.compare_exchange_strong(
MUTEX_STATE_LOCKED, oldval,
MY_MEMORY_ORDER_ACQUIRE, MUTEX_STATE_LOCKED,
MY_MEMORY_ORDER_RELAXED)); std::memory_order_acquire,
std::memory_order_relaxed);
} }
/** Release the mutex. */ /** Release the mutex. */
void exit() void exit()
UNIV_NOTHROW UNIV_NOTHROW
{ {
if (my_atomic_fas32_explicit(&m_lock_word, if (m_lock_word.exchange(MUTEX_STATE_UNLOCKED,
MUTEX_STATE_UNLOCKED, std::memory_order_release)
MY_MEMORY_ORDER_RELEASE)
== MUTEX_STATE_WAITERS) { == MUTEX_STATE_WAITERS) {
os_event_set(m_event); os_event_set(m_event);
sync_array_object_signalled(); sync_array_object_signalled();
...@@ -463,11 +463,12 @@ struct TTASEventMutex { ...@@ -463,11 +463,12 @@ struct TTASEventMutex {
: SYNC_MUTEX, : SYNC_MUTEX,
filename, line, &cell); filename, line, &cell);
int32 oldval = MUTEX_STATE_LOCKED; uint32_t oldval = MUTEX_STATE_LOCKED;
my_atomic_cas32_strong_explicit(&m_lock_word, &oldval, m_lock_word.compare_exchange_strong(
MUTEX_STATE_WAITERS, oldval,
MY_MEMORY_ORDER_RELAXED, MUTEX_STATE_WAITERS,
MY_MEMORY_ORDER_RELAXED); std::memory_order_relaxed,
std::memory_order_relaxed);
if (oldval == MUTEX_STATE_UNLOCKED) { if (oldval == MUTEX_STATE_UNLOCKED) {
sync_array_free_cell(sync_arr, cell); sync_array_free_cell(sync_arr, cell);
...@@ -486,9 +487,7 @@ struct TTASEventMutex { ...@@ -486,9 +487,7 @@ struct TTASEventMutex {
int32 state() const int32 state() const
UNIV_NOTHROW UNIV_NOTHROW
{ {
return(my_atomic_load32_explicit(const_cast<int32*> return m_lock_word.load(std::memory_order_relaxed);
(&m_lock_word),
MY_MEMORY_ORDER_RELAXED));
} }
/** The event that the mutex will wait in sync0arr.cc /** The event that the mutex will wait in sync0arr.cc
...@@ -518,9 +517,8 @@ struct TTASEventMutex { ...@@ -518,9 +517,8 @@ struct TTASEventMutex {
TTASEventMutex(const TTASEventMutex&); TTASEventMutex(const TTASEventMutex&);
TTASEventMutex& operator=(const TTASEventMutex&); TTASEventMutex& operator=(const TTASEventMutex&);
/** lock_word is the target of the atomic test-and-set instruction /** mutex state */
when atomic operations are enabled. */ std::atomic<uint32_t> m_lock_word;
int32 m_lock_word;
/** Used by sync0arr.cc for the wait queue */ /** Used by sync0arr.cc for the wait queue */
os_event_t m_event; os_event_t m_event;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment