+#include "src/kernel/activity/CommImpl.hpp"
+#include "src/kernel/activity/SynchroRaw.hpp"
+#include "src/kernel/actor/ActorImpl.hpp"
+#include "src/kernel/actor/SimcallObserver.hpp"
+#include "src/kernel/resource/CpuImpl.hpp"
+#include "src/mc/mc_replay.hpp"
+
+#include <boost/range/algorithm.hpp>
+#include <cmath> // isfinite()
+
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(ker_activity, kernel, "Kernel activity-related synchronization");
+
+namespace simgrid {
+namespace kernel {
+namespace activity {
+
+ActivityImpl::~ActivityImpl()
+{
+ clean_action();
+ XBT_DEBUG("Destroy activity %p", this);
+}
+
+void ActivityImpl::register_simcall(smx_simcall_t simcall)
+{
+ simcalls_.push_back(simcall);
+ simcall->issuer_->waiting_synchro_ = this;
+}
+
+void ActivityImpl::unregister_simcall(smx_simcall_t simcall)
+{
+ // Remove the first occurrence of simcall:
+ auto j = boost::range::find(simcalls_, simcall);
+ if (j != simcalls_.end())
+ simcalls_.erase(j);
+}
+
+void ActivityImpl::clean_action()
+{
+ if (surf_action_) {
+ surf_action_->unref();
+ surf_action_ = nullptr;
+ }
+}
+
+double ActivityImpl::get_remaining() const
+{
+ return surf_action_ ? surf_action_->get_remains() : 0;
+}
+
+const char* ActivityImpl::get_state_str() const
+{
+ return to_c_str(state_);
+}
+
+bool ActivityImpl::test(actor::ActorImpl* issuer)
+{
+ // Associate this simcall to the synchro
+ auto* observer = dynamic_cast<kernel::actor::ActivityTestSimcall*>(issuer->simcall_.observer_);
+ if (observer)
+ register_simcall(&issuer->simcall_);
+
+ if (state_ != State::WAITING && state_ != State::RUNNING) {
+ finish();
+ issuer->exception_ = nullptr; // Do not propagate exception in that case
+ return true;
+ }
+
+ if (observer) {
+ observer->set_result(false);
+ issuer->waiting_synchro_ = nullptr;
+ unregister_simcall(&issuer->simcall_);
+ issuer->simcall_answer();
+ }
+ return false;
+}