Skip to content

Commit f4770b4

Browse files
removed mailbox cond_variable and mutex
1 parent 2cd0c6b commit f4770b4

File tree

1 file changed

+43
-46
lines changed

1 file changed

+43
-46
lines changed

ZEngine/ZEngine/Engine.cpp

Lines changed: 43 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <Managers/AssetManager.h>
77
#include <Windows/GameWindow.h>
88
#include <chrono>
9+
#include <new>
910

1011
#ifdef __APPLE__
1112
#include <mach/mach.h>
@@ -16,17 +17,21 @@ using namespace std::chrono_literals;
1617

1718
namespace ZEngine
1819
{
19-
static std::atomic_bool s_request_terminate = false;
20-
static EngineContextPtr g_engine_ctx = nullptr;
21-
static Applications::GameApplicationPtr g_app = nullptr;
22-
static Applications::AppRenderPipelinePtr g_appRenderPipeline = nullptr;
23-
static std::thread g_render_thread = {};
24-
25-
static const uint8_t k_mailbox_buffer_size = 3;
26-
static std::atomic_int g_write_idx = 0;
27-
static std::atomic_int g_pending_idx = -1;
28-
static std::mutex g_mailbox_mut;
29-
static std::condition_variable g_mailbox_ready_cv = {};
20+
21+
struct alignas(std::hardware_destructive_interference_size) PaddedAtomicInt
22+
{
23+
std::atomic_uint32_t value;
24+
};
25+
26+
static std::atomic_bool s_request_terminate = false;
27+
static EngineContextPtr g_engine_ctx = nullptr;
28+
static Applications::GameApplicationPtr g_app = nullptr;
29+
static Applications::AppRenderPipelinePtr g_appRenderPipeline = nullptr;
30+
static std::thread g_render_thread = {};
31+
32+
static PaddedAtomicInt g_head{0};
33+
static PaddedAtomicInt g_tail{0};
34+
static constexpr uint8_t k_mailbox_buffer_size = 3;
3035
static Applications::RenderPayload g_mailbox_payloads[k_mailbox_buffer_size] = {};
3136

3237
void Engine::Initialize(ZEngine::Core::Memory::ArenaAllocator* arena, Windows::WindowConfigurationPtr window_cfg_ptr, Applications::GameApplicationPtr app)
@@ -73,7 +78,7 @@ namespace ZEngine
7378

7479
void Engine::Dispose()
7580
{
76-
s_request_terminate = false;
81+
s_request_terminate.store(false, std::memory_order_release);
7782
Managers::AssetManager::Shutdown();
7883
g_engine_ctx->Device->Dispose();
7984

@@ -82,11 +87,7 @@ namespace ZEngine
8287

8388
bool Engine::OnEngineClosed(Event::EngineClosedEvent& event)
8489
{
85-
{
86-
std::lock_guard l(g_mailbox_mut);
87-
s_request_terminate.store(true, std::memory_order_release);
88-
g_mailbox_ready_cv.notify_all();
89-
}
90+
s_request_terminate.store(true, std::memory_order_release);
9091
return true;
9192
}
9293

@@ -125,18 +126,17 @@ namespace ZEngine
125126

126127
g_app->Update(dt);
127128

128-
{
129-
std::unique_lock l(g_mailbox_mut);
130-
g_mailbox_ready_cv.wait(l, [&] { return s_request_terminate.load(std::memory_order_acquire) || g_pending_idx.load(std::memory_order_acquire) == -1; });
129+
uint32_t head = g_head.value.load(std::memory_order_relaxed);
131130

132-
if (s_request_terminate.load(std::memory_order_acquire))
133-
{
134-
break;
135-
}
131+
uint32_t next = (head + 1) % k_mailbox_buffer_size;
136132

137-
int next_payload_idx = g_write_idx.load(std::memory_order_relaxed);
133+
uint32_t tail = g_tail.value.load(std::memory_order_acquire);
138134

139-
auto& r_payload = g_mailbox_payloads[next_payload_idx];
135+
// Buffer full, drop frame (non-blocking)
136+
if (next == tail)
137+
continue;
138+
{
139+
auto& r_payload = g_mailbox_payloads[head];
140140
r_payload.UIOverlay.DrawDataIndex = 0;
141141
r_payload.RenderUIOverlay = false;
142142

@@ -152,10 +152,8 @@ namespace ZEngine
152152

153153
g_app->PrepareScene(r_payload);
154154

155-
g_pending_idx.store(next_payload_idx, std::memory_order_release);
156-
g_write_idx.store((g_write_idx + 1) % k_mailbox_buffer_size, std::memory_order_relaxed);
155+
g_head.value.store(next, std::memory_order_release);
157156
}
158-
g_mailbox_ready_cv.notify_one();
159157
}
160158
}
161159

@@ -174,23 +172,23 @@ namespace ZEngine
174172
#endif
175173
while (true)
176174
{
177-
int idx = -1;
175+
if (s_request_terminate.load(std::memory_order_acquire))
178176
{
179-
std::unique_lock l(g_mailbox_mut);
180-
g_mailbox_ready_cv.wait(l, [&] { return s_request_terminate.load(std::memory_order_acquire) || g_pending_idx.load(std::memory_order_acquire) != -1; });
177+
break;
178+
}
181179

182-
if (s_request_terminate.load(std::memory_order_acquire))
183-
{
184-
break;
185-
}
180+
uint32_t tail = g_tail.value.load(std::memory_order_relaxed);
186181

187-
idx = g_pending_idx.load(std::memory_order_acquire);
188-
g_pending_idx.store(-1, std::memory_order_release);
189-
}
182+
uint32_t head = g_head.value.load(std::memory_order_acquire);
190183

191-
ZENGINE_VALIDATE_ASSERT(idx > -1, "Invalid payload index")
184+
// Buffer empty
185+
if (tail == head)
186+
{
187+
std::this_thread::sleep_for(std::chrono::microseconds(50));
188+
continue;
189+
}
192190

193-
Applications::RenderPayload& r_payload = g_mailbox_payloads[idx];
191+
Applications::RenderPayload& r_payload = g_mailbox_payloads[tail];
194192

195193
auto pipeline = g_app->RenderPipeline;
196194

@@ -208,7 +206,9 @@ namespace ZEngine
208206
}
209207
pipeline->EndFrame();
210208

211-
g_mailbox_ready_cv.notify_one();
209+
uint32_t next = (tail + 1) % k_mailbox_buffer_size;
210+
211+
g_tail.value.store(next, std::memory_order_release);
212212
}
213213
}
214214

@@ -218,9 +218,6 @@ namespace ZEngine
218218
g_render_thread = std::thread(Engine::RenderThreadRun);
219219
MainThreadRun();
220220

221-
if (s_request_terminate.load(std::memory_order_acquire))
222-
{
223-
Deinitialize();
224-
}
221+
Deinitialize();
225222
}
226223
} // namespace ZEngine

0 commit comments

Comments
 (0)