2022-07-08 00:55:01 +02:00
|
|
|
|
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
|
|
|
|
|
//
|
2022-09-09 19:47:31 +02:00
|
|
|
|
// Purpose: Thread tools
|
2022-07-08 00:55:01 +02:00
|
|
|
|
//
|
|
|
|
|
// $Workfile: $
|
|
|
|
|
// $NoKeywords: $
|
|
|
|
|
//===========================================================================//
|
|
|
|
|
|
2023-04-06 23:50:48 +02:00
|
|
|
|
#include "tier0/threadtools.h"
|
2022-07-08 00:55:01 +02:00
|
|
|
|
|
2023-07-02 11:38:36 +02:00
|
|
|
|
#define INIT_SEM_COUNT 0
|
|
|
|
|
#define MAX_SEM_COUNT 1
|
2022-07-08 00:55:01 +02:00
|
|
|
|
|
2023-07-02 11:38:36 +02:00
|
|
|
|
int CThreadFastMutex::Lock(void)
|
2022-07-08 00:55:01 +02:00
|
|
|
|
{
|
2023-07-02 11:38:36 +02:00
|
|
|
|
DWORD threadId = GetCurrentThreadId();
|
|
|
|
|
LONG result = ThreadInterlockedCompareExchange((volatile LONG*)&m_lAddend, 0, 1);
|
2022-07-08 00:55:01 +02:00
|
|
|
|
|
2023-07-02 11:38:36 +02:00
|
|
|
|
if (result)
|
|
|
|
|
{
|
|
|
|
|
if (m_nOwnerID == threadId)
|
|
|
|
|
{
|
|
|
|
|
result = m_nDepth + 1;
|
|
|
|
|
m_nDepth = result;
|
2022-07-08 00:55:01 +02:00
|
|
|
|
|
2023-07-02 11:38:36 +02:00
|
|
|
|
return result;
|
|
|
|
|
}
|
2022-08-18 12:00:01 +02:00
|
|
|
|
|
2023-07-02 11:38:36 +02:00
|
|
|
|
LONG cycle = 1;
|
|
|
|
|
LONG64 delay;
|
2022-08-18 12:00:01 +02:00
|
|
|
|
|
2023-07-02 11:38:36 +02:00
|
|
|
|
while (true)
|
|
|
|
|
{
|
|
|
|
|
delay = (10 * cycle);
|
|
|
|
|
if (delay)
|
|
|
|
|
{
|
|
|
|
|
do
|
|
|
|
|
{
|
|
|
|
|
ThreadPause();
|
|
|
|
|
--delay;
|
|
|
|
|
} while (delay);
|
|
|
|
|
}
|
2022-08-21 19:35:06 +02:00
|
|
|
|
|
2023-07-02 11:38:36 +02:00
|
|
|
|
result = ThreadInterlockedCompareExchange((volatile LONG*)&m_lAddend, 0, 1);
|
|
|
|
|
|
|
|
|
|
if (result)
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
if (++cycle > 5)
|
|
|
|
|
{
|
|
|
|
|
if (_InterlockedIncrement((volatile LONG*)&m_lAddend) != 1)
|
|
|
|
|
{
|
|
|
|
|
if (!m_hSemaphore)
|
|
|
|
|
{
|
|
|
|
|
HANDLE hSemaphore = CreateSemaphoreA(
|
|
|
|
|
NULL, INIT_SEM_COUNT, MAX_SEM_COUNT, NULL);
|
|
|
|
|
|
|
|
|
|
if (ThreadInterlockedCompareExchange64(
|
|
|
|
|
(volatile LONG64*)&m_hSemaphore, NULL, (LONG64)hSemaphore))
|
|
|
|
|
CloseHandle(hSemaphore);
|
|
|
|
|
}
|
|
|
|
|
WaitForSingleObject(m_hSemaphore, INFINITE);
|
|
|
|
|
}
|
|
|
|
|
m_nOwnerID = threadId;
|
|
|
|
|
m_nDepth = 1;
|
|
|
|
|
|
|
|
|
|
return m_nDepth;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_nDepth = 1;
|
|
|
|
|
m_nOwnerID = threadId;
|
|
|
|
|
|
|
|
|
|
return result;
|
2022-09-18 19:01:37 +02:00
|
|
|
|
}
|
|
|
|
|
|
2023-07-02 11:38:36 +02:00
|
|
|
|
int CThreadFastMutex::Unlock()
|
2022-08-18 12:00:01 +02:00
|
|
|
|
{
|
2023-07-02 11:38:36 +02:00
|
|
|
|
LONG result; // eax
|
|
|
|
|
HANDLE SemaphoreA; // rcx
|
|
|
|
|
|
|
|
|
|
result = m_nDepth - 1;
|
|
|
|
|
m_nDepth = result;
|
|
|
|
|
|
|
|
|
|
if (!result)
|
|
|
|
|
{
|
|
|
|
|
m_nOwnerID = 0;
|
|
|
|
|
result = _InterlockedExchangeAdd((volatile LONG*)&m_lAddend, 0xFFFFFFFF);
|
|
|
|
|
|
|
|
|
|
if (result != 1)
|
|
|
|
|
{
|
|
|
|
|
if (!m_hSemaphore)
|
|
|
|
|
{
|
|
|
|
|
SemaphoreA = CreateSemaphoreA(NULL, INIT_SEM_COUNT, MAX_SEM_COUNT, NULL);
|
|
|
|
|
|
|
|
|
|
if (ThreadInterlockedAssignIf64(
|
|
|
|
|
(volatile LONG64*)&m_hSemaphore, NULL, (LONG64)SemaphoreA))
|
|
|
|
|
CloseHandle(SemaphoreA);
|
|
|
|
|
}
|
|
|
|
|
return ReleaseSemaphore(m_hSemaphore, 1, NULL);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|