-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathThreading.h
261 lines (219 loc) · 10.9 KB
/
Threading.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
//--------------------------------------------------------------------------------------
// File: Threading.h
//
// Distributed as part of NVIDIA Nsight serialization output.
//
// Copyright (c) NVIDIA Corporation. All rights reserved.
//--------------------------------------------------------------------------------------
#pragma once
#include "ReplayHelpers.h"
#if defined(WIN32)
#include <Windows.h>
#else // defined(WIN32)
#include <condition_variable>
#include <memory>
#include <mutex>
#endif // defined(WIN32)
//--------------------------------------------------------------------------------------
// NV_EXEC - Wrapper macro for functions
// -------------------------------------------------------------------------------------
#define NV_EXEC(_Function) _Function
#if defined(WIN32)
//--------------------------------------------------------------------------------------
// NV_SIGNAL_THREAD_AND_WAIT - Signal a waiting thread to begin execution and wait
// to be signaled
// -------------------------------------------------------------------------------------
#define NV_SIGNAL_THREAD_AND_WAIT(_ThreadId) \
SetEvent(threadSequenceEvents[_ThreadId]); \
WaitForSingleObject(threadSequenceEvents[threadId], INFINITE)
//--------------------------------------------------------------------------------------
// NV_SIGNAL_THREAD - Signal a waiting thread to begin execution
// -------------------------------------------------------------------------------------
#define NV_SIGNAL_THREAD(_ThreadId) \
SetEvent(threadSequenceEvents[_ThreadId])
//--------------------------------------------------------------------------------------
// NV_WAIT - Wait untils this thread is signaled
// -------------------------------------------------------------------------------------
#define NV_WAIT_FOR_SIGNAL() \
WaitForSingleObject(threadSequenceEvents[threadId], INFINITE)
//--------------------------------------------------------------------------------------
// NV_SIGNAL_FRAME_COMPLETE - Signal that the frame traversal has been completed
// -------------------------------------------------------------------------------------
#define NV_SIGNAL_FRAME_COMPLETE() \
for (unsigned int i = 0; i < NUM_REPLAYER_THREADS; ++i) \
{ \
if (i != threadId) \
{ \
SetEvent(threadSequenceEvents[i]); \
} \
}
#else // defined(WIN32)
//--------------------------------------------------------------------------------------
// NV_SIGNAL_THREAD_AND_WAIT - Signal a waiting thread to begin execution and wait
// to be signaled
// -------------------------------------------------------------------------------------
#define NV_SIGNAL_THREAD_AND_WAIT(_ThreadId) \
threadSequenceEvents[_ThreadId]->Signal(); \
threadSequenceEvents[threadId]->Wait()
//--------------------------------------------------------------------------------------
// NV_SIGNAL_FRAME_COMPLETE - Signal that the frame traversal has been completed
// -------------------------------------------------------------------------------------
#define NV_SIGNAL_FRAME_COMPLETE() \
for (unsigned int i = 0; i < NUM_REPLAYER_THREADS; ++i) \
{ \
if (i != threadId) \
{ \
threadSequenceEvents[i]->Signal(); \
} \
}
#endif // defined(WIN32)
//--------------------------------------------------------------------------------------
// Function pointer types
//--------------------------------------------------------------------------------------
using ThreadInitFunc = void (*)();
using ThreadReleaseFunc = void (*)();
using RunFrameFunc = void (*)();
using ResetFrameFunc = void (*)(bool);
#if defined(WIN32)
//--------------------------------------------------------------------------------------
// ThreadRunner - Class and derived classes used to manage the running of threads
//--------------------------------------------------------------------------------------
class ThreadRunner
{
public:
ThreadRunner(HANDLE sequenceEvent, HANDLE doneEvent, RunFrameFunc runFrameFunc);
virtual ~ThreadRunner()
{
}
virtual void Init()
{
}
virtual void Release()
{
}
void RunThread();
protected:
void SignalMainThreadAndWait() const;
private:
virtual void PreRunThread()
{
}
virtual void PostRunThread()
{
}
HANDLE m_sequenceEvent;
HANDLE m_doneEvent;
RunFrameFunc m_runFrameFunc;
};
class BasicThreadRunner : public ThreadRunner
{
public:
BasicThreadRunner(HANDLE sequenceEvent, HANDLE doneEvent, RunFrameFunc runFrameFunc, ResetFrameFunc resetFrameFunc);
private:
virtual void PostRunThread() override;
ResetFrameFunc m_resetFrameFunc;
};
//--------------------------------------------------------------------------------------
// ThreadStart - The method each replayer thread begins running
//--------------------------------------------------------------------------------------
DWORD WINAPI ThreadStart(LPVOID lpParameter);
//--------------------------------------------------------------------------------------
// CreateThreadEvents - Create Windows events used to synchronize the threads
//--------------------------------------------------------------------------------------
bool CreateThreadEvents(unsigned int numThreads, HANDLE* events);
//--------------------------------------------------------------------------------------
// CreateReplayerThreads - Create and start the replayer threads
//--------------------------------------------------------------------------------------
bool CreateReplayerThreads(ThreadRunner** threadRunners, unsigned int numThreads, HANDLE* sequenceEvents, HANDLE* doneEvents, bool& exitThreads, bool& releaseThreads);
//--------------------------------------------------------------------------------------
// ReleaseReplayerThreads - Release all of the replayer threads
//--------------------------------------------------------------------------------------
void ReleaseReplayerThreads(unsigned int numThreads, HANDLE* sequenceEvents, HANDLE* doneEvents, bool& releaseThreads);
//--------------------------------------------------------------------------------------
// ExitReplayerThreads - Exit all of the replayer threads
//--------------------------------------------------------------------------------------
void ExitReplayerThreads(unsigned int numThreads, HANDLE* sequenceEvents, HANDLE* doneEvents, bool& exitThreads);
//--------------------------------------------------------------------------------------
// RunReplayerThreads - Tell each replayer thread to run a frame and wait for
// them to complete
//--------------------------------------------------------------------------------------
void RunReplayerThreads(unsigned int numThreads, unsigned int startThread, HANDLE* doneEvents, HANDLE* sequenceEvents);
#else // defined(WIN32)
//--------------------------------------------------------------------------------------
// AutoResetEvent - Class used as a synchronization event for replayer threads,
// automatically set to an unsignaled state after being waited on
//--------------------------------------------------------------------------------------
class AutoResetEvent
{
public:
AutoResetEvent();
void Signal();
void Wait();
private:
bool m_signaled;
std::mutex m_mutex;
std::condition_variable m_condtionVariable;
};
//--------------------------------------------------------------------------------------
// ThreadRunner - Class and derived classes used to manage the running of threads
//--------------------------------------------------------------------------------------
class ThreadRunner : public std::enable_shared_from_this<ThreadRunner>
{
public:
using ThreadStartFunc = void (*)(unsigned int, std::shared_ptr<ThreadRunner>);
ThreadRunner(unsigned int threadId, RunFrameFunc runFrameFunc);
virtual void CreateThread(ThreadStartFunc threadStartFunc, unsigned int threadId);
virtual void Init()
{
}
virtual void Release()
{
}
void RunThread();
protected:
void SignalMainThreadAndWait() const;
unsigned int GetThreadId() const;
private:
virtual void PreRunThread()
{
}
virtual void PostRunThread()
{
}
unsigned int m_threadId;
RunFrameFunc m_runFrameFunc;
};
class BasicThreadRunner : public ThreadRunner
{
public:
BasicThreadRunner(unsigned int threadId, RunFrameFunc runFrameFunc, ResetFrameFunc resetFrameFunc);
private:
virtual void PostRunThread() override;
ResetFrameFunc m_resetFrameFunc;
};
//--------------------------------------------------------------------------------------
// ThreadRunnerArray
//--------------------------------------------------------------------------------------
using ThreadRunnerArray = std::array<std::shared_ptr<ThreadRunner>, NUM_REPLAYER_THREADS>;
//--------------------------------------------------------------------------------------
// CreateThreadEvents - Create Windows events used to synchronize the threads
//--------------------------------------------------------------------------------------
bool CreateThreadEvents(EventsArray& events);
//--------------------------------------------------------------------------------------
// CreateReplayerThreads - Create and start the replayer threads
//--------------------------------------------------------------------------------------
bool CreateReplayerThreads(ThreadRunnerArray& threadRunners);
//--------------------------------------------------------------------------------------
// ReleaseReplayerThreads - Release all of the replayer threads
//--------------------------------------------------------------------------------------
void ReleaseReplayerThreads(unsigned int numThreads);
//--------------------------------------------------------------------------------------
// ExitReplayerThreads - Exit all of the replayer threads
//--------------------------------------------------------------------------------------
void ExitReplayerThreads(unsigned int numThreads);
//--------------------------------------------------------------------------------------
// RunReplayerThreads - Tell each replayer thread to run a frame and wait for
// them to complete
//--------------------------------------------------------------------------------------
void RunReplayerThreads();
#endif // defined(WIN32)