Maestro 0.3.11
Unified interface for quantum circuit simulation
Loading...
Searching...
No Matches
WorkerThread.h
Go to the documentation of this file.
1
11
12#pragma once
13
14#ifndef __WORKER_THREAD_H_
15#define __WORKER_THREAD_H_
16
17#include <atomic>
18#include <mutex>
19#include <thread>
20
21namespace Utils
22{
23
34template <class ThreadsPool, class Job> class WorkerThread
35{
36 public:
45 explicit WorkerThread(ThreadsPool *threadsPool) : threadsPool(threadsPool), StopFlag(false)
46 {
47 Thread = std::thread(&WorkerThread::Run, this);
48 }
49
57 {
58 Stop();
59 }
60
66 void Start()
67 {
68 if (Thread.joinable())
69 return;
70
71 {
72 std::lock_guard lock(threadsPool->Mutex);
73 StopFlag = false;
74 }
75 Thread = std::thread(&WorkerThread::Run, this);
76 }
77
83 void Stop()
84 {
85 if (!Thread.joinable())
86 return;
87
88 {
89 std::lock_guard lock(threadsPool->Mutex);
90
91 StopFlag = true;
92 }
93
94 Join();
95 }
96
103 {
104 StopFlag = true;
105 }
106
112 inline void Join()
113 {
114 if (Thread.joinable())
115 Thread.join();
116 }
117
125 void Abandon()
126 {
127 if (Thread.joinable())
128 (void)new std::thread(std::move(Thread));
129 }
130
131 private:
141 inline bool TerminateWait() const
142 {
143 return threadsPool->HasWork() || StopFlag;
144 }
145
154 void Run()
155 {
156 for (;;)
157 {
158 std::unique_lock lock(threadsPool->Mutex);
159 if (!TerminateWait())
160 threadsPool->Condition.wait(lock, [this] { return TerminateWait(); });
161
162 while (threadsPool->HasWork() && !StopFlag)
163 {
164 std::shared_ptr<Job> job = std::move(threadsPool->JobsQueue.front());
165 threadsPool->JobsQueue.pop();
166 ++threadsPool->Running;
167 lock.unlock();
168
169 job->DoWork();
170 const size_t count = job->GetJobCount();
171 // A job can own the pool's owner (execution jobs hold their
172 // network). Release it before it counts as finished, so the
173 // owner is never destroyed on one of its own workers.
174 job.reset();
175
176 // Idle before the waiter can see the job finished, so a fork()
177 // right after WaitForFinish() finds the pool idle.
178 lock.lock();
179 --threadsPool->Running;
180 {
181 std::lock_guard lockCount(threadsPool->FinishMutex);
182 threadsPool->FinishCount += count;
183 }
184 }
185
186 if (StopFlag)
187 break;
188 lock.unlock();
189 threadsPool->NotifyFinish();
190 }
191 }
192
193 ThreadsPool *threadsPool;
194 std::thread Thread;
195 bool StopFlag;
197};
198
199} // namespace Utils
200
201#endif // !__WORKER_THREAD_H_
ThreadsPool class for holding and controlling a pool of threads.
void Join()
Join the thread.
void Stop()
Stop the thread.
WorkerThread(ThreadsPool *threadsPool)
Construct a new Worker Thread object.
void Start()
Start the thread.
void SetStopUnlocked()
Set the stop flag without locking it.
void Abandon()
Forget a thread that does not exist any more.
~WorkerThread()
Destroy the Worker Thread object.
Portable dense contraction kernels.