/*////////////////////////////////////////////////////////////////////////////// // CMT Cosmic Muon Tomography project ////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova All rights reserved Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > ------------------------------------------------------------------ This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3.0 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. //////////////////////////////////////////////////////////////////////////////*/ #ifndef U_CORE_THREADS_H #define U_CORE_THREADS_H #include #include #include #include #include #include "Core/Monitor.h" #include "Core/Object.h" namespace uLib { /** * @brief Thread class wraps std::thread and provides a common interface. */ class Thread : public Object { public: Thread(); virtual ~Thread(); /** @brief Starts the thread by calling Run(). */ void Start(); /** @brief Joins the thread. */ void Join(); /** @brief Detaches the thread. */ void Detach(); /** @brief Returns true if the thread is currently joinable. */ bool IsJoinable() const; /** @brief Returns true if the thread is currently running. */ bool IsRunning() const; /** @brief The entry point for the thread. Override this in subclasses. */ virtual void Run(); /** @brief Static helper to sleep the current thread. */ static void Sleep(int milliseconds); /** @brief Static helper to yield the current thread. */ static void Yield(); /** @brief Returns the native handle of the thread. */ std::thread::native_handle_type GetNativeHandle() { return m_Thread.native_handle(); } /** @brief Sets CPU affinity for the thread. (Linux only) */ void SetAffinity(int cpu); /** @brief Sets CPU affinity for the thread using a list of CPUs. (Linux only) */ void SetAffinity(const std::vector& cpus); // OpenMP Support // /** @brief Sets the number of threads for OpenMP parallel regions. */ static void SetNumThreads(int n); /** @brief Returns the number of threads for OpenMP parallel regions. */ static int GetNumThreads(); /** @brief Returns the ID of the current thread in an OpenMP parallel region. */ static int GetThreadNum(); protected: // Internal thread entry point void ThreadEntryPoint(); std::thread m_Thread; std::atomic m_Running; mutable Mutex m_ThreadMutex; }; /** * @brief Task class wraps a function call to be executed by a Team. */ class Task : public Object { public: Task(std::function func) : m_Func(func) {} virtual ~Task() = default; /** @brief Executes the task. */ virtual void Execute() { if (m_Func) m_Func(); } protected: std::function m_Func; }; /** * @brief Team class manages a group of threads and can execute Tasks. * This is designed to be compatible with OpenMP tasks and teams. */ class Team : public Object { public: Team(int num_threads = -1); virtual ~Team(); /** @brief Runs a task within the team. Uses OpenMP task if available. */ void Run(Task* task); /** @brief Waits for all tasks in the team to finish. */ void Wait(); /** @brief Sets the number of threads for this team. */ void SetSize(int n); /** @brief Returns the number of threads in the team. */ int GetSize() const { return m_Size; } /** @brief Sets CPU affinity for all threads in the team. */ void SetAffinity(const std::vector& cpus); protected: int m_Size; bool m_UseOpenMP; std::vector m_Threads; }; } // namespace uLib #endif // U_CORE_THREADS_H