45template <
template <
typename>
class Policy =
NoPolicy>
98 void enter(uint32_t max_spins [[maybe_unused]],
99 uint32_t max_delay [[maybe_unused]],
100 const char *
filename [[maybe_unused]],
159#ifdef HAVE_IB_LINUX_FUTEX
161#include <linux/futex.h>
162#include <sys/syscall.h>
165template <
template <
typename>
class Policy =
NoPolicy>
166struct TTASFutexMutex {
167 typedef Policy<TTASFutexMutex> MutexPolicy;
170 using futex_word_t = uint32_t;
172 enum class mutex_state_t : futex_word_t {
180 LOCKED_WITH_WAITERS = 2
182 using lock_word_t = mutex_state_t;
184 TTASFutexMutex()
UNIV_NOTHROW : m_lock_word(mutex_state_t::UNLOCKED) {
189 using m_lock_word_t =
decltype(m_lock_word);
190 static_assert(m_lock_word_t::is_always_lock_free);
191 static_assert(
sizeof(m_lock_word_t) ==
sizeof(futex_word_t));
193 const auto addr =
reinterpret_cast<std::uintptr_t
>(&m_lock_word);
194 ut_a(addr %
alignof(m_lock_word_t) == 0);
199 ~TTASFutexMutex() {
ut_a(m_lock_word == mutex_state_t::UNLOCKED); }
207 ut_a(m_lock_word == mutex_state_t::UNLOCKED);
208 m_policy.init(*
this,
id,
filename, line);
214 ut_a(m_lock_word == mutex_state_t::UNLOCKED);
223 void enter(uint32_t max_spins, uint32_t max_delay,
const char *
filename,
226 lock_word_t
lock = ttas(max_spins, max_delay, n_spins);
235 const uint32_t n_waits = (
lock == mutex_state_t::LOCKED_WITH_WAITERS ||
236 (
lock == mutex_state_t::LOCKED && !set_waiters()))
240 m_policy.add(n_spins, n_waits);
249 std::atomic_thread_fence(std::memory_order_acquire);
251 if (state() == mutex_state_t::LOCKED_WITH_WAITERS) {
252 m_lock_word = mutex_state_t::UNLOCKED;
254 }
else if (unlock() == mutex_state_t::LOCKED) {
265 lock_word_t unlocked = mutex_state_t::UNLOCKED;
266 m_lock_word.compare_exchange_strong(unlocked, mutex_state_t::LOCKED);
273 lock_word_t unlocked = mutex_state_t::UNLOCKED;
274 return m_lock_word.compare_exchange_strong(unlocked, mutex_state_t::LOCKED);
279 return (state() != mutex_state_t::UNLOCKED);
285 return (
is_locked() && m_policy.is_owned());
290 MutexPolicy &policy()
UNIV_NOTHROW {
return (m_policy); }
293 const MutexPolicy &policy() const
UNIV_NOTHROW {
return (m_policy); }
297 lock_word_t state() const
UNIV_NOTHROW {
return (m_lock_word); }
302 return m_lock_word.exchange(mutex_state_t::UNLOCKED);
308 return m_lock_word.exchange(mutex_state_t::LOCKED_WITH_WAITERS) ==
309 mutex_state_t::UNLOCKED;
315 uint32_t n_waits = 0;
323 syscall(SYS_futex, &m_lock_word, FUTEX_WAIT_PRIVATE,
324 mutex_state_t::LOCKED_WITH_WAITERS, 0, 0, 0);
329 }
while (!set_waiters());
336 syscall(SYS_futex, &m_lock_word, FUTEX_WAKE_PRIVATE, 1, 0, 0, 0);
344 lock_word_t ttas(uint32_t max_spins, uint32_t max_delay,
346 std::atomic_thread_fence(std::memory_order_acquire);
348 for (n_spins = 0; n_spins < max_spins; ++n_spins) {
350 lock_word_t
lock = trylock();
352 if (
lock == mutex_state_t::UNLOCKED) {
366 MutexPolicy m_policy;
368 alignas(4) std::atomic<lock_word_t> m_lock_word;
373template <
template <
typename>
class Policy =
NoPolicy>
379 using m_owner_t =
decltype(
m_owner);
380 ut_ad(
reinterpret_cast<std::uintptr_t
>(&
m_owner) %
alignof(m_owner_t) == 0);
381 static_assert(m_owner_t::is_always_lock_free);
421 return m_owner.compare_exchange_strong(expected,
479 bool is_free(uint32_t max_spins, uint32_t max_delay,
481 ut_ad(n_spins <= max_spins);
498 }
while (n_spins < max_spins);
510 uint32_t n_spins = 0;
511 uint32_t n_waits = 0;
512 const uint32_t step = max_spins;
517 if (
is_free(max_spins, max_delay, n_spins)) {
525 max_spins = n_spins + step;
530 std::this_thread::yield();
587template <
typename MutexImpl>
590 typedef typename MutexImpl::MutexPolicy
Policy;
622 void enter(uint32_t n_spins, uint32_t n_delay,
const char *
name,
662 int ret =
m_impl.try_lock() ? 0 : 1;
731 if (
m_ptr !=
nullptr) {
748 if (
m_ptr !=
nullptr) {
762 if (locker !=
nullptr) {
769 if (
m_ptr !=
nullptr) {
778 if (
m_ptr !=
nullptr) {
static mysql_service_status_t init()
Component initialization.
Definition: audit_api_message_emit.cc:570
#define PSI_MUTEX_CALL(M)
Definition: psi_mutex.h:35
struct PSI_mutex_locker PSI_mutex_locker
Definition: psi_mutex_bits.h:104
@ PSI_MUTEX_TRYLOCK
Lock attempt.
Definition: psi_mutex_bits.h:111
@ PSI_MUTEX_LOCK
Lock.
Definition: psi_mutex_bits.h:109
#define exit(A)
Definition: lexyy.cc:917
native_mutex_t init_mutex
Definition: mysqlimport.cc:54
Provides atomic access in shared-exclusive modes.
Definition: shared_spin_lock.h:78
stdx::expected< size_t, std::error_code > wait(int epfd, epoll_event *fd_events, size_t num_fd_events, std::chrono::milliseconds timeout)
Definition: linux_epoll.h:82
static mysql_service_status_t destroy(reference_caching_channel channel) noexcept
Definition: component.cc:49
Definition: varlen_sort.h:183
pid_type get_id()
Definition: process.h:47
static uint64_t random_from_interval(uint64_t low, uint64_t high)
Generates a pseudo-random integer from a given interval.
Definition: ut0rnd.h:179
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:527
void os_event_destroy(os_event_t &event)
Frees an event object.
Definition: os0event.cc:594
const char * filename
Definition: pfs_example_component_population.cc:66
required string key
Definition: replication_asynchronous_connection_failover.proto:59
case opt name
Definition: sslopt-case.h:32
Definition: sync0policy.h:198
OS mutex, without any policy.
Definition: sync0types.h:471
void exit() 1
Release the mutex.
Definition: sync0types.h:517
bool try_lock() 1
Definition: sync0types.h:542
void enter() 1
Acquire the mutex.
Definition: sync0types.h:528
void init() 1
Create the mutex by calling the system functions.
Definition: sync0types.h:476
void destroy() 1
Destroy the mutex.
Definition: sync0types.h:495
OS mutex for tracking lock/unlock for debugging.
Definition: ib0mutex.h:46
bool is_owned() const 1
Definition: ib0mutex.h:129
void exit() 1
Release the mutex.
Definition: ib0mutex.h:85
void init(latch_id_t id, const char *filename, uint32_t line) 1
Initialise the mutex.
Definition: ib0mutex.h:61
bool m_freed
true if the mutex has not be initialized
Definition: ib0mutex.h:143
const MutexPolicy & policy() const 1
Definition: ib0mutex.h:138
void enter(uint32_t max_spins, uint32_t max_delay, const char *filename, uint32_t line) 1
Acquire the mutex.
Definition: ib0mutex.h:98
bool m_locked
true if the mutex has been locked.
Definition: ib0mutex.h:146
MutexPolicy m_policy
Policy data.
Definition: ib0mutex.h:156
void lock()
Definition: ib0mutex.h:110
~OSTrackMutex() 1
Definition: ib0mutex.h:55
MutexPolicy & policy() 1
Definition: ib0mutex.h:135
OSMutex m_mutex
OS Mutex instance.
Definition: ib0mutex.h:153
bool try_lock() 1
Definition: ib0mutex.h:114
Policy< OSTrackMutex > MutexPolicy
Definition: ib0mutex.h:47
void destroy() 1
Destroy the mutex.
Definition: ib0mutex.h:73
bool m_destroy_at_exit
Do/Dont destroy mutex at exit.
Definition: ib0mutex.h:149
OSTrackMutex(bool destroy_mutex_at_exit=true) 1
Definition: ib0mutex.h:49
void unlock()
Definition: ib0mutex.h:111
bool m_enabled
Instrumentation is enabled.
Definition: psi_bits.h:180
State data storage for start_mutex_wait_v1_t.
Definition: psi_mutex_bits.h:124
Interface for an instrumented mutex.
Definition: psi_mutex_bits.h:96
Mutex interface for all policy mutexes.
Definition: ib0mutex.h:588
void destroy() 1
Free resources (if any)
Definition: ib0mutex.h:697
MutexImpl m_impl
The mutex implementation.
Definition: ib0mutex.h:787
PolicyMutex() 1
Definition: ib0mutex.h:592
PSI_mutex * m_ptr
The performance schema instrumentation hook.
Definition: ib0mutex.h:791
MutexImpl::MutexPolicy Policy
Definition: ib0mutex.h:590
const Policy & policy() const 1
Definition: ib0mutex.h:604
void enter(uint32_t n_spins, uint32_t n_delay, const char *name, uint32_t line) 1
Acquire the mutex.
Definition: ib0mutex.h:622
bool is_owned() const 1
Definition: ib0mutex.h:679
PSI_mutex_locker * pfs_begin_trylock(PSI_mutex_locker_state *state, const char *name, uint32_t line) 1
Performance schema monitoring.
Definition: ib0mutex.h:745
PSI_mutex_locker * pfs_begin_lock(PSI_mutex_locker_state *state, const char *name, uint32_t line) 1
Performance schema monitoring.
Definition: ib0mutex.h:728
void pfs_del()
Performance schema monitoring - deregister.
Definition: ib0mutex.h:777
void pfs_exit()
Performance schema monitoring - register mutex release.
Definition: ib0mutex.h:768
Policy & policy() 1
Definition: ib0mutex.h:601
void init(latch_id_t id, const char *filename, uint32_t line) 1
Initialise the mutex.
Definition: ib0mutex.h:688
int trylock(const char *name, uint32_t line) 1
Try and lock the mutex, return 0 on SUCCESS and 1 otherwise.
Definition: ib0mutex.h:647
void pfs_end(PSI_mutex_locker *locker, int ret) 1
Performance schema monitoring.
Definition: ib0mutex.h:761
void pfs_add(mysql_pfs_key_t key) 1
Performance schema monitoring - register mutex with PFS.
Definition: ib0mutex.h:718
void exit() 1
Release the mutex.
Definition: ib0mutex.h:607
MutexImpl MutexType
Definition: ib0mutex.h:589
Definition: ib0mutex.h:374
void set_waiters() 1
Note that there are threads waiting on the mutex.
Definition: ib0mutex.h:555
void signal() 1
Wakeup any waiting thread(s).
Definition: ut0mutex.ic:218
os_event_t event() 1
The event that the mutex will wait in sync0arr.cc.
Definition: ib0mutex.h:448
os_event_t m_event
Used by sync0arr.cc for the wait queue.
Definition: ib0mutex.h:575
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:388
void destroy() 1
This is the real destructor.
Definition: ib0mutex.h:407
void enter(uint32_t max_spins, uint32_t max_delay, const char *filename, uint32_t line) 1
Acquire the mutex.
Definition: ib0mutex.h:439
void init(latch_id_t id, const char *filename, uint32_t line) 1
Called when the mutex is "created".
Definition: ib0mutex.h:395
MutexPolicy & policy() 1
Definition: ib0mutex.h:461
~TTASEventMutex() 1
Definition: ib0mutex.h:384
bool is_locked() const 1
Definition: ib0mutex.h:451
MutexPolicy m_policy
Policy data.
Definition: ib0mutex.h:578
bool try_lock() 1
Try and lock the mutex.
Definition: ib0mutex.h:419
void exit() 1
Release the mutex.
Definition: ib0mutex.h:426
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:582
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:479
const MutexPolicy & policy() const 1
Definition: ib0mutex.h:464
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:508
void clear_waiters() 1
Note that there are no threads waiting on the mutex.
Definition: ib0mutex.h:558
Policy< TTASEventMutex > MutexPolicy
Definition: ib0mutex.h:375
TTASEventMutex() 1
Definition: ib0mutex.h:377
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:572
bool is_owned() const 1
Definition: ib0mutex.h:456
bool wait(const char *filename, uint32_t line, uint32_t spin) 1
Wait in the sync array.
Definition: ut0mutex.ic:47
Define for performance schema registration key.
Definition: sync0sync.h:50
InnoDB condition variable.
Definition: os0event.cc:62
pthread_mutex_t sys_mutex_t
Native mutex.
Definition: sync0types.h:55
latch_id_t
Each latch has an ID.
Definition: sync0types.h:341
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:919
bool innodb_calling_exit
Set when InnoDB has invoked exit().
Definition: srv0srv.cc:224
unsigned int uint
Definition: uca-dump.cc:29
#define UNIV_NOTHROW
Definition: univ.i:457
#define ut_ad(EXPR)
Debug assertion.
Definition: ut0dbg.h:68
#define ut_d(EXPR)
Debug statement.
Definition: ut0dbg.h:70
#define ut_a(EXPR)
Abort execution if EXPR does not evaluate to nonzero.
Definition: ut0dbg.h:56
Random numbers and hashing.
ulint ut_delay(ulint delay)
Runs an idle loop on CPU.
Definition: ut0ut.cc:98
unsigned long id[MAX_DEAD]
Definition: xcom_base.cc:509