X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/844de0597296879c91593ae0604d5718498b81e3..7ddbdc25753a729517ed23899c83eb808acdd50f:/src/include/xbt/parmap.hpp diff --git a/src/include/xbt/parmap.hpp b/src/include/xbt/parmap.hpp index 5f97049f11..4e073a14a7 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. */ @@ -10,7 +10,6 @@ #include "src/internal_config.h" // HAVE_FUTEX_H #include "src/kernel/context/Context.hpp" -#include "xbt/xbt_os_thread.h" #include #include @@ -22,6 +21,10 @@ #include #endif +#if HAVE_PTHREAD_NP_H +#include +#endif + XBT_LOG_EXTERNAL_CATEGORY(xbt_parmap); namespace simgrid { @@ -137,7 +140,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 +162,35 @@ 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.resize(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; - unsigned int core_bind = 0; + 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); - xbt_os_thread_bind(this->workers[i], core_bind); + this->workers[i] = new std::thread(worker_main, new ThreadData(*this, i)); + + /* Bind the worker to a core if possible */ +#if HAVE_PTHREAD_SETAFFINITY +#if HAVE_PTHREAD_NP_H /* FreeBSD ? */ + cpuset_t cpuset; + size_t size = sizeof(cpuset_t); +#else /* Linux ? */ + cpu_set_t cpuset; + size_t size = sizeof(cpu_set_t); +#endif + pthread_t pthread = this->workers[i]->native_handle(); + CPU_ZERO(&cpuset); + CPU_SET(core_bind, &cpuset); + pthread_setaffinity_np(pthread, size, &cpuset); if (core_bind != std::thread::hardware_concurrency() - 1) core_bind++; else core_bind = 0; +#endif } } @@ -186,9 +203,8 @@ 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; delete synchro; } @@ -272,22 +288,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;