From: Martin Quinson Date: Wed, 5 Jul 2017 23:18:41 +0000 (+0200) Subject: change the prototype of s4u::Comm::wait_any to mimick the C code X-Git-Tag: v3_17~451 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/08447964cfc19a4b579429ef71c0fccebd60199f change the prototype of s4u::Comm::wait_any to mimick the C code Returning an iterator was not working as we returned every elements in the input collection, without any sorting (fix #170). Returning a collection or an iterator is difficult, as is. We would have to build the collection in the backstage, iterating over the provided comms to see which ones are done. Plus, the user would probably want to then find these comms in the provided vector to remove them from there. In the end, that would be a lot of useless and potentially unefficient code. It seems much better to provide the index in the vector provided by the user. If she wants, she can iterate from there to see if the comms are to be removed, or she can just remove this one and fire another wait_any. Maybe less C++ish, but more efficient and not that ugly either. --- diff --git a/include/simgrid/s4u/Comm.hpp b/include/simgrid/s4u/Comm.hpp index d409c0b073..f57798004f 100644 --- a/include/simgrid/s4u/Comm.hpp +++ b/include/simgrid/s4u/Comm.hpp @@ -11,6 +11,9 @@ #include #include #include + +#include + namespace simgrid { namespace s4u { /** @brief Communication async @@ -28,19 +31,15 @@ public: /*! take a range of s4u::CommPtr (last excluded) and return when one of them is finished. The return value is an * iterator on the finished Comms. */ - template static I wait_any(I first, I last) - { - return wait_any_for(first, last, -1); - } + static int wait_any(std::vector * comms) { return wait_any_for(comms, -1); } /*! Same as wait_any, but with a timeout. If the timeout occurs, parameter last is returned.*/ - template static I wait_any_for(I first, I last, double timeout) + static int wait_any_for(std::vector * comms_in, double timeout) { // Map to dynar: xbt_dynar_t comms = xbt_dynar_new(sizeof(simgrid::kernel::activity::ActivityImpl*), [](void*ptr){ intrusive_ptr_release(*(simgrid::kernel::activity::ActivityImpl**)ptr); }); - for (I iter = first; iter != last; iter++) { - CommPtr comm = *iter; + for (auto comm : *comms_in) { if (comm->state_ == inited) comm->start(); xbt_assert(comm->state_ == started); @@ -51,13 +50,7 @@ public: // Call the underlying simcall: int idx = simcall_comm_waitany(comms, timeout); xbt_dynar_free(&comms); - // Not found: - if (idx == -1) - return last; - // Lift the index to the corresponding iterator: - auto res = std::next(first, idx); - (*res)->state_ = finished; - return res; + return idx; } /** Creates (but don't start) an async send to the mailbox @p dest */ static CommPtr send_init(MailboxPtr dest); diff --git a/teshsuite/s4u/comm-waitany/comm-waitany.cpp b/teshsuite/s4u/comm-waitany/comm-waitany.cpp index 75784b948b..50303b178a 100644 --- a/teshsuite/s4u/comm-waitany/comm-waitany.cpp +++ b/teshsuite/s4u/comm-waitany/comm-waitany.cpp @@ -29,16 +29,10 @@ static void receiver() XBT_INFO("Sleeping for 3 seconds (for the %dth time)...", i + 1); simgrid::s4u::this_actor::sleep_for(3.0); XBT_INFO("Calling wait_any() for %zu pending comms", pending_comms.size()); - std::vector::iterator ret_it = - simgrid::s4u::Comm::wait_any(pending_comms.begin(), pending_comms.end()); + int changed_pos = simgrid::s4u::Comm::wait_any(&pending_comms); XBT_INFO("Counting the number of completed comms..."); - int count = 0; - for (; ret_it != pending_comms.end(); count++, ret_it++) - ; - - XBT_INFO("wait_any() replied that %d comms have completed", count); - // xbt_assert(count == 1, "wait_any() replied that %d comms have completed, which is broken!", count); + pending_comms.erase(pending_comms.begin() + changed_pos); } }