Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
C bindings of ActivitySet, along with 4 examples
[simgrid.git] / src / s4u / s4u_ActivitySet.cpp
1 /* Copyright (c) 2023-. The SimGrid Team. All rights reserved.          */
2
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. */
5
6 #include "src/kernel/activity/ActivityImpl.hpp"
7 #include "src/kernel/actor/ActorImpl.hpp"
8 #include "src/kernel/actor/CommObserver.hpp"
9 #include <simgrid/Exception.hpp>
10 #include <simgrid/activity_set.h>
11 #include <simgrid/s4u/ActivitySet.hpp>
12 #include <simgrid/s4u/Engine.hpp>
13
14 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(s4u_activityset, s4u_activity, "S4U set of activities");
15
16 namespace simgrid {
17
18 template class xbt::Extendable<s4u::ActivitySet>;
19
20 namespace s4u {
21
22 void ActivitySet::erase(ActivityPtr a)
23 {
24   for (auto it = activities_.begin(); it != activities_.end(); it++)
25     if (*it == a) {
26       activities_.erase(it);
27       return;
28     }
29 }
30
31 void ActivitySet::wait_all_for(double timeout)
32 {
33   if (timeout < 0.0) {
34     for (const auto& act : activities_)
35       act->wait();
36
37   } else {
38
39     double deadline = Engine::get_clock() + timeout;
40     for (const auto& act : activities_)
41       act->wait_until(deadline);
42   }
43 }
44
45 ActivityPtr ActivitySet::test_any()
46 {
47   std::vector<kernel::activity::ActivityImpl*> act_impls(activities_.size());
48   std::transform(begin(activities_), end(activities_), begin(act_impls),
49                  [](const ActivityPtr& act) { return act->pimpl_.get(); });
50
51   kernel::actor::ActorImpl* issuer = kernel::actor::ActorImpl::self();
52   kernel::actor::ActivityTestanySimcall observer{issuer, act_impls, "test_any"};
53   ssize_t changed_pos = kernel::actor::simcall_answered(
54       [&observer] {
55         return kernel::activity::ActivityImpl::test_any(observer.get_issuer(), observer.get_activities());
56       },
57       &observer);
58   if (changed_pos == -1)
59     return ActivityPtr(nullptr);
60
61   auto ret = activities_.at(changed_pos);
62   erase(ret);
63   ret->complete(Activity::State::FINISHED);
64   return ret;
65 }
66
67 ActivityPtr ActivitySet::wait_any_for(double timeout)
68 {
69   std::vector<kernel::activity::ActivityImpl*> act_impls(activities_.size());
70   std::transform(begin(activities_), end(activities_), begin(act_impls),
71                  [](const ActivityPtr& activity) { return activity->pimpl_.get(); });
72
73   kernel::actor::ActorImpl* issuer = kernel::actor::ActorImpl::self();
74   kernel::actor::ActivityWaitanySimcall observer{issuer, act_impls, timeout, "wait_any_for"};
75   ssize_t changed_pos = kernel::actor::simcall_blocking(
76       [&observer] {
77         kernel::activity::ActivityImpl::wait_any_for(observer.get_issuer(), observer.get_activities(),
78                                                      observer.get_timeout());
79       },
80       &observer);
81   if (changed_pos == -1)
82     throw TimeoutException(XBT_THROW_POINT, "Timeouted");
83
84   auto ret = activities_.at(changed_pos);
85   erase(ret);
86   ret->complete(Activity::State::FINISHED);
87   return ret;
88 }
89
90 ActivityPtr ActivitySet::get_failed_activity()
91 {
92   if (failed_activities_.empty())
93     return ActivityPtr(nullptr);
94   auto ret = failed_activities_.back();
95   failed_activities_.pop_back();
96   return ret;
97 }
98
99 } // namespace s4u
100 } // namespace simgrid
101
102 SG_BEGIN_DECL
103
104 sg_activity_set_t sg_activity_set_init()
105 {
106   return new simgrid::s4u::ActivitySet();
107 }
108 void sg_activity_set_push(sg_activity_set_t as, sg_activity_t acti)
109 {
110   as->push(acti);
111 }
112 void sg_activity_set_erase(sg_activity_set_t as, sg_activity_t acti)
113 {
114   as->erase(acti);
115 }
116 size_t sg_activity_set_size(sg_activity_set_t as)
117 {
118   return as->size();
119 }
120 int sg_activity_set_empty(sg_activity_set_t as)
121 {
122   return as->empty();
123 }
124
125 sg_activity_t sg_activity_set_test_any(sg_activity_set_t as)
126 {
127   return as->test_any().get();
128 }
129 void sg_activity_set_wait_all(sg_activity_set_t as)
130 {
131   as->wait_all();
132 }
133 int sg_activity_set_wait_all_for(sg_activity_set_t as, double timeout)
134 {
135   try {
136     as->wait_all_for(timeout);
137     return 1;
138   } catch (const simgrid::TimeoutException& e) {
139     return 0;
140   }
141 }
142 sg_activity_t sg_activity_set_wait_any(sg_activity_set_t as)
143 {
144   return as->wait_any().get();
145 }
146 sg_activity_t sg_activity_set_wait_any_for(sg_activity_set_t as, double timeout)
147 {
148   try {
149     return as->wait_any_for(timeout).get();
150   } catch (const simgrid::TimeoutException& e) {
151     return nullptr;
152   }
153 }
154
155 void sg_activity_set_delete(sg_activity_set_t as)
156 {
157   delete as;
158 }
159
160 SG_END_DECL