#ifndef QUTEX_H #define QUTEX_H #include #include #include #include #include #include namespace sscl { /** * @brief Qutex - Queue-based mutex for asynchronous lock management * * A Qutex combines a spinlock, an ownership flag, and a queue of waiting * lockvokers to provide efficient asynchronous lock management with * priority-based acquisition for LockSets. */ class Qutex { public: /** * @brief Constructor */ Qutex([[maybe_unused]] const std::string &_name) : #ifdef CONFIG_ENABLE_DEBUG_LOCKS name(_name), currOwner(nullptr), #endif isOwned(false) {} /** * @brief Register a lockvoker in the queue * @param lockvoker The lockvoker to register * @return Iterator pointing to the registered lockvoker in the queue */ LockerAndInvokerBase::List::iterator registerInQueue( const std::shared_ptr &lockvoker ) { lock.acquire(); auto it = queue.insert(queue.end(), lockvoker); lock.release(); return it; } /** * @brief Unregister a lockvoker from the queue * @param it Iterator pointing to the lockvoker to unregister * @param shouldLock Whether to acquire the spinlock before erasing (default: true) */ void unregisterFromQueue( LockerAndInvokerBase::List::iterator it, bool shouldLock = true ) { if (shouldLock) { lock.acquire(); queue.erase(it); lock.release(); } else { queue.erase(it); } } /** * @brief Try to acquire the lock for a lockvoker * @param tryingLockvoker The lockvoker attempting to acquire the lock * @param nRequiredLocks Number of locks required by the lockvoker's LockSet * @return true if the lock was successfully acquired, false otherwise */ bool tryAcquire( const LockerAndInvokerBase &tryingLockvoker, int nRequiredLocks); /** * @brief Handle backoff when a lockvoker fails to acquire all required locks * @param failedAcquirer The lockvoker that failed to acquire all locks * @param nRequiredLocks Number of locks required by the lockvoker's LockSet */ void backoff(const LockerAndInvokerBase &failedAcquirer, int nRequiredLocks); /** * @brief Release the lock and wake up the next waiting lockvoker */ void release(); #ifdef CONFIG_ENABLE_DEBUG_LOCKS std::shared_ptr getCurrOwner() const { return currOwner; } #endif public: #ifdef CONFIG_ENABLE_DEBUG_LOCKS std::string name; std::shared_ptr currOwner; #endif SpinLock lock; LockerAndInvokerBase::List queue; bool isOwned; }; } // namespace sscl #endif // QUTEX_H