mirror of
https://gitlab.com/niansa/cosched.git
synced 2025-03-06 20:53:26 +01:00
Implemented experimental async mutex
This commit is contained in:
parent
9d1047be54
commit
ecacf7f9f7
2 changed files with 68 additions and 0 deletions
|
@ -8,6 +8,7 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
|||
add_library(cosched SHARED
|
||||
scheduler.cpp include/scheduler.hpp
|
||||
scheduled_thread.cpp include/scheduled_thread.hpp
|
||||
include/scheduler_mutex.hpp
|
||||
basic-coro/SingleEvent.cpp
|
||||
)
|
||||
target_include_directories(cosched PUBLIC include/ basic-coro/include/)
|
||||
|
|
67
include/scheduler_mutex.hpp
Normal file
67
include/scheduler_mutex.hpp
Normal file
|
@ -0,0 +1,67 @@
|
|||
#ifndef SCHEDULER_MUTEX_HPP
|
||||
#define SCHEDULER_MUTEX_HPP
|
||||
#include "scheduler.hpp"
|
||||
|
||||
#include <queue>
|
||||
|
||||
|
||||
namespace CoSched {
|
||||
class Mutex {
|
||||
bool held = false;
|
||||
std::queue<Task*> resume_on_unlock;
|
||||
|
||||
public:
|
||||
Mutex() {}
|
||||
Mutex(const Mutex&) = delete;
|
||||
Mutex(Mutex&&) = delete;
|
||||
~Mutex() {
|
||||
unlock();
|
||||
}
|
||||
|
||||
AwaitableTask<void> lock() {
|
||||
// Just hold lock and return if lock isn't currently being held
|
||||
if (!held) {
|
||||
held = true;
|
||||
co_return;
|
||||
}
|
||||
// Lock is already being held, add task to queue and suspend until lock is passed
|
||||
auto& task = Task::get_current();
|
||||
resume_on_unlock.push(&task);
|
||||
task.set_suspended(true);
|
||||
co_await task.yield();
|
||||
}
|
||||
void unlock() {
|
||||
// If nothing is waiting for the lock to release, just release it and we're done
|
||||
if (!resume_on_unlock.empty()) {
|
||||
held = false;
|
||||
return;
|
||||
}
|
||||
// Something is waiting or the lock to be released, just pass it by.
|
||||
resume_on_unlock.front()->set_suspended(false);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class ScopedLock {
|
||||
Mutex& mutex;
|
||||
bool held_by_us = false;
|
||||
|
||||
public:
|
||||
ScopedLock(Mutex &m) : mutex(m) {}
|
||||
ScopedLock(const ScopedLock&) = delete;
|
||||
ScopedLock(ScopedLock&&) = delete;
|
||||
~ScopedLock() {
|
||||
if (held_by_us) unlock();
|
||||
}
|
||||
|
||||
AwaitableTask<void> lock() {
|
||||
co_await mutex.lock();
|
||||
held_by_us = true;
|
||||
}
|
||||
void unlock() {
|
||||
mutex.unlock();
|
||||
held_by_us = false;
|
||||
}
|
||||
};
|
||||
}
|
||||
#endif // SCHEDULER_MUTEX_HPP
|
Loading…
Add table
Reference in a new issue