X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/d3895264c64b329397e38b3a6a1fc054672f3f55..45e860b49df0a17950158c0f5c6403463bd68b71:/src/include/xbt/parmap.hpp diff --git a/src/include/xbt/parmap.hpp b/src/include/xbt/parmap.hpp index a47f35f92d..77d13e0b88 100644 --- a/src/include/xbt/parmap.hpp +++ b/src/include/xbt/parmap.hpp @@ -62,25 +62,25 @@ private: class Synchro { public: explicit Synchro(Parmap& parmap) : parmap(parmap) {} - virtual ~Synchro() {} + virtual ~Synchro() = default; /** * \brief Wakes all workers and waits for them to finish the tasks. * * This function is called by the controller thread. */ - virtual void master_signal() = 0; + virtual void master_signal() = 0; /** * \brief Starts the parmap: waits for all workers to be ready and returns. * * This function is called by the controller thread. */ - virtual void master_wait() = 0; + virtual void master_wait() = 0; /** * \brief Ends the parmap: wakes the controller thread when all workers terminate. * * This function is called by all worker threads when they end (not including the controller). */ - virtual void worker_signal() = 0; + virtual void worker_signal() = 0; /** * \brief Waits for some work to process. * @@ -90,7 +90,6 @@ private: */ virtual void worker_wait(unsigned) = 0; - protected: Parmap& parmap; }; @@ -138,15 +137,16 @@ private: Synchro* new_synchro(e_xbt_parmap_mode_t mode); void work(); - Flag status; /**< is the parmap active or being destroyed? */ - unsigned work_round; /**< index of the current round */ - unsigned thread_counter; /**< number of workers that have done the work */ - unsigned num_workers; /**< total number of worker threads including the controller */ - xbt_os_thread_t* workers; /**< worker thread handlers */ - void (*fun)(const T); /**< function to run in parallel on each element of data */ - const std::vector* data; /**< parameters to pass to fun in parallel */ - std::atomic index; /**< index of the next element of data to pick */ - Synchro* synchro; /**< synchronization object */ + Flag status; /**< is the parmap active or being destroyed? */ + unsigned work_round; /**< index of the current round */ + xbt_os_thread_t* workers; /**< worker thread handlers */ + unsigned num_workers; /**< total number of worker threads including the controller */ + Synchro* synchro; /**< synchronization object */ + + unsigned thread_counter = 0; /**< number of workers that have done the work */ + void (*fun)(const T) = nullptr; /**< function to run in parallel on each element of data */ + const std::vector* data = nullptr; /**< parameters to pass to fun in parallel */ + std::atomic index; /**< index of the next element of data to pick */ }; /** @@ -224,7 +224,7 @@ template void Parmap::apply(void (*fun)(T), const std::vector */ template boost::optional Parmap::next() { - unsigned index = this->index++; + unsigned index = this->index.fetch_add(1, std::memory_order_relaxed); if (index < this->data->size()) return (*this->data)[index]; else @@ -236,11 +236,11 @@ template boost::optional Parmap::next() */ template void Parmap::work() { - unsigned index = this->index++; unsigned length = this->data->size(); + unsigned index = this->index.fetch_add(1, std::memory_order_relaxed); while (index < length) { this->fun((*this->data)[index]); - index = this->index++; + index = this->index.fetch_add(1, std::memory_order_relaxed); } } @@ -381,25 +381,25 @@ template inline void Parmap::FutexSynchro::futex_wake(unsigned* template void Parmap::FutexSynchro::master_signal() { - this->parmap.thread_counter = 1; - __sync_add_and_fetch(&this->parmap.work_round, 1); + __atomic_store_n(&this->parmap.thread_counter, 1, __ATOMIC_SEQ_CST); + __atomic_add_fetch(&this->parmap.work_round, 1, __ATOMIC_SEQ_CST); /* wake all workers */ futex_wake(&this->parmap.work_round, std::numeric_limits::max()); } template void Parmap::FutexSynchro::master_wait() { - unsigned count = this->parmap.thread_counter; + unsigned count = __atomic_load_n(&this->parmap.thread_counter, __ATOMIC_SEQ_CST); while (count < this->parmap.num_workers) { /* wait for all workers to be ready */ futex_wait(&this->parmap.thread_counter, count); - count = this->parmap.thread_counter; + count = __atomic_load_n(&this->parmap.thread_counter, __ATOMIC_SEQ_CST); } } template void Parmap::FutexSynchro::worker_signal() { - unsigned count = __sync_add_and_fetch(&this->parmap.thread_counter, 1); + unsigned count = __atomic_add_fetch(&this->parmap.thread_counter, 1, __ATOMIC_SEQ_CST); if (count == this->parmap.num_workers) { /* all workers have finished, wake the controller */ futex_wake(&this->parmap.thread_counter, std::numeric_limits::max()); @@ -408,37 +408,37 @@ template void Parmap::FutexSynchro::worker_signal() template void Parmap::FutexSynchro::worker_wait(unsigned round) { - unsigned work_round = this->parmap.work_round; + unsigned work_round = __atomic_load_n(&this->parmap.work_round, __ATOMIC_SEQ_CST); /* wait for more work */ while (work_round != round) { futex_wait(&this->parmap.work_round, work_round); - work_round = this->parmap.work_round; + work_round = __atomic_load_n(&this->parmap.work_round, __ATOMIC_SEQ_CST); } } #endif template void Parmap::BusyWaitSynchro::master_signal() { - this->parmap.thread_counter = 1; - __sync_add_and_fetch(&this->parmap.work_round, 1); + __atomic_store_n(&this->parmap.thread_counter, 1, __ATOMIC_SEQ_CST); + __atomic_add_fetch(&this->parmap.work_round, 1, __ATOMIC_SEQ_CST); } template void Parmap::BusyWaitSynchro::master_wait() { - while (this->parmap.thread_counter < this->parmap.num_workers) { + while (__atomic_load_n(&this->parmap.thread_counter, __ATOMIC_SEQ_CST) < this->parmap.num_workers) { xbt_os_thread_yield(); } } template void Parmap::BusyWaitSynchro::worker_signal() { - __sync_add_and_fetch(&this->parmap.thread_counter, 1); + __atomic_add_fetch(&this->parmap.thread_counter, 1, __ATOMIC_SEQ_CST); } template void Parmap::BusyWaitSynchro::worker_wait(unsigned round) { /* wait for more work */ - while (this->parmap.work_round != round) { + while (__atomic_load_n(&this->parmap.work_round, __ATOMIC_SEQ_CST) != round) { xbt_os_thread_yield(); } }