Qutexes: Implement them and supporting classes

Implements: LockSet, SerializedAsynchronousContinuation,
	LockerAndInvoker, LockerAndInvokerBase, Qutex.

Very big leap in functionality here. See qutexes.md for
an explanation of what we've done.
This commit is contained in:
2025-09-20 18:16:46 -04:00
parent f05c465d61
commit 32179eee5e
10 changed files with 825 additions and 211 deletions
+27 -71
View File
@@ -4,13 +4,13 @@
#include <list>
#include <atomic>
#include <memory>
#include <string>
#include <stdexcept>
#include <spinLock.h>
#include <lockerAndInvokerBase.h>
namespace smo {
// Forward declarations
class LockerAndInvoker;
/**
* @brief Qutex - Queue-based mutex for asynchronous lock management
*
@@ -21,30 +21,22 @@ class LockerAndInvoker;
class Qutex
{
public:
typedef std::list<std::shared_ptr<LockerAndInvoker>> LockerAndInvokerList;
/**
* @brief Constructor
*/
Qutex()
{
// TODO: Initialize member variables
}
: 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
*/
LockerAndInvokerList::iterator registerInQueue(
const std::shared_ptr<LockerAndInvoker> &lockvoker
LockerAndInvokerBase::List::iterator registerInQueue(
const std::shared_ptr<LockerAndInvokerBase> &lockvoker
)
{
// TODO: Implement registration logic
// - Acquire the spinlock
// - Insert lockvoker at the rear of the queue
// - Return iterator to the inserted element
// - Release the spinlock
lock.acquire();
auto it = queue.insert(queue.end(), lockvoker);
lock.release();
@@ -54,14 +46,21 @@ public:
/**
* @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(LockerAndInvokerList::iterator it)
void unregisterFromQueue(
LockerAndInvokerBase::List::iterator it, bool shouldLock = true
)
{
// TODO: Implement unregistration logic
// - Acquire the spinlock
// - Erase the element at the given iterator
// - Release the spinlock
(void)it; // Suppress unused parameter warning
if (shouldLock)
{
lock.acquire();
queue.erase(it);
lock.release();
}
else {
queue.erase(it);
}
}
/**
@@ -70,68 +69,25 @@ public:
* @param nRequiredLocks Number of locks required by the lockvoker's LockSet
* @return true if the lock was successfully acquired, false otherwise
*/
bool tryAcquire(LockerAndInvoker &tryingLockvoker, int nRequiredLocks)
{
// TODO: Implement acquisition logic
// - Acquire the spinlock
// - Check if lock is already owned
// - For single-lock requests, grant immediately if available
// - For multi-lock requests, check if in top X% of queue
// - Set isOwned flag if successful
// - Release the spinlock
// - Return success/failure
(void)tryingLockvoker; // Suppress unused parameter warning
(void)nRequiredLocks; // Suppress unused parameter warning
return false; // Placeholder return value
}
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(LockerAndInvoker &failedAcquirer)
{
// TODO: Implement backoff logic
// - Acquire the spinlock
// - If failedAcquirer is at front, rotate queue items
// - Move failedAcquirer to appropriate position in queue
// - Release the spinlock
// - Wake up the new front item
(void)failedAcquirer; // Suppress unused parameter warning
}
void backoff(const LockerAndInvokerBase &failedAcquirer, int nRequiredLocks);
/**
* @brief Release the lock and wake up the next waiting lockvoker
* @param prevOwner The lockvoker that previously owned the lock
*/
void release(LockerAndInvoker &prevOwner)
{
// TODO: Implement release logic
// - Acquire the spinlock
// - Unregister the previous owner from the queue
// - Clear the isOwned flag
// - Get the new front item
// - Release the spinlock
// - Wake up the new front item (conditionally)
(void)prevOwner; // Suppress unused parameter warning
}
/**
* @brief Wake up a specific lockvoker
* @param lockvoker The lockvoker to wake up
*/
void wakeUp(LockerAndInvoker &lockvoker)
{
// TODO: Implement wake-up logic
// - Post the lockvoker's invocation to its io_service
// - This will cause the lockvoker to retry acquisition
(void)lockvoker; // Suppress unused parameter warning
}
void release();
public:
SpinLock lock;
std::atomic<bool> isOwned;
LockerAndInvokerList queue;
LockerAndInvokerBase::List queue;
bool isOwned;
};
} // namespace smo