14#include <DeterministicConcurrency>
17#include <condition_variable>
20namespace DeterministicConcurrency{
33 class DeterministicThread;
67 thread_context() noexcept : control_mutex(), tick_tock(), thread_status_v(thread_status_t::NOT_STARTED) {}
111 template<
typename BasicLockable,
typename... Args>
112 void lock(BasicLockable* lockable, Args&&... args){
115 std::lock_guard<std::mutex>
lock(control_mutex);
116 thread_status_v = DeterministicConcurrency::thread_status_t::WAITING_EXTERNAL;
119 lockable->lock(std::forward<Args>(args)...);
122 std::lock_guard<std::mutex>
lock(control_mutex);
123 thread_status_v = DeterministicConcurrency::thread_status_t::RUNNING;
151 template<
typename BasicLockable,
typename... Args>
155 std::lock_guard<std::mutex>
lock(control_mutex);
156 thread_status_v = DeterministicConcurrency::thread_status_t::WAITING_EXTERNAL;
159 lockable->lock_shared(std::forward<Args>(args)...);
162 std::lock_guard<std::mutex>
lock(control_mutex);
163 thread_status_v = DeterministicConcurrency::thread_status_t::RUNNING;
172 friend class DeterministicThread;
184 std::unique_lock<std::mutex>
lock(control_mutex);
185 while (thread_status_v == thread_status_t::NOT_STARTED)
186 tick_tock.wait(
lock);
194 std::unique_lock<std::mutex>
lock(control_mutex);
195 thread_status_v = thread_status_t::FINISHED;
197 tick_tock.notify_one();
205 std::unique_lock<std::mutex>
lock(control_mutex);
206 thread_status_v = thread_status_t::WAITING;
208 tick_tock.notify_one();
214 void wait_for_tick(){
215 std::unique_lock<std::mutex>
lock(control_mutex);
216 while (thread_status_v == thread_status_t::WAITING)
217 tick_tock.wait(
lock);
220 std::condition_variable tick_tock;
222 std::mutex control_mutex;
229 class DeterministicThread {
232 template <
typename Func,
typename... Args>
233 explicit DeterministicThread(thread_context* t ,Func&& func, Args&&... args)
234 : _thread([function = std::forward<Func>(func), t, tuple = std::make_tuple(std::forward<Args>(args)...)]() mutable {
236 std::apply(function, std::tuple_cat(std::make_tuple(t), tuple));
253 std::unique_lock<std::mutex> lock(_this_thread->control_mutex);
254 if (_this_thread->thread_status_v == thread_status_t::FINISHED)
return;
255 _this_thread->thread_status_v = thread_status_t::RUNNING;
257 _this_thread->tick_tock.notify_one();
263 void wait_for_tock(){
264 std::unique_lock<std::mutex> lock(_this_thread->control_mutex);
265 while (_this_thread->thread_status_v == thread_status_t::RUNNING)
266 _this_thread->tick_tock.wait(lock);
270 thread_context* _this_thread;
thread_status_t
Enum describing the possible states of a thread.
Definition DeterministicThread.h:25
A scheduler which allow to manage the flow of its managed threads.
Definition UserControlledScheduler.h:29
Provide the thread with basic functionalities.
Definition DeterministicThread.h:65
void switchContext()
Notify the scheduler that this thread is ready to give it back the control and wait until the schedul...
Definition DeterministicThread.h:83
void lock_shared(BasicLockable *lockable, Args &&... args)
Lock lockable in shared mode and update the current thread_status_v of the current deterministic thre...
Definition DeterministicThread.h:152
void lock(BasicLockable *lockable, Args &&... args)
Lock lockable and update the current thread_status_v of the current deterministic thread.
Definition DeterministicThread.h:112