33 using Ptr = std::shared_ptr<AsyncJob>;
35 std::function<
void()> job;
37 std::promise<void> done_promise;
38 std::shared_future<void> done_future;
40 std::atomic<bool> cancelled{
false };
42 explicit AsyncJob(std::function<
void()>
j)
43 : job(std::move(
j)), done_future(done_promise.get_future().share())
50 if (!cancelled.load(std::memory_order_relaxed)) {
53 done_promise.set_value();
56 done_promise.set_exception(std::current_exception());
65 cancelled.store(
true, std::memory_order_relaxed);
67 done_promise.set_value();
79 bool is_cancelled()
const {
return cancelled.load(std::memory_order_relaxed); }
85 std::thread::id thread_id;
87 std::queue<typename AsyncJob::Ptr> async_jobs;
88 typename AsyncJob::Ptr running_job;
89 std::mutex async_jobs_mutex;
92 std::atomic<bool> running{
true };
94 explicit Core(std::thread::id
id): thread_id(id), jobs_handler_event(
false) {}
97 std::shared_ptr<Core> m_core;
107 std::unique_lock<std::mutex>
lock(
core->async_jobs_mutex);
109 while (
core->running.load(std::memory_order_relaxed)) {
110 while (
core->running.load(std::memory_order_relaxed) && !
core->async_jobs.empty()) {
111 core->running_job =
core->async_jobs.front();
112 core->async_jobs.pop();
116 sc_core::sc_unsuspendable();
117 (*
core->running_job)();
118 sc_core::sc_suspendable();
121 core->running_job.reset();
125 wait(
core->jobs_handler_event);
137 core->running.store(
false, std::memory_order_relaxed);
145 std::lock_guard<std::mutex>
lock(
core->async_jobs_mutex);
147 while (!
core->async_jobs.empty()) {
148 core->async_jobs.front()->cancel();
149 core->async_jobs.pop();
152 if (
core->running_job) {
153 core->running_job->cancel();
154 core->running_job.reset();
162 explicit runonsysc(
const sc_core::sc_module_name&
n =
"run-on-sysc"): sc_module(
n)
164 m_core = std::make_shared<Core>(std::this_thread::get_id());
171 ~runonsysc()
override
185 bool is_on_sysc()
const
188 return core && (std::this_thread::get_id() ==
core->thread_id);
191 void end_of_simulation()
214 if (!
core)
return false;
216 if (!
core->running.load(std::memory_order_relaxed))
return false;
223 auto job = std::make_shared<typename Core::AsyncJob>(std::move(
job_entry));
226 std::lock_guard<std::mutex>
lock(
core->async_jobs_mutex);
228 if (!
core->running.load(std::memory_order_relaxed))
return false;
230 core->async_jobs.push(job);
233 core->jobs_handler_event.async_notify();
239 auto old = sc_core::sc_report_handler::set_actions(sc_core::SC_ERROR,
240 sc_core::SC_LOG | sc_core::SC_DISPLAY);
241 SC_REPORT_ERROR(
"RunOnSysc",
"Run on systemc received an unknown exception from job");
242 sc_core::sc_report_handler::set_actions(sc_core::SC_ERROR,
old);
245 core->jobs_handler_event.async_notify();
249 return !job->is_cancelled();
bool run_on_sysc(std::function< void()> job_entry, bool wait=true)
Run a job on the SystemC kernel thread.
Definition runonsysc.h:211