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:566
 
int destroy(azio_stream *s)
Definition: azio.cc:372
 
#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:59
 
Provides atomic access in shared-exclusive modes.
Definition: shared_spin_lock.h:79
 
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:62
 
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:29
 
Definition: sync0policy.h:199
 
OS mutex, without any policy.
Definition: sync0types.h:478
 
void exit() 1
Release the mutex.
Definition: sync0types.h:524
 
bool try_lock() 1
Definition: sync0types.h:549
 
void enter() 1
Acquire the mutex.
Definition: sync0types.h:535
 
void init() 1
Create the mutex by calling the system functions.
Definition: sync0types.h:483
 
void destroy() 1
Destroy the mutex.
Definition: sync0types.h:502
 
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:347
 
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:926
 
bool innodb_calling_exit
Set when InnoDB has invoked exit().
Definition: srv0srv.cc:225
 
#define UNIV_NOTHROW
Definition: univ.i:456
 
#define ut_ad(EXPR)
Debug assertion.
Definition: ut0dbg.h:105
 
#define ut_d(EXPR)
Debug statement.
Definition: ut0dbg.h:107
 
#define ut_a(EXPR)
Abort execution if EXPR does not evaluate to nonzero.
Definition: ut0dbg.h:93
 
Random numbers and hashing.
 
ulint ut_delay(ulint delay)
Runs an idle loop on CPU.
Definition: ut0ut.cc:95
 
unsigned long id[MAX_DEAD]
Definition: xcom_base.cc:510