1 /* Copyright (c) 2019-2023. The SimGrid Team. All rights reserved. */
3 /* This program is free software; you can redistribute it and/or modify it
4 * under the terms of the license (GNU LGPL) which comes with this package. */
6 #ifndef SIMGRID_MC_MUTEX_OBSERVER_HPP
7 #define SIMGRID_MC_MUTEX_OBSERVER_HPP
9 #include "simgrid/forward.h"
10 #include "src/kernel/activity/ConditionVariableImpl.hpp"
11 #include "src/kernel/activity/MutexImpl.hpp"
12 #include "src/kernel/actor/ActorImpl.hpp"
13 #include "src/kernel/actor/SimcallObserver.hpp"
17 namespace simgrid::kernel::actor {
19 /* All the observers of Mutex transitions are very similar, so implement them all together in this class */
20 class MutexObserver final : public SimcallObserver {
21 mc::Transition::Type type_;
22 activity::MutexImpl* const mutex_;
25 MutexObserver(ActorImpl* actor, mc::Transition::Type type, activity::MutexImpl* mutex);
27 void serialize(std::stringstream& stream) const override;
28 std::string to_string() const override;
29 bool is_enabled() override;
31 activity::MutexImpl* get_mutex() const { return mutex_; }
34 /* This observer is used for SEM_LOCK and SEM_UNLOCK (only) */
35 class SemaphoreObserver final : public SimcallObserver {
36 mc::Transition::Type type_;
37 activity::SemaphoreImpl* const sem_;
40 SemaphoreObserver(ActorImpl* actor, mc::Transition::Type type, activity::SemaphoreImpl* sem);
42 void serialize(std::stringstream& stream) const override;
43 std::string to_string() const override;
45 activity::SemaphoreImpl* get_sem() const { return sem_; }
48 /* This observer is ued for SEM_WAIT, that is returning and needs the acquisition (in MC mode) */
49 class SemaphoreAcquisitionObserver final : public ResultingSimcall<bool> {
50 mc::Transition::Type type_;
51 activity::SemAcquisitionImpl* const acquisition_;
52 const double timeout_;
55 SemaphoreAcquisitionObserver(ActorImpl* actor, mc::Transition::Type type, activity::SemAcquisitionImpl* acqui,
56 double timeout = -1.0);
58 void serialize(std::stringstream& stream) const override;
59 std::string to_string() const override;
60 bool is_enabled() override;
62 double get_timeout() const { return timeout_; }
65 /* This observer is used for BARRIER_LOCK and BARRIER_WAIT. WAIT is returning and needs the acquisition */
66 class BarrierObserver final : public ResultingSimcall<bool> {
67 mc::Transition::Type type_;
68 activity::BarrierImpl* const barrier_ = nullptr;
69 activity::BarrierAcquisitionImpl* const acquisition_ = nullptr;
70 const double timeout_;
73 BarrierObserver(ActorImpl* actor, mc::Transition::Type type, activity::BarrierImpl* bar);
74 BarrierObserver(ActorImpl* actor, mc::Transition::Type type, activity::BarrierAcquisitionImpl* acqui,
75 double timeout = -1.0);
77 void serialize(std::stringstream& stream) const override;
78 std::string to_string() const override;
79 bool is_enabled() override;
81 double get_timeout() const { return timeout_; }
84 class ConditionVariableObserver final : public ResultingSimcall<bool> {
85 mc::Transition::Type type_;
86 activity::ConditionVariableImpl* const cond_;
87 activity::MutexImpl* const mutex_;
88 const double timeout_;
91 ConditionVariableObserver(ActorImpl* actor, activity::ConditionVariableImpl* cond, activity::MutexImpl* mutex,
92 double timeout = -1.0)
93 : ResultingSimcall(actor, false), cond_(cond), mutex_(mutex), timeout_(timeout)
95 xbt_assert(mutex != nullptr, "Cannot wait on a condition variable without a valid mutex");
97 void serialize(std::stringstream& stream) const override;
98 std::string to_string() const override;
99 bool is_enabled() override;
100 activity::ConditionVariableImpl* get_cond() const { return cond_; }
101 activity::MutexImpl* get_mutex() const { return mutex_; }
102 double get_timeout() const { return timeout_; }
105 } // namespace simgrid::kernel::actor