-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathEngineThread.cpp
More file actions
127 lines (111 loc) · 2.61 KB
/
Copy pathEngineThread.cpp
File metadata and controls
127 lines (111 loc) · 2.61 KB
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
#include "EngineThread.h"
#include "Logger.h"
#include <deque>
namespace sh::core
{
SH_CORE_API EngineThread::EngineThread() :
mutex(),
beginTasks(), endTasks(),
bStop(false),
bSleep(false),
bRun(false)
{
thr = std::thread{ [&] { Update(); } };
}
SH_CORE_API void EngineThread::Run()
{
if (!bRun)
{
bRun = true;
cv.notify_one();
}
}
SH_CORE_API auto EngineThread::GetThread() -> std::thread&
{
return thr;
}
void EngineThread::Update()
{
// Run전에는 Sleep
{
std::unique_lock<std::mutex> lock{ mutex };
while(!bRun)
cv.wait(lock);
}
while (!bStop.load(std::memory_order::memory_order_relaxed)) // 원자적이기만 하면 되므로 relaxed
{
static double mean = 0;
static std::deque<uint64_t> us;
//auto start = std::chrono::high_resolution_clock::now();
std::unique_lock<std::mutex> lock{ mutex };
taskMutex.lock();
while (!beginTasks.empty())
{
beginTasks.front()();
beginTasks.pop();
}
taskMutex.unlock();
for (auto& task : tasks)
task();
taskMutex.lock();
while (!endTasks.empty())
{
endTasks.front()();
endTasks.pop();
}
taskMutex.unlock();
//auto end = std::chrono::high_resolution_clock::now();
//if (us.size() < 100)
// us.push_back(std::chrono::duration_cast<std::chrono::microseconds>(end - start).count());
//else
// us.pop_front();
//uint64_t sum = 0;
//for (auto t : us)
// sum += t;
//mean = sum / 100.0;
//SH_INFO_FORMAT("mean {}us", mean);
bSleep = true;
while (bSleep)
cv.wait(lock); // wait이 되는 순간 lock은 풀린다. <~ 동기화에 활용
}
}
SH_CORE_API void EngineThread::AddTask(const std::function<void()>& task)
{
tasks.push_back(task);
}
SH_CORE_API void EngineThread::AddBeginTaskFromOtherThread(const std::function<void()>& task)
{
taskMutex.lock();
beginTasks.push(task);
taskMutex.unlock();
}
SH_CORE_API void EngineThread::AddEndTaskFromOtherThread(const std::function<void()>& task)
{
taskMutex.lock();
endTasks.push(task);
taskMutex.unlock();
}
SH_CORE_API void EngineThread::Stop()
{
bStop.store(true, std::memory_order::memory_order_relaxed); // 원자적이기만 하면 되므로 relaxed
mutex.lock();
bSleep = false;
mutex.unlock();
cv.notify_one();
}
SH_CORE_API bool EngineThread::Awake()
{
if (mutex.try_lock()) // 잠금을 획득 할 수 있다 = 스레드가 자고 있다.
{
bSleep = false;
mutex.unlock();
cv.notify_one();
return true;
}
return false;
}
SH_CORE_API auto EngineThread::GetThreadID() const -> std::thread::id
{
return thr.get_id();
}
}//namespace