Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Document ActivitySet
[simgrid.git] / include / simgrid / s4u / ActivitySet.hpp
index 4add822..10ec7c8 100644 (file)
 
 #include <vector>
 
-namespace simgrid::s4u {
+namespace simgrid {
+
+extern template class XBT_PUBLIC xbt::Extendable<s4u::ActivitySet>;
+
+namespace s4u {
 /** @brief ActivitiesSet
  *
  * This class is a container of activities, allowing to wait for the completion of any or all activities in the set.
@@ -19,12 +23,15 @@ namespace simgrid::s4u {
  * activities.
  */
 class XBT_PUBLIC ActivitySet : public xbt::Extendable<ActivitySet> {
-  std::vector<ActivityPtr>
-      activities_; // We use a vector instead of a set to improve reproductibility accross architectures
+  std::atomic_int_fast32_t refcount_{1};
+  std::vector<ActivityPtr> activities_; // Use vectors, not sets for better reproductibility accross architectures
   std::vector<ActivityPtr> failed_activities_;
 
+  void handle_failed_activities();
+
 public:
   ActivitySet()  = default;
+  ActivitySet(const std::vector<ActivityPtr> init) : activities_(init) {}
   ~ActivitySet() = default;
 
   /** Add an activity to the set */
@@ -39,11 +46,12 @@ public:
 
   /** Wait for the completion of all activities in the set, but not longer than the provided timeout
    *
-   * On timeout, an exception is raised, and the completed activities remain in the set. Use test_any() to retrieve
-   * them.
+   * On timeout, an exception is raised.
+   *
+   * In any case, the completed activities remain in the set. Use test_any() to retrieve them.
    */
   void wait_all_for(double timeout);
-  /** Wait for the completion of all activities in the set */
+  /** Wait for the completion of all activities in the set. The set is NOT emptied afterward. */
   void wait_all() { wait_all_for(-1); }
   /** Returns the first terminated activity if any, or ActivityPtr(nullptr) if no activity is terminated */
   ActivityPtr test_any();
@@ -70,10 +78,27 @@ public:
    */
   ActivityPtr wait_any() { return wait_any_for(-1); }
 
+  /** Return one of the failed activity of the set that was revealed during the previous wait operation, or
+   * ActivityPtr() if no failed activity exist in the set. */
   ActivityPtr get_failed_activity();
+  /** Return whether the set contains any failed activity. */
   bool has_failed_activities() { return not failed_activities_.empty(); }
+
+  // boost::intrusive_ptr<ActivitySet> support:
+  friend void intrusive_ptr_add_ref(ActivitySet* as)
+  {
+    XBT_ATTRIB_UNUSED auto previous = as->refcount_.fetch_add(1);
+    xbt_assert(previous != 0);
+  }
+
+  friend void intrusive_ptr_release(ActivitySet* as)
+  {
+    if (as->refcount_.fetch_sub(1) == 1)
+      delete as;
+  }
 };
 
-}; // namespace simgrid::s4u
+} // namespace s4u
+} // namespace simgrid
 
 #endif