Nektar++
ThreadStd.h
Go to the documentation of this file.
1///////////////////////////////////////////////////////////////////////////////
2//
3// File: ThreadStd.h
4//
5// For more information, please see: http://www.nektar.info
6//
7// The MIT License
8//
9// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
10// Department of Aeronautics, Imperial College London (UK), and Scientific
11// Computing and Imaging Institute, University of Utah (USA).
12//
13// Permission is hereby granted, free of charge, to any person obtaining a
14// copy of this software and associated documentation files (the "Software"),
15// to deal in the Software without restriction, including without limitation
16// the rights to use, copy, modify, merge, publish, distribute, sublicense,
17// and/or sell copies of the Software, and to permit persons to whom the
18// Software is furnished to do so, subject to the following conditions:
19//
20// The above copyright notice and this permission notice shall be included
21// in all copies or substantial portions of the Software.
22//
23// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29// DEALINGS IN THE SOFTWARE.
30//
31// Description: Thread manager implementation using std::thread.
32//
33///////////////////////////////////////////////////////////////////////////////
34
35#ifndef NEKTAR_LIBUTILITIES_THREADSTD_H_
36#define NEKTAR_LIBUTILITIES_THREADSTD_H_
37
38#include <condition_variable>
39#include <map>
40#include <mutex>
41#include <queue>
42#include <vector>
43
46
47namespace Nektar::Thread
48{
49
50typedef std::unique_lock<std::mutex> Lock;
51
52class ThreadWorkerStd;
53
54/**
55 * @brief Implementation of ThreadManager using std::thread.
56 */
58{
59 /// Lightweight barrier class
60 class Barrier
61 {
62 public:
63 explicit Barrier(std::size_t iCount)
64 : mThreshold(iCount), mCount(iCount), mGeneration(0)
65 {
66 }
67
68 void Wait()
69 {
70 std::unique_lock<std::mutex> lLock{mMutex};
71 auto lGen = mGeneration;
72 if (!--mCount)
73 {
76 mCond.notify_all();
77 }
78 else
79 {
80 mCond.wait(lLock, [this, lGen] { return lGen != mGeneration; });
81 }
82 }
83
84 private:
85 std::mutex mMutex;
86 std::condition_variable mCond;
87 std::size_t mThreshold;
88 std::size_t mCount;
89 std::size_t mGeneration;
90 };
91
92 /**
93 * So the workers can access the master queue and locks.
94 */
95 friend class ThreadWorkerStd;
96
97public:
98 /// Constructs a ThreadManagerStd.
99 ThreadManagerStd(unsigned int numWorkers);
100 /// Shuts down threading.
101 ~ThreadManagerStd() override;
102
103 /// Called by the factory method.
104 static ThreadManagerSharedPtr Create(unsigned int numT)
105 {
106 return std::shared_ptr<ThreadManager>(new ThreadManagerStd(numT));
107 }
108
109protected:
110 void v_QueueJobs(std::vector<ThreadJob *> &joblist) override;
111 void v_QueueJob(ThreadJob *job) override;
112 unsigned int v_GetNumWorkers() override;
113 unsigned int v_GetWorkerNum() override;
114 void v_SetNumWorkers(const unsigned int num) override;
115 void v_SetNumWorkers() override;
116 unsigned int v_GetMaxNumWorkers() override;
117 void v_Wait() override;
118 void v_SetChunkSize(unsigned int chnk) override;
119 void v_SetSchedType(SchedType s) override;
120 bool v_InThread() override;
121 void v_Hold() override;
122 const std::string &v_GetType() const override;
123
124private:
127 bool IsWorking();
128 void SetNumWorkersImpl(const unsigned int num);
129
130 // Member variables
131 const unsigned int m_numThreads;
132 unsigned int m_numWorkers;
133 std::queue<ThreadJob *> m_masterQueue;
136 std::condition_variable m_masterQueueCondVar;
137 std::condition_variable m_masterActiveCondVar;
139 std::thread **m_threadThreadList;
140 std::thread::id m_masterThreadId;
143 unsigned int m_chunkSize;
146 std::map<std::thread::id, unsigned int> m_threadMap;
147 static std::string className;
148 std::string m_type;
149};
150
151/**
152 * @brief Implementation class for ThreadManagerStd.
153 *
154 * Each instance of this class corresponds to a worker thread.
155 * Instances manage their own queue of jobs to run, grabbing new
156 * jobs from the master queue when it is exhausted.
157 */
159{
160public:
161 /// Constructor
162 ThreadWorkerStd(ThreadManagerStd *threadManager, unsigned int workerNum);
163 /// Destructor.
165 /// This provides the interface that std::thread uses to start the worker.
167 {
168 MainLoop();
169 };
170 /**
171 * @brief Return the index of the worker thread.
172 * @return Index of worker thread, an integer between 0 and
173 * (number_of_threads - 1)
174 */
175 unsigned int GetWorkerNum()
176 {
177 return m_threadNum;
178 };
179 /**
180 * @brief A signal to shut down.
181 *
182 * If this method is called the worker will shut down. Used by the
183 * ThreadManagerStd to stop threading.
184 */
185 void Stop()
186 {
187 m_keepgoing = false;
188 };
189
190private:
193 void MainLoop();
194 void LoadJobs();
195 unsigned int GetNumToLoad();
196 void WaitForActive();
197 void RunJobs();
198
199 // Member variables
201 std::queue<ThreadJob *> m_workerQueue;
203 unsigned int m_threadNum;
204};
205
206} // namespace Nektar::Thread
207
208#endif
Base class for tasks to be sent to the ThreadManager to run.
Definition: Thread.h:94
The interface class for the controller for worker threads and jobs.
Definition: Thread.h:160
Lightweight barrier class.
Definition: ThreadStd.h:61
Implementation of ThreadManager using std::thread.
Definition: ThreadStd.h:58
void v_SetSchedType(SchedType s) override
Definition: ThreadStd.cpp:188
~ThreadManagerStd() override
Shuts down threading.
Definition: ThreadStd.cpp:115
const std::string & v_GetType() const override
Definition: ThreadStd.cpp:300
std::map< std::thread::id, unsigned int > m_threadMap
Definition: ThreadStd.h:146
void v_QueueJob(ThreadJob *job) override
Definition: ThreadStd.cpp:155
ThreadWorkerStd ** m_threadList
Definition: ThreadStd.h:138
void v_QueueJobs(std::vector< ThreadJob * > &joblist) override
Definition: ThreadStd.cpp:143
static ThreadManagerSharedPtr Create(unsigned int numT)
Called by the factory method.
Definition: ThreadStd.h:104
std::thread ** m_threadThreadList
Definition: ThreadStd.h:139
std::thread::id m_masterThreadId
Definition: ThreadStd.h:140
unsigned int v_GetNumWorkers() override
Definition: ThreadStd.cpp:225
ThreadManagerStd(const ThreadManagerStd &)
const unsigned int m_numThreads
Definition: ThreadStd.h:131
std::queue< ThreadJob * > m_masterQueue
Definition: ThreadStd.h:133
std::condition_variable m_masterQueueCondVar
Definition: ThreadStd.h:136
std::condition_variable m_masterActiveCondVar
Definition: ThreadStd.h:137
void SetNumWorkersImpl(const unsigned int num)
Definition: ThreadStd.cpp:242
unsigned int v_GetMaxNumWorkers() override
Definition: ThreadStd.cpp:284
void v_SetChunkSize(unsigned int chnk) override
Definition: ThreadStd.cpp:179
unsigned int v_GetWorkerNum() override
Definition: ThreadStd.cpp:233
static std::string className
Definition: ThreadStd.h:147
Implementation class for ThreadManagerStd.
Definition: ThreadStd.h:159
std::queue< ThreadJob * > m_workerQueue
Definition: ThreadStd.h:201
ThreadManagerStd * m_threadManager
Definition: ThreadStd.h:200
void Stop()
A signal to shut down.
Definition: ThreadStd.h:185
unsigned int GetWorkerNum()
Return the index of the worker thread.
Definition: ThreadStd.h:175
void operator()()
This provides the interface that std::thread uses to start the worker.
Definition: ThreadStd.h:166
ThreadWorkerStd(const ThreadWorkerStd &)
std::unique_lock< std::mutex > Lock
Definition: ThreadStd.h:50
SchedType
Identifies the algorithm for scheduling.
Definition: Thread.h:63
std::shared_ptr< ThreadManager > ThreadManagerSharedPtr
Definition: Thread.h:69