#ifdefined __linux__ /* futex(2): FUTEX_WAIT_PRIVATE, FUTEX_WAKE_PRIVATE */ #elifdefined __OpenBSD__ || defined __FreeBSD__ || defined __DragonFly__ /* system calls similar to Linux futex(2) */ #elifdefined _WIN32 /* SRWLOCK as well as WaitOnAddress(), WakeByAddressSingle() */ #else # define SUX_LOCK_GENERIC /* fall back to generic synchronization primitives */ #endif
#if !defined SUX_LOCK_GENERIC && 0/* defined SAFE_MUTEX */ # define SUX_LOCK_GENERIC /* Use dummy implementation for debugging purposes */ #endif
/** Futex-based mutex */ template<bool spinloop> class srw_mutex_impl final
{ friend ssux_lock_impl<spinloop>; /** The lock word, containing HOLDER + WAITER if the lock is being held,
plus WAITER times the number of waiters */
std::atomic<uint32_t> lock; /** Identifies that the lock is being held */ static constexpr uint32_t HOLDER= 1; /** Identifies a lock waiter */ static constexpr uint32_t WAITER= 2;
#ifdef SUX_LOCK_GENERIC public: /** The mutex for the condition variables. */
pthread_mutex_t mutex; private: /** Condition variable for the lock word. Used with mutex. */
pthread_cond_t cond; #endif
/** Wait until the mutex has been acquired */ void wait_and_lock() noexcept; /** Wait for lock!=lk */ inlinevoid wait(uint32_t lk) noexcept; /** Wake up one wait() thread */ void wake() noexcept; /** Wake up all wait() threads */ inlinevoid wake_all() noexcept; public: /** @return whether the mutex is being held or waited for */ bool is_locked_or_waiting() const noexcept
{ return lock.load(std::memory_order_acquire) != 0; } /** @return whether the mutex is being held by any thread */ bool is_locked() const noexcept
{ return (lock.load(std::memory_order_acquire) & HOLDER) != 0; }
/** Slim shared-update-exclusive lock with no recursion */ template<bool spinloop> class ssux_lock_impl
{ #ifdef UNIV_PFS_RWLOCK friendclass ssux_lock; # ifdef SUX_LOCK_GENERIC # elif defined _WIN32 # else friend srw_lock_impl<spinloop>; # endif #endif /** mutex for synchronization; held by U or X lock holders */
srw_mutex_impl<spinloop> writer; #ifdef SUX_LOCK_GENERIC /** Condition variable for "readers"; used with writer.mutex. */
pthread_cond_t readers_cond; #endif /** S or U holders, and WRITER flag for X holder or waiter */
std::atomic<uint32_t> readers; /** indicates an X request; readers=WRITER indicates granted X lock */ static constexpr uint32_t WRITER= 1U << 31;
/** Wait for readers!=lk */ inlinevoid wait(uint32_t lk) noexcept;
/** Wait for readers!=lk|WRITER */ void wr_wait(uint32_t lk) noexcept; /** Wake up wait() on the last rd_unlock() */ void wake() noexcept; public: /** Acquire a read lock, with a spin loop */ void rd_lock_spin() noexcept; /** Acquire a read lock, without a spin loop */ void rd_lock_nospin() noexcept;
void init() noexcept
{
writer.init();
DBUG_ASSERT(is_vacant()); #ifdef SUX_LOCK_GENERIC
pthread_cond_init(&readers_cond, nullptr); #endif
} void destroy() noexcept
{
DBUG_ASSERT(is_vacant());
writer.destroy(); #ifdef SUX_LOCK_GENERIC
pthread_cond_destroy(&readers_cond); #endif
} /** @return whether any writer is waiting */ bool is_waiting() const noexcept
{ return (readers.load(std::memory_order_relaxed) & WRITER) != 0; } #ifndef DBUG_OFF /** @return whether the lock is being held or waited for */ bool is_vacant() const noexcept { return !is_locked_or_waiting(); } #endif/* !DBUG_OFF */ private: /** Try to acquire a shared latch. @returnthelockwordvalueifthelatchwasnotacquired
@retval 0 if the latch was acquired */
uint32_t rd_lock_try_low() noexcept
{
uint32_t lk= 0; while (!readers.compare_exchange_weak(lk, lk + 1,
std::memory_order_acquire,
std::memory_order_relaxed)) if (lk & WRITER) return lk; return0;
} public:
class srw_lock_debug : private srw_lock
{ /** The owner of the exclusive lock (0 if none) */
std::atomic<pthread_t> writer; /** Protects readers */ mutable srw_mutex readers_lock; /** Threads that hold the lock in shared mode */
std::atomic<std::unordered_multiset<pthread_t>*> readers;
/** Register a read lock. */ void readers_register() noexcept;
# ifndef SUX_LOCK_GENERIC /** @return whether any lock may be held by any thread */ bool is_locked_or_waiting() const noexcept
{ return srw_lock::is_locked_or_waiting(); } /** @return whether an exclusive lock may be held by any thread */ bool is_write_locked() const noexcept { return srw_lock::is_write_locked(); } # endif
/** Acquire an exclusive lock */ void wr_lock(SRW_LOCK_ARGS(constchar *file, unsigned line)) noexcept; /** @return whether an exclusive lock was acquired */ bool wr_lock_try() noexcept; /** Release after wr_lock() */ void wr_unlock() noexcept; # ifdefined _WIN32 || defined SUX_LOCK_GENERIC # else /** Downgrade wr_lock() to rd_lock() */ void wr_rd_downgrade(SRW_LOCK_ARGS(constchar*,unsigned)) noexcept; # endif /** Acquire a shared lock */ void rd_lock(SRW_LOCK_ARGS(constchar *file, unsigned line)) noexcept; /** @return whether a shared lock was acquired */ bool rd_lock_try() noexcept; /** Release after rd_lock() */ void rd_unlock() noexcept; /** @return whether this thread is between rd_lock() and rd_unlock() */ bool have_rd() const noexcept; /** @return whether this thread is between wr_lock() and wr_unlock() */ bool have_wr() const noexcept; /** @return whether this thread is holding rd_lock() or wr_lock() */ bool have_any() const noexcept;
};
# ifndef LOG_LATCH_DEBUG # elif !defined UNIV_PFS_RWLOCK typedef srw_lock_debug srw_lock_debug_simple; # else class srw_lock_debug_simple : private ssux_lock_impl<false>
{ /** The owner of the exclusive lock (0 if none) */
std::atomic<pthread_t> writer; /** Protects readers */ mutable srw_mutex readers_lock; /** Threads that hold the lock in shared mode */
std::atomic<std::unordered_multiset<pthread_t>*> readers;
/** Register a read lock. */ void readers_register() noexcept;
#ifndef SUX_LOCK_GENERIC /** @return whether any lock may be held by any thread */ bool is_locked_or_waiting() const noexcept
{ return ssux_lock_impl::is_locked_or_waiting(); } /** @return whether an exclusive lock may be held by any thread */ bool is_write_locked() const noexcept
{ return ssux_lock_impl::is_write_locked(); } #endif
/** Acquire an exclusive lock */ void wr_lock() noexcept; /** @return whether an exclusive lock was acquired */ bool wr_lock_try() noexcept; /** Release after wr_lock() */ void wr_unlock() noexcept; /** Acquire a shared lock */ void rd_lock() noexcept; /** @return whether a shared lock was acquired */ bool rd_lock_try() noexcept; /** Release after rd_lock() */ void rd_unlock() noexcept; /** @return whether this thread is between rd_lock() and rd_unlock() */ bool have_rd() const noexcept; /** @return whether this thread is between wr_lock() and wr_unlock() */ bool have_wr() const noexcept; /** @return whether this thread is holding rd_lock() or wr_lock() */ bool have_any() const noexcept;
}; # endif #endif
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.12 Sekunden
(vorverarbeitet am 2026-10-08)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.