46template <
template <
typename>
class Policy =
NoPolicy>
99 void enter(uint32_t max_spins [[maybe_unused]],
100 uint32_t max_delay [[maybe_unused]],
101 const char *
filename [[maybe_unused]],
160#ifdef HAVE_IB_LINUX_FUTEX
162#include <linux/futex.h>
163#include <sys/syscall.h>
166template <
template <
typename>
class Policy =
NoPolicy>
167struct TTASFutexMutex {
168 typedef Policy<TTASFutexMutex> MutexPolicy;
171 using futex_word_t = uint32_t;
173 enum class mutex_state_t : futex_word_t {
181 LOCKED_WITH_WAITERS = 2
183 using lock_word_t = mutex_state_t;
185 TTASFutexMutex()
UNIV_NOTHROW : m_lock_word(mutex_state_t::UNLOCKED) {
190 using m_lock_word_t =
decltype(m_lock_word);
191 static_assert(m_lock_word_t::is_always_lock_free);
192 static_assert(
sizeof(m_lock_word_t) ==
sizeof(futex_word_t));
194 const auto addr =
reinterpret_cast<std::uintptr_t
>(&m_lock_word);
195 ut_a(addr %
alignof(m_lock_word_t) == 0);
200 ~TTASFutexMutex() {
ut_a(m_lock_word == mutex_state_t::UNLOCKED); }
208 ut_a(m_lock_word == mutex_state_t::UNLOCKED);
209 m_policy.init(*
this,
id,
filename, line);
215 ut_a(m_lock_word == mutex_state_t::UNLOCKED);
224 void enter(uint32_t max_spins, uint32_t max_delay,
const char *
filename,
227 lock_word_t
lock = ttas(max_spins, max_delay, n_spins);
236 const uint32_t n_waits = (
lock == mutex_state_t::LOCKED_WITH_WAITERS ||
237 (
lock == mutex_state_t::LOCKED && !set_waiters()))
241 m_policy.add(n_spins, n_waits);
250 std::atomic_thread_fence(std::memory_order_acquire);
252 if (state() == mutex_state_t::LOCKED_WITH_WAITERS) {
253 m_lock_word = mutex_state_t::UNLOCKED;
255 }
else if (unlock() == mutex_state_t::LOCKED) {
266 lock_word_t unlocked = mutex_state_t::UNLOCKED;
267 m_lock_word.compare_exchange_strong(unlocked, mutex_state_t::LOCKED);
274 lock_word_t unlocked = mutex_state_t::UNLOCKED;
275 return m_lock_word.compare_exchange_strong(unlocked, mutex_state_t::LOCKED);
280 return (state() != mutex_state_t::UNLOCKED);
286 return (
is_locked() && m_policy.is_owned());
291 MutexPolicy &policy()
UNIV_NOTHROW {
return (m_policy); }
294 const MutexPolicy &policy() const
UNIV_NOTHROW {
return (m_policy); }
298 lock_word_t state() const
UNIV_NOTHROW {
return (m_lock_word); }
303 return m_lock_word.exchange(mutex_state_t::UNLOCKED);
309 return m_lock_word.exchange(mutex_state_t::LOCKED_WITH_WAITERS) ==
310 mutex_state_t::UNLOCKED;
316 uint32_t n_waits = 0;
324 syscall(SYS_futex, &m_lock_word, FUTEX_WAIT_PRIVATE,
325 mutex_state_t::LOCKED_WITH_WAITERS, 0, 0, 0);
330 }
while (!set_waiters());
337 syscall(SYS_futex, &m_lock_word, FUTEX_WAKE_PRIVATE, 1, 0, 0, 0);
345 lock_word_t ttas(uint32_t max_spins, uint32_t max_delay,
347 std::atomic_thread_fence(std::memory_order_acquire);
349 for (n_spins = 0; n_spins < max_spins; ++n_spins) {
351 lock_word_t
lock = trylock();
353 if (
lock == mutex_state_t::UNLOCKED) {
367 MutexPolicy m_policy;
369 alignas(4) std::atomic<lock_word_t> m_lock_word;
374template <
template <
typename>
class Policy =
NoPolicy>
380 using m_owner_t =
decltype(
m_owner);
381 ut_ad(
reinterpret_cast<std::uintptr_t
>(&
m_owner) %
alignof(m_owner_t) == 0);
382 static_assert(m_owner_t::is_always_lock_free);
422 return m_owner.compare_exchange_strong(expected,
480 bool is_free(uint32_t max_spins, uint32_t max_delay,
482 ut_ad(n_spins <= max_spins);
499 }
while (n_spins < max_spins);
511 uint32_t n_spins = 0;
512 uint32_t n_waits = 0;
513 const uint32_t step = max_spins;
518 if (
is_free(max_spins, max_delay, n_spins)) {
526 max_spins = n_spins + step;
531 std::this_thread::yield();
588template <
typename MutexImpl>
591 typedef typename MutexImpl::MutexPolicy
Policy;
623 void enter(uint32_t n_spins, uint32_t n_delay,
const char *
name,
663 int ret =
m_impl.try_lock() ? 0 : 1;
732 if (
m_ptr !=
nullptr) {
749 if (
m_ptr !=
nullptr) {
763 if (locker !=
nullptr) {
770 if (
m_ptr !=
nullptr) {
779 if (
m_ptr !=
nullptr) {
static mysql_service_status_t init()
Component initialization.
Definition: audit_api_message_emit.cc:571
#define PSI_MUTEX_CALL(M)
Definition: psi_mutex.h:36
struct PSI_mutex_locker PSI_mutex_locker
Definition: psi_mutex_bits.h:105
@ PSI_MUTEX_TRYLOCK
Lock attempt.
Definition: psi_mutex_bits.h:112
@ PSI_MUTEX_LOCK
Lock.
Definition: psi_mutex_bits.h:110
#define exit(A)
Definition: lexyy.cc:917
native_mutex_t init_mutex
Definition: mysqlimport.cc:55
Provides atomic access in shared-exclusive modes.
Definition: shared_spin_lock.h:79
static int destroy(mysql_cond_t *that, const char *, unsigned int)
Definition: mysql_cond_v1_native.cc:54
static int signal(mysql_cond_t *that, const char *, unsigned int)
Definition: mysql_cond_v1_native.cc:87
static int wait(mysql_cond_t *that, mysql_mutex_t *mutex_arg, const char *, unsigned int)
Definition: mysql_cond_v1_native.cc:63
Definition: gcs_xcom_synode.h:64
pid_type get_id()
Definition: process.h:48
static uint64_t random_from_interval_fast(uint64_t low, uint64_t high)
Generates a light-weight pseudo-random integer from a given interval.
Definition: ut0rnd.h:185
Macros for using atomics.
The interface to the operating system condition variables.
os_event_t os_event_create()
Creates an event semaphore, i.e., a semaphore which may just have two states: signaled and nonsignale...
Definition: os0event.cc:528
void os_event_destroy(os_event_t &event)
Frees an event object.
Definition: os0event.cc:595
const char * filename
Definition: pfs_example_component_population.cc:67
required string key
Definition: replication_asynchronous_connection_failover.proto:60
case opt name
Definition: sslopt-case.h:33
Definition: sync0policy.h:199
OS mutex, without any policy.
Definition: sync0types.h:474
void exit() 1
Release the mutex.
Definition: sync0types.h:520
bool try_lock() 1
Definition: sync0types.h:545
void enter() 1
Acquire the mutex.
Definition: sync0types.h:531
void init() 1
Create the mutex by calling the system functions.
Definition: sync0types.h:479
void destroy() 1
Destroy the mutex.
Definition: sync0types.h:498
OS mutex for tracking lock/unlock for debugging.
Definition: ib0mutex.h:47
bool is_owned() const 1
Definition: ib0mutex.h:130
void exit() 1
Release the mutex.
Definition: ib0mutex.h:86
void init(latch_id_t id, const char *filename, uint32_t line) 1
Initialise the mutex.
Definition: ib0mutex.h:62
bool m_freed
true if the mutex has not be initialized
Definition: ib0mutex.h:144
const MutexPolicy & policy() const 1
Definition: ib0mutex.h:139
void enter(uint32_t max_spins, uint32_t max_delay, const char *filename, uint32_t line) 1
Acquire the mutex.
Definition: ib0mutex.h:99
bool m_locked
true if the mutex has been locked.
Definition: ib0mutex.h:147
MutexPolicy m_policy
Policy data.
Definition: ib0mutex.h:157
void lock()
Definition: ib0mutex.h:111
~OSTrackMutex() 1
Definition: ib0mutex.h:56
MutexPolicy & policy() 1
Definition: ib0mutex.h:136
OSMutex m_mutex
OS Mutex instance.
Definition: ib0mutex.h:154
bool try_lock() 1
Definition: ib0mutex.h:115
Policy< OSTrackMutex > MutexPolicy
Definition: ib0mutex.h:48
void destroy() 1
Destroy the mutex.
Definition: ib0mutex.h:74
bool m_destroy_at_exit
Do/Dont destroy mutex at exit.
Definition: ib0mutex.h:150
OSTrackMutex(bool destroy_mutex_at_exit=true) 1
Definition: ib0mutex.h:50
void unlock()
Definition: ib0mutex.h:112
bool m_enabled
Instrumentation is enabled.
Definition: psi_bits.h:191
State data storage for start_mutex_wait_v1_t.
Definition: psi_mutex_bits.h:125
Interface for an instrumented mutex.
Definition: psi_mutex_bits.h:97
Mutex interface for all policy mutexes.
Definition: ib0mutex.h:589
void destroy() 1
Free resources (if any)
Definition: ib0mutex.h:698
MutexImpl m_impl
The mutex implementation.
Definition: ib0mutex.h:788
PolicyMutex() 1
Definition: ib0mutex.h:593
PSI_mutex * m_ptr
The performance schema instrumentation hook.
Definition: ib0mutex.h:792
MutexImpl::MutexPolicy Policy
Definition: ib0mutex.h:591
const Policy & policy() const 1
Definition: ib0mutex.h:605
void enter(uint32_t n_spins, uint32_t n_delay, const char *name, uint32_t line) 1
Acquire the mutex.
Definition: ib0mutex.h:623
bool is_owned() const 1
Definition: ib0mutex.h:680
PSI_mutex_locker * pfs_begin_trylock(PSI_mutex_locker_state *state, const char *name, uint32_t line) 1
Performance schema monitoring.
Definition: ib0mutex.h:746
PSI_mutex_locker * pfs_begin_lock(PSI_mutex_locker_state *state, const char *name, uint32_t line) 1
Performance schema monitoring.
Definition: ib0mutex.h:729
void pfs_del()
Performance schema monitoring - deregister.
Definition: ib0mutex.h:778
void pfs_exit()
Performance schema monitoring - register mutex release.
Definition: ib0mutex.h:769
Policy & policy() 1
Definition: ib0mutex.h:602
void init(latch_id_t id, const char *filename, uint32_t line) 1
Initialise the mutex.
Definition: ib0mutex.h:689
int trylock(const char *name, uint32_t line) 1
Try and lock the mutex, return 0 on SUCCESS and 1 otherwise.
Definition: ib0mutex.h:648
void pfs_end(PSI_mutex_locker *locker, int ret) 1
Performance schema monitoring.
Definition: ib0mutex.h:762
void pfs_add(mysql_pfs_key_t key) 1
Performance schema monitoring - register mutex with PFS.
Definition: ib0mutex.h:719
void exit() 1
Release the mutex.
Definition: ib0mutex.h:608
MutexImpl MutexType
Definition: ib0mutex.h:590
Definition: ib0mutex.h:375
void set_waiters() 1
Note that there are threads waiting on the mutex.
Definition: ib0mutex.h:556
void signal() 1
Wakeup any waiting thread(s).
Definition: ut0mutex.ic:219
os_event_t event() 1
The event that the mutex will wait in sync0arr.cc.
Definition: ib0mutex.h:449
os_event_t m_event
Used by sync0arr.cc for the wait queue.
Definition: ib0mutex.h:576
std::thread::id peek_owner() const 1
If the lock is locked, returns the current owner of the lock, otherwise returns the default std::thre...
Definition: ib0mutex.h:389
void destroy() 1
This is the real destructor.
Definition: ib0mutex.h:408
void enter(uint32_t max_spins, uint32_t max_delay, const char *filename, uint32_t line) 1
Acquire the mutex.
Definition: ib0mutex.h:440
void init(latch_id_t id, const char *filename, uint32_t line) 1
Called when the mutex is "created".
Definition: ib0mutex.h:396
MutexPolicy & policy() 1
Definition: ib0mutex.h:462
~TTASEventMutex() 1
Definition: ib0mutex.h:385
bool is_locked() const 1
Definition: ib0mutex.h:452
MutexPolicy m_policy
Policy data.
Definition: ib0mutex.h:579
bool try_lock() 1
Try and lock the mutex.
Definition: ib0mutex.h:420
void exit() 1
Release the mutex.
Definition: ib0mutex.h:427
std::atomic_bool m_waiters
true if there are (or may be) threads waiting in the global wait array for this mutex to be released.
Definition: ib0mutex.h:583
bool is_free(uint32_t max_spins, uint32_t max_delay, uint32_t &n_spins) const 1
Spin and wait for the mutex to become free.
Definition: ib0mutex.h:480
const MutexPolicy & policy() const 1
Definition: ib0mutex.h:465
void spin_and_try_lock(uint32_t max_spins, uint32_t max_delay, const char *filename, uint32_t line) 1
Spin while trying to acquire the mutex.
Definition: ib0mutex.h:509
void clear_waiters() 1
Note that there are no threads waiting on the mutex.
Definition: ib0mutex.h:559
Policy< TTASEventMutex > MutexPolicy
Definition: ib0mutex.h:376
TTASEventMutex() 1
Definition: ib0mutex.h:378
std::atomic< std::thread::id > m_owner
Set to owner's thread's id when locked, and reset to the default std::thread::id{} when unlocked.
Definition: ib0mutex.h:573
bool is_owned() const 1
Definition: ib0mutex.h:457
bool wait(const char *filename, uint32_t line, uint32_t spin) 1
Wait in the sync array.
Definition: ut0mutex.ic:48
Define for performance schema registration key.
Definition: sync0sync.h:51
InnoDB condition variable.
Definition: os0event.cc:63
pthread_mutex_t sys_mutex_t
Native mutex.
Definition: sync0types.h:56
latch_id_t
Each latch has an ID.
Definition: sync0types.h:344
mysql_pfs_key_t sync_latch_get_pfs_key(latch_id_t id)
Get the latch PFS key from the latch ID.
Definition: sync0types.h:922
bool innodb_calling_exit
Set when InnoDB has invoked exit().
Definition: srv0srv.cc:226
unsigned int uint
Definition: uca9-dump.cc:75
#define UNIV_NOTHROW
Definition: univ.i:456
#define ut_ad(EXPR)
Debug assertion.
Definition: ut0dbg.h:69
#define ut_d(EXPR)
Debug statement.
Definition: ut0dbg.h:71
#define ut_a(EXPR)
Abort execution if EXPR does not evaluate to nonzero.
Definition: ut0dbg.h:57
Random numbers and hashing.
ulint ut_delay(ulint delay)
Runs an idle loop on CPU.
Definition: ut0ut.cc:99
unsigned long id[MAX_DEAD]
Definition: xcom_base.cc:510