X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/29a3b2869c0075fc75e8ccc66fc1d9c4c8bf6a85..3d96858a5d972ece808c8bb79a8add51f6235603:/src/include/xbt/parmap.hpp diff --git a/src/include/xbt/parmap.hpp b/src/include/xbt/parmap.hpp index b8fbed6b5d..f2360eb4d3 100644 --- a/src/include/xbt/parmap.hpp +++ b/src/include/xbt/parmap.hpp @@ -1,6 +1,6 @@ /* A thread pool (C++ version). */ -/* Copyright (c) 2004-2018 The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2004-2019 The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -22,6 +22,10 @@ #include #endif +#if HAVE_PTHREAD_NP_H +#include +#endif + XBT_LOG_EXTERNAL_CATEGORY(xbt_parmap); namespace simgrid { @@ -137,7 +141,7 @@ private: 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 */ + std::vector workers; /**< worker thread handlers */ unsigned num_workers; /**< total number of worker threads including the controller */ Synchro* synchro; /**< synchronization object */ @@ -159,21 +163,25 @@ template Parmap::Parmap(unsigned num_workers, e_xbt_parmap_mode_ /* Initialize the thread pool data structure */ this->status = PARMAP_WORK; this->work_round = 0; - this->workers = new xbt_os_thread_t[num_workers]; + this->workers.reserve(num_workers); this->num_workers = num_workers; this->synchro = new_synchro(mode); - /* Create the pool of worker threads */ + /* Create the pool of worker threads (the caller of apply() will be worker[0]) */ this->workers[0] = nullptr; -#if HAVE_PTHREAD_SETAFFINITY - int core_bind = 0; -#endif + XBT_ATTRIB_UNUSED unsigned int core_bind = 0; + for (unsigned i = 1; i < num_workers; i++) { - ThreadData* data = new ThreadData(*this, i); - this->workers[i] = xbt_os_thread_create(nullptr, worker_main, data, nullptr); + this->workers[i] = new std::thread(worker_main, new ThreadData(*this, i)); + + /* Bind the worker to a core if possible */ #if HAVE_PTHREAD_SETAFFINITY - xbt_os_thread_bind(this->workers[i], core_bind); - if (core_bind != xbt_os_get_numcores() - 1) + pthread_t pthread = this->workers[i]->native_handle(); + cpu_set_t cpuset; + CPU_ZERO(&cpuset); + CPU_SET(core_bind, &cpuset); + pthread_setaffinity_np(pthread, sizeof(cpu_set_t), &cpuset); + if (core_bind != std::thread::hardware_concurrency() - 1) core_bind++; else core_bind = 0; @@ -190,9 +198,9 @@ template Parmap::~Parmap() synchro->master_signal(); for (unsigned i = 1; i < num_workers; i++) - xbt_os_thread_join(workers[i], nullptr); + workers[i]->join(); - delete[] workers; + workers.clear(); delete synchro; } @@ -276,22 +284,20 @@ template typename Parmap::Synchro* Parmap::new_synchro(e_xbt_ return res; } -/** - * @brief Main function of a worker thread. - */ +/** @brief Main function of a worker thread */ template void* Parmap::worker_main(void* arg) { ThreadData* data = static_cast(arg); Parmap& parmap = data->parmap; unsigned round = 0; smx_context_t context = SIMIX_context_new(std::function(), nullptr, nullptr); - SIMIX_context_set_current(context); + kernel::context::Context::set_current(context); XBT_CDEBUG(xbt_parmap, "New worker thread created"); /* Worker's main loop */ while (1) { - round++; + round++; // New scheduling round parmap.synchro->worker_wait(round); if (parmap.status == PARMAP_DESTROY) break;