Skip to content

Commit 1ea1436

Browse files
committed
move magic spin lock elsewhere
1 parent 2f828e2 commit 1ea1436

File tree

2 files changed

+20
-23
lines changed

2 files changed

+20
-23
lines changed

src/materialsystem/shaderapidx9/shaderapidx8.cpp

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4032,7 +4032,8 @@ void CShaderAPIDx8::UpdateFrameSyncQuery( int queryIndex, bool bIssue )
40324032
displayRate = 1.0f / m_PresentParameters.FullScreen_RefreshRateInHz;
40334033
}
40344034
displayRate /= 2.0f;
4035-
int iLoops = 0;
4035+
int tries = 0;
4036+
int backoff = 1;
40364037
do
40374038
{
40384039
hr = m_pFrameSyncQueryObject[queryIndex]->GetData(&bFinished, sizeof(bFinished), D3DGETDATA_FLUSH);
@@ -4045,22 +4046,12 @@ void CShaderAPIDx8::UpdateFrameSyncQuery( int queryIndex, bool bIssue )
40454046
// don't wait more than display rate for these
40464047
if (dt > displayRate)
40474048
break;
4048-
// Avoid burning a full core while waiting for the query. Spinning can actually harm performance
4049-
// because there might be driver threads that are trying to do work that end up starved, and the
4050-
// power drawn by the CPU may take away from the power available to the integrated graphics chip.
4051-
iLoops++;
4052-
if (iLoops % 3 == 0)
4053-
{
4054-
ThreadSleep(1);
4055-
}
4056-
else if (iLoops % 2 == 0)
4057-
{
4058-
ThreadSleep();
4059-
}
4060-
else
4061-
{
4049+
for (int yields = 0; yields < backoff; yields++) {
40624050
ThreadPause();
4051+
tries++;
40634052
}
4053+
constexpr int kMaxBackoff = 64;
4054+
backoff = min(kMaxBackoff, backoff << 1);
40644055
}
40654056
while (true);
40664057
m_bQueryIssued[queryIndex] = false;

src/vstdlib/jobthread.cpp

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -550,26 +550,33 @@ class CJobThread : public CWorkerThread
550550
case Queue:
551551
{
552552
bool bTookJob = false;
553-
int spins = 0;
553+
int tries = 0;
554+
int backoff = 1;
555+
constexpr int iSpinCount = 1000;
554556
do
555557
{
556558
// TODO: checking is fine for now, even if we spin since threads only use either queue for receiving their jobs
557559
if (waitResult != WAIT_OBJECT_0 + DIRECT_QUEUE || !m_DirectQueue.Pop(&pJob))
558560
{
559561
if (waitResult != WAIT_OBJECT_0 + SHARED_QUEUE || !m_SharedQueue.Pop(&pJob))
560562
{
561-
// Nothing to process, keep spinning
562-
++spins;
563-
if (spins >= 5000)
563+
if (tries > iSpinCount)
564564
{
565565
break;
566566
}
567-
ThreadPause();
567+
// Nothing to process, keep spinning
568+
for (int yields = 0; yields < backoff; yields++) {
569+
ThreadPause();
570+
tries++;
571+
}
572+
constexpr int kMaxBackoff = 64;
573+
backoff = min(kMaxBackoff, backoff << 1);
568574
continue;
569575
}
570576
}
571577
// If we took a job, reset the spins to reprioritize checking jobs rather than calls.
572-
spins = 0;
578+
tries = 0;
579+
backoff = 1;
573580
if (!bTookJob)
574581
{
575582
m_IdleEvent.Reset();
@@ -1201,7 +1208,7 @@ bool CThreadPool::Start( const ThreadPoolStartParams_t &startParams, const char
12011208
{
12021209
if (startParams.bIOThreads)
12031210
{
1204-
iLoad = CJobThread::Call;
1211+
iLoad = CJobThread::Burst;
12051212
}
12061213
else
12071214
{
@@ -1212,7 +1219,6 @@ bool CThreadPool::Start( const ThreadPoolStartParams_t &startParams, const char
12121219
{
12131220
iLoad = CJobThread::Burst;
12141221
}
1215-
iLoad = CJobThread::Burst;
12161222
m_Threads[iThread] = new CJobThread( this, iThread, false, iLoad );
12171223
m_IdleEvents[iThread] = &m_Threads[iThread]->GetIdleEvent();
12181224
m_Threads[iThread]->SetName( CFmtStr( "%s%d", pszName, iThread ) );

0 commit comments

Comments
 (0)