2021-10-12 14:20:30 +02:00
|
|
|
#pragma once
|
|
|
|
|
#include <thread>
|
2021-11-18 12:48:21 +01:00
|
|
|
#include <coroutine>
|
2021-11-05 00:01:12 +01:00
|
|
|
#include "MinimalEngine.h"
|
2021-10-23 00:22:35 +02:00
|
|
|
#include "Containers/List.h"
|
2021-12-09 12:38:02 +01:00
|
|
|
#include "Concepts.h"
|
2022-02-24 22:38:26 +01:00
|
|
|
#include <source_location>
|
2021-10-12 14:20:30 +02:00
|
|
|
|
|
|
|
|
namespace Seele
|
|
|
|
|
{
|
2021-11-01 20:25:16 +01:00
|
|
|
extern class ThreadPool& getGlobalThreadPool();
|
|
|
|
|
template<bool MainJob>
|
2021-12-15 00:05:42 +01:00
|
|
|
struct JobPromiseBase;
|
2021-11-01 20:25:16 +01:00
|
|
|
struct Event
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
Event();
|
2021-12-02 13:00:03 +01:00
|
|
|
Event(nullptr_t);
|
2021-11-01 20:25:16 +01:00
|
|
|
Event(const std::string& name);
|
2022-03-19 22:45:30 +01:00
|
|
|
Event(const std::source_location& location);
|
2022-01-12 14:40:26 +01:00
|
|
|
~Event() = default;
|
2021-11-11 20:12:50 +01:00
|
|
|
auto operator<=>(const Event& other) const
|
|
|
|
|
{
|
2021-11-13 19:28:18 +01:00
|
|
|
return flag <=> other.flag;
|
2021-11-11 20:12:50 +01:00
|
|
|
}
|
2021-12-15 00:05:42 +01:00
|
|
|
bool operator==(const Event& other) const
|
|
|
|
|
{
|
|
|
|
|
return flag == other.flag;
|
|
|
|
|
}
|
2021-11-11 20:12:50 +01:00
|
|
|
Event operator co_await()
|
|
|
|
|
{
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
2021-11-14 20:36:53 +01:00
|
|
|
operator bool()
|
|
|
|
|
{
|
2022-02-14 16:29:26 +01:00
|
|
|
std::scoped_lock lock(flag->lock);
|
|
|
|
|
return flag->data;
|
2021-11-14 20:36:53 +01:00
|
|
|
}
|
2021-11-11 20:12:50 +01:00
|
|
|
|
2022-03-19 22:45:30 +01:00
|
|
|
friend std::ostream& operator<<(std::ostream& stream, const Event& event)
|
|
|
|
|
{
|
|
|
|
|
stream
|
|
|
|
|
<< event.flag->location.file_name()
|
|
|
|
|
<< "("
|
|
|
|
|
<< event.flag->location.line()
|
|
|
|
|
<< ":"
|
|
|
|
|
<< event.flag->location.column()
|
|
|
|
|
<< "): "
|
|
|
|
|
<< event.flag->location.function_name();
|
|
|
|
|
return stream;
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-01 20:25:16 +01:00
|
|
|
void raise();
|
|
|
|
|
void reset();
|
|
|
|
|
bool await_ready();
|
|
|
|
|
template<bool MainJob>
|
|
|
|
|
constexpr void await_suspend(std::coroutine_handle<JobPromiseBase<MainJob>> h);
|
|
|
|
|
constexpr void await_resume() {}
|
|
|
|
|
private:
|
2022-02-14 16:29:26 +01:00
|
|
|
struct StateStore
|
|
|
|
|
{
|
|
|
|
|
std::mutex lock;
|
2022-03-19 22:45:30 +01:00
|
|
|
std::string name;
|
|
|
|
|
std::source_location location;
|
2022-02-14 16:29:26 +01:00
|
|
|
bool data;
|
|
|
|
|
};
|
|
|
|
|
std::shared_ptr<StateStore> flag;
|
2021-11-11 20:12:50 +01:00
|
|
|
friend class ThreadPool;
|
2021-10-12 14:20:30 +02:00
|
|
|
};
|
|
|
|
|
|
2022-02-14 16:29:26 +01:00
|
|
|
template<bool MainJob>
|
2021-12-15 00:05:42 +01:00
|
|
|
struct JobBase;
|
|
|
|
|
template<bool MainJob>
|
|
|
|
|
struct JobPromiseBase
|
2021-11-24 12:10:23 +01:00
|
|
|
{
|
2021-12-27 15:04:53 +01:00
|
|
|
enum class State
|
|
|
|
|
{
|
|
|
|
|
READY,
|
|
|
|
|
WAITING,
|
|
|
|
|
SCHEDULED,
|
|
|
|
|
EXECUTING,
|
|
|
|
|
DONE
|
|
|
|
|
};
|
2022-02-24 22:38:26 +01:00
|
|
|
JobPromiseBase(const std::source_location& location = std::source_location::current())
|
2021-12-09 12:38:02 +01:00
|
|
|
{
|
2021-12-15 00:05:42 +01:00
|
|
|
handle = std::coroutine_handle<JobPromiseBase<MainJob>>::from_promise(*this);
|
2022-03-19 22:45:30 +01:00
|
|
|
finishedEvent = Event(location);
|
2021-12-09 12:38:02 +01:00
|
|
|
}
|
2022-02-14 16:29:26 +01:00
|
|
|
~JobPromiseBase()
|
|
|
|
|
{}
|
2021-12-15 00:05:42 +01:00
|
|
|
JobBase<MainJob> get_return_object() noexcept;
|
|
|
|
|
|
|
|
|
|
inline auto initial_suspend() noexcept;
|
2022-02-14 16:29:26 +01:00
|
|
|
inline auto final_suspend() noexcept;
|
2021-12-15 00:05:42 +01:00
|
|
|
|
|
|
|
|
void return_void() noexcept {}
|
2022-03-19 22:45:30 +01:00
|
|
|
void unhandled_exception() {
|
|
|
|
|
std::exception_ptr exception = std::current_exception();
|
|
|
|
|
std::cerr << "Unhandled exception!" << std::endl;
|
|
|
|
|
throw exception;
|
2021-12-15 00:05:42 +01:00
|
|
|
};
|
|
|
|
|
|
2021-11-24 12:10:23 +01:00
|
|
|
void resume()
|
|
|
|
|
{
|
2022-02-14 16:29:26 +01:00
|
|
|
std::scoped_lock lock(promiseLock);
|
2021-12-27 15:04:53 +01:00
|
|
|
if(!handle || handle.done() || executing())
|
2021-12-15 00:05:42 +01:00
|
|
|
{
|
2021-12-27 15:04:53 +01:00
|
|
|
return;
|
2021-12-15 00:05:42 +01:00
|
|
|
}
|
2021-12-27 15:04:53 +01:00
|
|
|
state = State::EXECUTING;
|
|
|
|
|
handle.resume();
|
2021-11-24 12:10:23 +01:00
|
|
|
}
|
2022-02-14 16:29:26 +01:00
|
|
|
void markDone()
|
|
|
|
|
{
|
|
|
|
|
state = State::DONE;
|
|
|
|
|
finishedEvent.raise();
|
|
|
|
|
if(continuation)
|
|
|
|
|
{
|
2022-02-24 22:38:26 +01:00
|
|
|
std::scoped_lock lock(continuation->promiseLock);
|
2022-02-14 16:29:26 +01:00
|
|
|
getGlobalThreadPool().scheduleJob(continuation);
|
|
|
|
|
continuation->removeRef();
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-12-15 00:05:42 +01:00
|
|
|
void setContinuation(JobPromiseBase* cont)
|
2021-12-09 12:38:02 +01:00
|
|
|
{
|
2022-01-12 14:40:26 +01:00
|
|
|
std::scoped_lock lock(promiseLock, cont->promiseLock);
|
2022-02-24 22:38:26 +01:00
|
|
|
assert(cont->ready());
|
2022-02-14 16:29:26 +01:00
|
|
|
continuation = cont;
|
2022-01-12 14:40:26 +01:00
|
|
|
cont->state = State::SCHEDULED;
|
2022-02-14 16:29:26 +01:00
|
|
|
cont->addRef();
|
2021-12-02 13:00:03 +01:00
|
|
|
}
|
|
|
|
|
bool done()
|
|
|
|
|
{
|
2022-02-14 16:29:26 +01:00
|
|
|
return state == State::DONE;
|
2021-12-02 13:00:03 +01:00
|
|
|
}
|
2021-12-27 15:04:53 +01:00
|
|
|
bool scheduled()
|
|
|
|
|
{
|
|
|
|
|
return state == State::SCHEDULED;
|
|
|
|
|
}
|
|
|
|
|
bool waiting()
|
|
|
|
|
{
|
|
|
|
|
return state == State::WAITING;
|
|
|
|
|
}
|
|
|
|
|
bool executing()
|
|
|
|
|
{
|
|
|
|
|
return state == State::EXECUTING;
|
|
|
|
|
}
|
|
|
|
|
bool ready()
|
|
|
|
|
{
|
|
|
|
|
return state == State::READY;
|
|
|
|
|
}
|
2021-12-02 13:00:03 +01:00
|
|
|
void reset()
|
|
|
|
|
{
|
2022-01-12 14:40:26 +01:00
|
|
|
std::scoped_lock lock(promiseLock);
|
2021-12-15 00:05:42 +01:00
|
|
|
finishedEvent.reset();
|
|
|
|
|
}
|
|
|
|
|
void enqueue(Event& event)
|
|
|
|
|
{
|
2021-12-27 15:04:53 +01:00
|
|
|
if(!handle || handle.done() || waiting() || scheduled())
|
2021-12-22 11:42:07 +01:00
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
2021-12-27 15:04:53 +01:00
|
|
|
state = State::WAITING;
|
2021-12-15 00:05:42 +01:00
|
|
|
getGlobalThreadPool().enqueueWaiting(event, this);
|
|
|
|
|
}
|
|
|
|
|
void schedule()
|
|
|
|
|
{
|
2022-01-12 14:40:26 +01:00
|
|
|
std::scoped_lock lock(promiseLock);
|
2021-12-27 15:04:53 +01:00
|
|
|
if(!handle || done() || !ready())
|
2021-12-15 00:05:42 +01:00
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
2022-02-24 22:38:26 +01:00
|
|
|
state = State::SCHEDULED;
|
2022-01-12 14:40:26 +01:00
|
|
|
getGlobalThreadPool().scheduleJob(this);
|
2021-12-15 00:05:42 +01:00
|
|
|
}
|
2022-02-14 16:29:26 +01:00
|
|
|
void addRef()
|
|
|
|
|
{
|
|
|
|
|
numRefs++;
|
|
|
|
|
}
|
|
|
|
|
void removeRef()
|
|
|
|
|
{
|
2022-03-19 22:45:30 +01:00
|
|
|
if(--numRefs < 1)
|
2022-02-14 16:29:26 +01:00
|
|
|
{
|
2022-03-19 22:45:30 +01:00
|
|
|
if(done())
|
|
|
|
|
{
|
|
|
|
|
handle.destroy();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
schedule();
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-02-14 16:29:26 +01:00
|
|
|
}
|
2021-12-15 00:05:42 +01:00
|
|
|
|
|
|
|
|
std::mutex promiseLock;
|
|
|
|
|
std::coroutine_handle<JobPromiseBase> handle;
|
2022-02-14 16:29:26 +01:00
|
|
|
JobPromiseBase* continuation = nullptr;
|
|
|
|
|
std::atomic_uint64_t numRefs = 0;
|
2021-12-15 00:05:42 +01:00
|
|
|
Event finishedEvent;
|
2021-12-27 15:04:53 +01:00
|
|
|
State state = State::READY;
|
2021-12-15 00:05:42 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template<bool MainJob = false>
|
|
|
|
|
struct JobBase
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
using promise_type = JobPromiseBase<MainJob>;
|
|
|
|
|
|
|
|
|
|
explicit JobBase()
|
|
|
|
|
: promise(nullptr)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
explicit JobBase(JobPromiseBase<MainJob>* promise)
|
|
|
|
|
: promise(promise)
|
|
|
|
|
{
|
|
|
|
|
}
|
2022-02-14 16:29:26 +01:00
|
|
|
JobBase(const JobBase& other)
|
|
|
|
|
{
|
|
|
|
|
std::scoped_lock lock(other.promise->promiseLock);
|
|
|
|
|
promise = other.promise;
|
|
|
|
|
promise->addRef();
|
|
|
|
|
}
|
|
|
|
|
JobBase(JobBase&& other)
|
|
|
|
|
{
|
|
|
|
|
std::scoped_lock lock(other.promise->promiseLock);
|
|
|
|
|
promise = other.promise;
|
|
|
|
|
other.promise = nullptr;
|
|
|
|
|
}
|
2021-12-15 00:05:42 +01:00
|
|
|
~JobBase()
|
|
|
|
|
{
|
|
|
|
|
if(promise)
|
|
|
|
|
{
|
2022-03-19 22:45:30 +01:00
|
|
|
//promise->schedule();
|
2022-02-14 16:29:26 +01:00
|
|
|
promise->removeRef();
|
2021-12-15 00:05:42 +01:00
|
|
|
}
|
|
|
|
|
}
|
2022-02-14 16:29:26 +01:00
|
|
|
JobBase& operator=(const JobBase& other)
|
|
|
|
|
{
|
|
|
|
|
if(this != &other)
|
|
|
|
|
{
|
|
|
|
|
std::scoped_lock lock(other.promise->promiseLock);
|
|
|
|
|
promise = other.promise;
|
|
|
|
|
promise->addRef();
|
|
|
|
|
}
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
JobBase& operator=(JobBase&& other)
|
|
|
|
|
{
|
|
|
|
|
if(this != &other)
|
|
|
|
|
{
|
|
|
|
|
std::scoped_lock lock(other.promise->promiseLock);
|
|
|
|
|
promise = other.promise;
|
|
|
|
|
other.promise = nullptr;
|
|
|
|
|
}
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
2021-12-15 00:05:42 +01:00
|
|
|
void resume()
|
|
|
|
|
{
|
|
|
|
|
promise->resume();
|
|
|
|
|
}
|
|
|
|
|
template<std::invocable Callable>
|
2021-12-22 11:42:07 +01:00
|
|
|
inline JobBase&& then(Callable callable)
|
2021-12-15 00:05:42 +01:00
|
|
|
{
|
|
|
|
|
return then(callable());
|
|
|
|
|
}
|
2021-12-22 11:42:07 +01:00
|
|
|
JobBase&& then(JobBase&& continuation)
|
2021-12-15 00:05:42 +01:00
|
|
|
{
|
|
|
|
|
promise->setContinuation(continuation.promise);
|
2022-02-24 22:38:26 +01:00
|
|
|
promise->schedule();
|
2021-12-22 11:42:07 +01:00
|
|
|
return std::move(continuation);
|
2021-12-15 00:05:42 +01:00
|
|
|
}
|
|
|
|
|
bool done()
|
|
|
|
|
{
|
|
|
|
|
return promise->done();
|
|
|
|
|
}
|
2022-02-24 22:38:26 +01:00
|
|
|
Event operator co_await() const
|
2021-12-02 13:00:03 +01:00
|
|
|
{
|
2022-03-19 22:45:30 +01:00
|
|
|
// the co_await operator keeps a reference to this, it won't
|
2022-02-14 16:29:26 +01:00
|
|
|
// be scheduled from the destructor
|
2021-12-27 15:04:53 +01:00
|
|
|
promise->schedule();
|
2022-02-24 22:38:26 +01:00
|
|
|
return promise->finishedEvent;
|
2021-12-02 13:00:03 +01:00
|
|
|
}
|
2021-12-09 12:38:02 +01:00
|
|
|
static JobBase all() = delete;
|
2022-03-19 22:45:30 +01:00
|
|
|
template<std::ranges::range Iterable>
|
|
|
|
|
requires std::same_as<std::ranges::range_value_t<Iterable>, JobBase>
|
|
|
|
|
static JobBase all(Iterable collection)
|
|
|
|
|
{
|
|
|
|
|
getGlobalThreadPool().scheduleBatch(collection);
|
|
|
|
|
for(auto it : collection)
|
|
|
|
|
{
|
|
|
|
|
co_await it;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
template<std::ranges::range Iterable>
|
2022-02-14 16:29:26 +01:00
|
|
|
static JobBase all(Iterable collection)
|
2021-12-02 13:00:03 +01:00
|
|
|
{
|
2022-02-14 16:29:26 +01:00
|
|
|
for(auto it : collection)
|
2021-12-02 13:00:03 +01:00
|
|
|
{
|
|
|
|
|
co_await it;
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-02-14 16:29:26 +01:00
|
|
|
template<typename... Awaitable>
|
|
|
|
|
static JobBase all(Awaitable&&... jobs)
|
|
|
|
|
{
|
|
|
|
|
return JobBase::all(Array{jobs...});
|
|
|
|
|
}
|
2022-03-19 22:45:30 +01:00
|
|
|
template<typename JobFunc, std::ranges::input_range Iterable>
|
|
|
|
|
requires std::invocable<JobFunc, std::ranges::range_reference_t<Iterable>>
|
|
|
|
|
static JobBase launchJobs(JobFunc&& func, Iterable params)
|
2021-12-02 13:00:03 +01:00
|
|
|
{
|
2022-03-19 22:45:30 +01:00
|
|
|
Array<JobBase> jobs;
|
2021-12-02 13:00:03 +01:00
|
|
|
for(auto&& param : params)
|
|
|
|
|
{
|
2022-03-19 22:45:30 +01:00
|
|
|
JobBase base = func(param);
|
|
|
|
|
jobs.add(base);
|
2021-12-02 13:00:03 +01:00
|
|
|
}
|
2022-03-19 22:45:30 +01:00
|
|
|
getGlobalThreadPool().scheduleBatch(jobs);
|
2021-12-02 13:00:03 +01:00
|
|
|
for(auto job : jobs)
|
|
|
|
|
{
|
|
|
|
|
co_await job;
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-11-24 12:10:23 +01:00
|
|
|
private:
|
2021-12-15 00:05:42 +01:00
|
|
|
JobPromiseBase<MainJob>* promise;
|
2022-03-19 22:45:30 +01:00
|
|
|
friend class ThreadPool;
|
2021-11-24 12:10:23 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
using MainJob = JobBase<true>;
|
|
|
|
|
using Job = JobBase<false>;
|
2021-12-15 00:05:42 +01:00
|
|
|
using MainPromise = JobPromiseBase<true>;
|
|
|
|
|
using Promise = JobPromiseBase<false>;
|
2021-11-24 12:10:23 +01:00
|
|
|
|
2021-10-12 14:20:30 +02:00
|
|
|
class ThreadPool
|
|
|
|
|
{
|
|
|
|
|
public:
|
2022-02-14 16:29:26 +01:00
|
|
|
ThreadPool(uint32 threadCount = std::thread::hardware_concurrency());
|
2021-10-12 14:20:30 +02:00
|
|
|
virtual ~ThreadPool();
|
2022-03-19 22:45:30 +01:00
|
|
|
void waitIdle();
|
2022-01-12 14:40:26 +01:00
|
|
|
// Adds a job to the waiting queue for event
|
2021-12-15 00:05:42 +01:00
|
|
|
void enqueueWaiting(Event& event, Promise* job);
|
2022-01-12 14:40:26 +01:00
|
|
|
// Adds a job to the waiting queue for event
|
2021-12-15 00:05:42 +01:00
|
|
|
void enqueueWaiting(Event& event, MainPromise* job);
|
2022-01-12 14:40:26 +01:00
|
|
|
void scheduleJob(Promise* job);
|
|
|
|
|
void scheduleJob(MainPromise* job);
|
2022-03-19 22:45:30 +01:00
|
|
|
template<std::ranges::range Iterable>
|
|
|
|
|
requires std::same_as<std::ranges::range_value_t<Iterable>, MainJob>
|
|
|
|
|
void scheduleBatch(Iterable jobs)
|
|
|
|
|
{
|
|
|
|
|
std::scoped_lock lock(mainJobLock);
|
|
|
|
|
for(auto job : jobs)
|
|
|
|
|
{
|
|
|
|
|
job.promise->addRef();
|
|
|
|
|
job.promise->state = JobPromiseBase<true>::State::SCHEDULED;
|
|
|
|
|
mainJobs.add(job.promise);
|
|
|
|
|
}
|
|
|
|
|
mainJobCV.notify_one();
|
|
|
|
|
}
|
|
|
|
|
template<std::ranges::range Iterable>
|
|
|
|
|
requires std::same_as<std::ranges::range_value_t<Iterable>, Job>
|
|
|
|
|
void scheduleBatch(Iterable jobs)
|
|
|
|
|
{
|
|
|
|
|
std::scoped_lock lock(jobQueueLock);
|
|
|
|
|
for(auto job : jobs)
|
|
|
|
|
{
|
|
|
|
|
job.promise->addRef();
|
|
|
|
|
job.promise->state = JobPromiseBase<false>::State::SCHEDULED;
|
|
|
|
|
jobQueue.add(job.promise);
|
|
|
|
|
}
|
|
|
|
|
jobQueueCV.notify_all();
|
|
|
|
|
}
|
2021-11-24 12:10:23 +01:00
|
|
|
void notify(Event& event);
|
2022-03-19 22:45:30 +01:00
|
|
|
void mainLoop();
|
|
|
|
|
void threadLoop();
|
2021-10-12 14:20:30 +02:00
|
|
|
private:
|
2021-11-01 20:25:16 +01:00
|
|
|
std::atomic_bool running;
|
2022-03-19 22:45:30 +01:00
|
|
|
std::mutex numIdlingLock;
|
|
|
|
|
std::condition_variable numIdlingIncr;
|
|
|
|
|
uint32 numIdling;
|
|
|
|
|
Array<std::thread> workers;
|
2021-11-01 20:25:16 +01:00
|
|
|
|
2022-03-19 22:45:30 +01:00
|
|
|
List<MainPromise*> mainJobs;
|
2021-11-01 20:25:16 +01:00
|
|
|
std::mutex mainJobLock;
|
2021-11-11 20:12:50 +01:00
|
|
|
std::condition_variable mainJobCV;
|
2021-11-01 20:25:16 +01:00
|
|
|
|
2022-03-19 22:45:30 +01:00
|
|
|
List<Promise*> jobQueue;
|
2021-11-01 20:25:16 +01:00
|
|
|
std::mutex jobQueueLock;
|
2021-11-11 20:12:50 +01:00
|
|
|
std::condition_variable jobQueueCV;
|
2021-11-01 20:25:16 +01:00
|
|
|
|
2022-03-19 22:45:30 +01:00
|
|
|
Map<Event, List<MainPromise*>> waitingMainJobs;
|
2021-11-01 20:25:16 +01:00
|
|
|
std::mutex waitingMainLock;
|
|
|
|
|
|
2022-03-19 22:45:30 +01:00
|
|
|
Map<Event, List<Promise*>> waitingJobs;
|
2021-12-15 00:05:42 +01:00
|
|
|
std::mutex waitingLock;
|
2022-03-19 22:45:30 +01:00
|
|
|
|
|
|
|
|
uint32 maxLocalQueueSize = 50;
|
2021-12-15 00:05:42 +01:00
|
|
|
};
|
2021-11-01 20:25:16 +01:00
|
|
|
|
|
|
|
|
template<bool MainJob>
|
2021-12-09 12:38:02 +01:00
|
|
|
inline JobBase<MainJob> JobPromiseBase<MainJob>::get_return_object() noexcept
|
|
|
|
|
{
|
2022-02-14 16:29:26 +01:00
|
|
|
numRefs++;
|
2021-12-15 00:05:42 +01:00
|
|
|
return JobBase<MainJob>(this);
|
2021-11-01 20:25:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<bool MainJob>
|
2021-12-09 12:38:02 +01:00
|
|
|
inline auto JobPromiseBase<MainJob>::initial_suspend() noexcept
|
2021-11-01 20:25:16 +01:00
|
|
|
{
|
2021-12-15 00:05:42 +01:00
|
|
|
return std::suspend_always{};
|
2021-11-01 20:25:16 +01:00
|
|
|
}
|
2022-01-12 14:40:26 +01:00
|
|
|
|
2021-12-02 13:00:03 +01:00
|
|
|
template<bool MainJob>
|
2022-02-14 16:29:26 +01:00
|
|
|
inline auto JobPromiseBase<MainJob>::final_suspend() noexcept
|
2021-12-02 13:00:03 +01:00
|
|
|
{
|
2022-02-14 16:29:26 +01:00
|
|
|
markDone();
|
|
|
|
|
return std::suspend_always{};
|
2021-12-02 13:00:03 +01:00
|
|
|
}
|
2021-11-01 20:25:16 +01:00
|
|
|
|
|
|
|
|
template<bool MainJob>
|
|
|
|
|
inline constexpr void Event::await_suspend(std::coroutine_handle<JobPromiseBase<MainJob>> h)
|
|
|
|
|
{
|
2021-12-15 00:05:42 +01:00
|
|
|
h.promise().enqueue(*this);
|
2022-02-14 16:29:26 +01:00
|
|
|
flag->lock.unlock();
|
2021-11-01 20:25:16 +01:00
|
|
|
}
|
|
|
|
|
|
2021-10-12 14:20:30 +02:00
|
|
|
} // namespace Seele
|