Skip to content

Commit 827a6dc

Browse files
author
nitrocaster
committed
Fix primary/secondary thread synchronization.
1 parent a1461ce commit 827a6dc

File tree

2 files changed

+24
-44
lines changed

2 files changed

+24
-44
lines changed

src/xrEngine/device.cpp

Lines changed: 17 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -121,30 +121,24 @@ void CRenderDevice::End(void)
121121
#endif
122122
#endif // !DEDICATED_SERVER
123123
}
124-
static volatile u32 mt_Thread_marker = 0x12345678;
125-
void mt_Thread(void* ptr)
124+
125+
void CRenderDevice::SecondaryThreadProc(void *context)
126126
{
127+
auto &device = *static_cast<CRenderDevice*>(context);
127128
while (true)
128129
{
129-
// waiting for Device permission to execute
130-
Device.mt_csEnter.Enter();
131-
if (Device.mt_bMustExit)
130+
device.syncProcessFrame.Wait();
131+
if (device.mt_bMustExit)
132132
{
133-
Device.mt_bMustExit = FALSE; // Important!!!
134-
Device.mt_csEnter.Leave(); // Important!!!
133+
device.mt_bMustExit = FALSE;
134+
device.syncThreadExit.Set();
135135
return;
136136
}
137-
mt_Thread_marker = Device.dwFrame;
138-
for (u32 pit = 0; pit < Device.seqParallel.size(); pit++)
139-
Device.seqParallel[pit]();
140-
Device.seqParallel.clear_not_free();
141-
Device.seqFrameMT.Process(rp_Frame);
142-
// now we give control to device - signals that we are ended our work
143-
Device.mt_csEnter.Leave();
144-
// waits for device signal to continue - to start again
145-
Device.mt_csLeave.Enter();
146-
// returns sync signal to device
147-
Device.mt_csLeave.Leave();
137+
for (u32 pit = 0; pit < device.seqParallel.size(); pit++)
138+
device.seqParallel[pit]();
139+
device.seqParallel.clear_not_free();
140+
device.seqFrameMT.Process(rp_Frame);
141+
device.syncFrameDone.Set();
148142
}
149143
}
150144

@@ -242,11 +236,7 @@ void CRenderDevice::on_idle()
242236
mFullTransform_saved = mFullTransform;
243237
mView_saved = mView;
244238
mProject_saved = mProject;
245-
// *** Resume threads
246-
// Capture end point - thread must run only ONE cycle
247-
// Release start point - allow thread to run
248-
mt_csLeave.Enter(); // prevent secondary thread to proceed with the next frame
249-
mt_csEnter.Leave(); // allow secondary thread to do its work
239+
syncProcessFrame.Set(); // allow secondary thread to do its job
250240
Sleep(0);
251241

252242
#ifndef DEDICATED_SERVER
@@ -266,19 +256,7 @@ void CRenderDevice::on_idle()
266256
renderTotalReal.FrameEnd();
267257
stats.RenderTotal.accum = renderTotalReal.accum;
268258
#endif // #ifndef DEDICATED_SERVER
269-
// *** Suspend threads
270-
// Capture startup point
271-
// Release end point - allow thread to wait for startup point
272-
mt_csEnter.Enter(); // wait for secondary thread to finish its work
273-
mt_csLeave.Leave(); // allow secondary thread to wait for its work in the next frame
274-
// Ensure, that second thread gets chance to execute anyway
275-
if (dwFrame!=mt_Thread_marker)
276-
{
277-
for (u32 pit = 0; pit < Device.seqParallel.size(); pit++)
278-
Device.seqParallel[pit]();
279-
Device.seqParallel.clear_not_free();
280-
seqFrameMT.Process(rp_Frame);
281-
}
259+
syncFrameDone.Wait(); // wait until secondary thread finish its job
282260
#ifdef DEDICATED_SERVER
283261
u32 FrameEndTime = TimerGlobal.GetElapsed_ms();
284262
u32 FrameTime = (FrameEndTime - FrameStartTime);
@@ -338,17 +316,17 @@ void CRenderDevice::Run()
338316
Timer_MM_Delta = time_system - time_local;
339317
}
340318
// Start all threads
341-
mt_csEnter.Enter();
342319
mt_bMustExit = FALSE;
343-
thread_spawn(mt_Thread, "X-RAY Secondary thread", 0, 0);
320+
thread_spawn(SecondaryThreadProc, "X-RAY Secondary thread", 0, this);
344321
// Message cycle
345322
seqAppStart.Process(rp_AppStart);
346323
Render->ClearTarget();
347324
message_loop();
348325
seqAppEnd.Process(rp_AppEnd);
349326
// Stop Balance-Thread
350327
mt_bMustExit = TRUE;
351-
mt_csEnter.Leave();
328+
syncProcessFrame.Set();
329+
syncThreadExit.Wait();
352330
while (mt_bMustExit)
353331
Sleep(0);
354332
}

src/xrEngine/device.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
#include "xrCore/ftimer.h"
1515
#include "stats.h"
16+
#include "xrCore/Threading/Event.hpp"
1617

1718
#define VIEWPORT_NEAR 0.2f
1819

@@ -203,7 +204,9 @@ class ENGINE_API CRenderDevice : public CRenderDeviceBase
203204

204205
void Pause(BOOL bOn, BOOL bTimer, BOOL bSound, LPCSTR reason);
205206
BOOL Paused();
206-
207+
private:
208+
static void SecondaryThreadProc(void *context);
209+
public:
207210
// Scene control
208211
void PreCache(u32 amount, bool b_draw_loadscreen, bool b_wait_user_input);
209212
BOOL Begin();
@@ -242,10 +245,9 @@ class ENGINE_API CRenderDevice : public CRenderDeviceBase
242245
VERIFY(Timer.time_factor() == TimerGlobal.time_factor());
243246
return (Timer.time_factor());
244247
}
245-
246-
// Multi-threading
247-
Lock mt_csEnter;
248-
Lock mt_csLeave;
248+
private:
249+
Event syncProcessFrame, syncFrameDone, syncThreadExit;
250+
public:
249251
volatile BOOL mt_bMustExit;
250252

251253
ICF void remove_from_seq_parallel(const fastdelegate::FastDelegate0<>& delegate)

0 commit comments

Comments
 (0)