Files
salmanoff/include/qutex.h
T

108 lines
2.5 KiB
C++
Raw Normal View History

2025-09-19 01:19:09 -04:00
#ifndef QUTEX_H
#define QUTEX_H
#include <config.h>
2025-09-19 01:19:09 -04:00
#include <list>
#include <memory>
#include <string>
2025-09-19 01:19:09 -04:00
#include <spinLock.h>
#include <lockerAndInvokerBase.h>
2025-09-19 01:19:09 -04:00
namespace smo {
/**
* @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
2025-09-29 12:40:43 -04:00
name(_name), currOwner(nullptr),
#endif
isOwned(false)
{}
2025-09-19 01:19:09 -04:00
/**
* @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<LockerAndInvokerBase> &lockvoker
2025-09-19 01:19:09 -04:00
)
{
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)
2025-09-19 01:19:09 -04:00
*/
void unregisterFromQueue(
LockerAndInvokerBase::List::iterator it, bool shouldLock = true
)
2025-09-19 01:19:09 -04:00
{
if (shouldLock)
{
lock.acquire();
queue.erase(it);
lock.release();
}
else {
queue.erase(it);
}
2025-09-19 01:19:09 -04:00
}
/**
* @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);
2025-09-19 01:19:09 -04:00
/**
* @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
2025-09-19 01:19:09 -04:00
*/
void backoff(const LockerAndInvokerBase &failedAcquirer, int nRequiredLocks);
2025-09-19 01:19:09 -04:00
/**
* @brief Release the lock and wake up the next waiting lockvoker
*/
void release();
2025-09-19 01:19:09 -04:00
2025-09-29 12:46:58 -04:00
#ifdef CONFIG_ENABLE_DEBUG_LOCKS
std::shared_ptr<LockerAndInvokerBase> getCurrOwner() const
{ return currOwner; }
2025-09-29 12:46:58 -04:00
#endif
2025-09-19 01:19:09 -04:00
public:
#ifdef CONFIG_ENABLE_DEBUG_LOCKS
std::string name;
std::shared_ptr<LockerAndInvokerBase> currOwner;
#endif
2025-09-19 01:19:09 -04:00
SpinLock lock;
LockerAndInvokerBase::List queue;
bool isOwned;
2025-09-19 01:19:09 -04:00
};
} // namespace smo
#endif // QUTEX_H