mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-08 19:00:57 +00:00
HPL1: fix physics library for windows build
This commit is contained in:
parent
c051f506fc
commit
0a33c0ba44
@ -44,20 +44,6 @@ void TraceFuntionName(const char *name) {
|
||||
#define TRACE_FUNTION(name)
|
||||
#endif // _DEBUG
|
||||
|
||||
#ifndef _NEWTON_STATIC_LIB
|
||||
#ifdef __MINGW32__
|
||||
int main(int argc, char *argv[]) {
|
||||
return 0;
|
||||
}
|
||||
#endif // _MINGW32__
|
||||
|
||||
#ifdef _MSC_VER
|
||||
BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
#endif // _NEWTON_STATIC_LIB
|
||||
|
||||
//#define SAVE_COLLISION
|
||||
#ifdef SAVE_COLLISION
|
||||
|
||||
|
@ -26,25 +26,7 @@
|
||||
#define NEWTON_MAJOR_VERSION 2
|
||||
#define NEWTON_MINOR_VERSION 36
|
||||
|
||||
|
||||
#ifdef _NEWTON_STATIC_LIB
|
||||
#define NEWTON_API
|
||||
#else
|
||||
#ifdef _NEWTON_BUILD_DLL
|
||||
#ifdef _WIN32
|
||||
#define NEWTON_API __declspec (dllexport)
|
||||
#else
|
||||
#define NEWTON_API __attribute__ ((visibility("default")))
|
||||
#endif
|
||||
#else
|
||||
#ifdef _WIN32
|
||||
#define NEWTON_API __declspec (dllimport)
|
||||
#else
|
||||
#define NEWTON_API
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define NEWTON_API
|
||||
|
||||
#ifdef __USE_DOUBLE_PRECISION__
|
||||
#define dFloat double
|
||||
|
@ -33,11 +33,7 @@ void dgApi dgExpandTraceMessage(const char *fmt, ...)
|
||||
va_start(v_args, fmt);
|
||||
vsprintf(text, fmt, v_args);
|
||||
va_end(v_args);
|
||||
printf ("%s\n", text);
|
||||
|
||||
#ifdef _WIN32
|
||||
OutputDebugStringA(text);
|
||||
#else
|
||||
printf ("%s\n", text);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
@ -23,119 +23,23 @@
|
||||
#include "dgTypes.h"
|
||||
#include "dgThreads.h"
|
||||
|
||||
static inline void dgThreadYield()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
Sleep(0);
|
||||
#else
|
||||
#ifndef TARGET_OS_IPHONE
|
||||
sched_yield();
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void dgSpinLock(dgInt32 *spin)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
while (InterlockedExchange((long*) spin, 1))
|
||||
{
|
||||
Sleep(0);
|
||||
}
|
||||
#elif defined (__APPLE__)
|
||||
#ifndef TARGET_OS_IPHONE
|
||||
while( ! OSAtomicCompareAndSwap32(0, 1, (int32_t*) spin) )
|
||||
{
|
||||
sched_yield();
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
while(! __sync_bool_compare_and_swap((int32_t*)spin, 0, 1) )
|
||||
{
|
||||
sched_yield();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void dgSpinUnlock(dgInt32 *spin)
|
||||
{
|
||||
*spin = 0;
|
||||
}
|
||||
|
||||
static inline void dgInterlockedIncrement(dgInt32* Addend)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
InterlockedIncrement((long*) Addend);
|
||||
#elif defined (__APPLE__)
|
||||
OSAtomicAdd32 (1, (int32_t*)Addend);
|
||||
#else
|
||||
__sync_fetch_and_add ((int32_t*)Addend, 1 );
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void dgInterlockedDecrement(dgInt32* Addend)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
InterlockedDecrement((long*) Addend);
|
||||
#elif defined (__APPLE__)
|
||||
OSAtomicAdd32 (-1, (int32_t*)Addend);
|
||||
#else
|
||||
__sync_fetch_and_sub ((int32_t*)Addend, 1 );
|
||||
#endif
|
||||
}
|
||||
|
||||
dgThreads::dgThreads()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
SYSTEM_INFO sysInfo;
|
||||
GetSystemInfo(&sysInfo);
|
||||
m_numberOfCPUCores = dgInt32(sysInfo.dwNumberOfProcessors);
|
||||
|
||||
m_numOfThreads = 0;
|
||||
m_exit = NULL;
|
||||
m_workToDo = NULL;
|
||||
m_emptySlot = NULL;
|
||||
|
||||
m_topIndex = 0;
|
||||
m_bottomIndex = 0;
|
||||
m_workInProgress = 0;
|
||||
m_globalSpinLock = 0;
|
||||
|
||||
memset(m_threadhandles, 0, sizeof(m_threadhandles));
|
||||
#elif defined (__APPLE__)
|
||||
int mib[2];
|
||||
size_t len;
|
||||
int procesorcount;
|
||||
|
||||
mib[0] = CTL_HW;
|
||||
mib[1] = HW_NCPU;
|
||||
len = sizeof (procesorcount);
|
||||
procesorcount = 0;
|
||||
m_numberOfCPUCores = sysctl(mib, 2, &procesorcount, &len, NULL, 0);
|
||||
m_numberOfCPUCores = procesorcount;
|
||||
m_numberOfCPUCores = 0;
|
||||
|
||||
m_numOfThreads = 0;
|
||||
m_exit = false;
|
||||
|
||||
memset (m_threadhandles, 0, sizeof (m_threadhandles));
|
||||
|
||||
m_topIndex = 0;
|
||||
m_bottomIndex = 0;
|
||||
m_workInProgress = 0;
|
||||
m_globalSpinLock = 0;
|
||||
m_workToDoSpinLock = 0;
|
||||
#else
|
||||
m_numberOfCPUCores = sysconf(_SC_NPROCESSORS_ONLN);
|
||||
|
||||
m_numOfThreads = 0;
|
||||
m_exit = false;
|
||||
|
||||
memset (m_threadhandles, 0, sizeof (m_threadhandles));
|
||||
m_topIndex = 0;
|
||||
m_bottomIndex = 0;
|
||||
m_workInProgress = 0;
|
||||
m_globalSpinLock = 0;
|
||||
m_workToDoSpinLock = 0;
|
||||
#endif
|
||||
|
||||
m_getPerformanceCount = NULL;
|
||||
for (dgInt32 i = 0; i < DG_MAXIMUN_THREADS; i++)
|
||||
@ -148,10 +52,7 @@ dgThreads::dgThreads()
|
||||
|
||||
dgThreads::~dgThreads()
|
||||
{
|
||||
if (m_numOfThreads)
|
||||
{
|
||||
DestroydgThreads();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
dgInt32 dgThreads::GetThreadCount() const
|
||||
@ -161,10 +62,7 @@ dgInt32 dgThreads::GetThreadCount() const
|
||||
|
||||
void dgThreads::ClearTimers()
|
||||
{
|
||||
for (dgInt32 i = 0; i < m_numOfThreads; i++)
|
||||
{
|
||||
m_localData[i].m_ticks = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void dgThreads::SetPerfomanceCounter(OnGetPerformanceCountCallback callback)
|
||||
@ -187,171 +85,23 @@ dgUnsigned32 dgThreads::GetPerfomanceTicks(dgUnsigned32 threadIndex) const
|
||||
|
||||
void dgThreads::CreateThreaded(dgInt32 threads)
|
||||
{
|
||||
if (m_numOfThreads)
|
||||
{
|
||||
DestroydgThreads();
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
if ((threads > 1) && (m_numberOfCPUCores > 1))
|
||||
{
|
||||
m_numOfThreads = GetMin(threads, m_numberOfCPUCores);
|
||||
|
||||
m_emptySlot = CreateSemaphoreA(NULL, DG_MAXQUEUE, DG_MAXQUEUE, NULL);
|
||||
m_workToDo = CreateSemaphoreA(NULL, 0, DG_MAXQUEUE, NULL);
|
||||
m_exit = CreateEventA(NULL, TRUE, FALSE, NULL);
|
||||
|
||||
InitializeCriticalSection(&m_criticalSection);
|
||||
|
||||
m_topIndex = 0;
|
||||
m_bottomIndex = 0;
|
||||
m_workInProgress = 0;
|
||||
for (dgInt32 i = 0; i < m_numOfThreads; i++)
|
||||
{
|
||||
m_threadhandles[i] = (HANDLE) _beginthreadex(NULL, 0, ThreadExecute,
|
||||
&m_localData[i], 0, NULL);
|
||||
}
|
||||
}
|
||||
#else
|
||||
if ((threads > 1) && (m_numberOfCPUCores > 1))
|
||||
{
|
||||
#ifdef TARGET_OS_IPHONE
|
||||
m_numOfThreads = 0;
|
||||
#else
|
||||
m_numOfThreads = (threads<m_numberOfCPUCores ? threads : m_numberOfCPUCores);
|
||||
#endif
|
||||
|
||||
m_emptySlot = DG_MAXQUEUE;
|
||||
m_workToDo = 0;
|
||||
m_workToDoSpinLock = 0;
|
||||
m_exit = false;
|
||||
m_criticalSection = 0;
|
||||
|
||||
m_topIndex = 0;
|
||||
m_bottomIndex = 0;
|
||||
m_workInProgress = 0;
|
||||
|
||||
#ifndef TARGET_OS_IPHONE
|
||||
for(dgInt32 i=0; i < m_numOfThreads; i++)
|
||||
{
|
||||
pthread_create( &m_threadhandles[i], NULL, ThreadExecute, &m_localData[i]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void dgThreads::DestroydgThreads()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
_ASSERTE(m_workInProgress == 0);
|
||||
|
||||
while (m_workInProgress > 0)
|
||||
{
|
||||
Sleep(10);
|
||||
}
|
||||
SetEvent(m_exit);
|
||||
DeleteCriticalSection(&m_criticalSection);
|
||||
WaitForMultipleObjects(DWORD(m_numOfThreads), m_threadhandles, TRUE,
|
||||
INFINITE);
|
||||
|
||||
for (dgInt32 i = 0; i < m_numOfThreads; i++)
|
||||
{
|
||||
CloseHandle(m_threadhandles[i]);
|
||||
}
|
||||
|
||||
CloseHandle(m_exit);
|
||||
CloseHandle(m_emptySlot);
|
||||
CloseHandle(m_workToDo);
|
||||
|
||||
m_exit = NULL;
|
||||
m_emptySlot = NULL;
|
||||
m_workToDo = NULL;
|
||||
memset(&m_criticalSection, 0, sizeof(CRITICAL_SECTION));
|
||||
for (dgInt32 i = 0; i < m_numOfThreads; i++)
|
||||
{
|
||||
m_threadhandles[i] = NULL;
|
||||
}
|
||||
|
||||
m_topIndex = 0;
|
||||
m_bottomIndex = 0;
|
||||
m_workInProgress = 0;
|
||||
m_numOfThreads = 0;
|
||||
#else
|
||||
while(m_workInProgress > 0)
|
||||
{
|
||||
usleep(100000);
|
||||
}
|
||||
dgSpinLock( &m_criticalSection );
|
||||
m_exit = true;
|
||||
m_workToDo = DG_MAXQUEUE+1;
|
||||
dgSpinUnlock( &m_criticalSection );
|
||||
|
||||
#ifndef TARGET_OS_IPHONE
|
||||
for(dgInt32 i=0; i<m_numOfThreads; i++ )
|
||||
{
|
||||
pthread_join( m_threadhandles[i], NULL );
|
||||
}
|
||||
#endif
|
||||
|
||||
m_exit = false;
|
||||
m_emptySlot = 0;
|
||||
m_workToDo = 0;
|
||||
m_workToDoSpinLock = 0;
|
||||
|
||||
m_topIndex = 0;
|
||||
m_bottomIndex = 0;
|
||||
m_workInProgress = 0;
|
||||
m_numOfThreads = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
//Queues up another to work
|
||||
dgInt32 dgThreads::SubmitJob(dgWorkerThread* const job)
|
||||
{
|
||||
if (!m_numOfThreads)
|
||||
{
|
||||
_ASSERTE(job->m_threadIndex != -1);
|
||||
job->ThreadExecute();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
#ifdef _WIN32
|
||||
dgInterlockedIncrement(&m_workInProgress);
|
||||
if (WaitForSingleObject(m_emptySlot, INFINITE) != WAIT_OBJECT_0)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
EnterCriticalSection(&m_criticalSection);
|
||||
m_queue[m_topIndex] = job;
|
||||
m_topIndex = (m_topIndex + 1) % DG_MAXQUEUE;
|
||||
ReleaseSemaphore(m_workToDo, 1, NULL);
|
||||
LeaveCriticalSection(&m_criticalSection);
|
||||
#else
|
||||
dgInterlockedIncrement(&m_workInProgress);
|
||||
while ( m_emptySlot == 0 )
|
||||
{
|
||||
dgThreadYield();
|
||||
}
|
||||
dgInterlockedDecrement( &m_emptySlot );
|
||||
|
||||
dgSpinLock(&m_criticalSection);
|
||||
m_queue[m_topIndex] = job;
|
||||
m_topIndex = (m_topIndex + 1) % DG_MAXQUEUE;
|
||||
dgInterlockedIncrement( &m_workToDo );
|
||||
dgSpinUnlock( &m_criticalSection );
|
||||
#endif
|
||||
}
|
||||
return 1;
|
||||
_ASSERTE(job->m_threadIndex != -1);
|
||||
job->ThreadExecute();
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
dgUnsigned32 _stdcall dgThreads::ThreadExecute(void *param)
|
||||
#else
|
||||
void* dgThreads::ThreadExecute(void *param)
|
||||
#endif
|
||||
{
|
||||
dgLocadData& data = *(dgLocadData*) param;
|
||||
data.m_manager->DoWork(data.m_threadIndex);
|
||||
@ -360,52 +110,8 @@ void* dgThreads::ThreadExecute(void *param)
|
||||
|
||||
dgInt32 dgThreads::GetWork(dgWorkerThread** job)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
HANDLE hWaitHandles[2];
|
||||
hWaitHandles[0] = m_workToDo;
|
||||
hWaitHandles[1] = m_exit;
|
||||
|
||||
if ((WaitForMultipleObjects(2, hWaitHandles, FALSE, INFINITE) - WAIT_OBJECT_0)
|
||||
== 1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
EnterCriticalSection(&m_criticalSection);
|
||||
*job = m_queue[m_bottomIndex];
|
||||
m_bottomIndex = (m_bottomIndex + 1) % DG_MAXQUEUE;
|
||||
ReleaseSemaphore(m_emptySlot, 1, NULL);
|
||||
LeaveCriticalSection(&m_criticalSection);
|
||||
#else
|
||||
for (;;)
|
||||
{
|
||||
while ( m_workToDo == 0 )
|
||||
{
|
||||
dgThreadYield();
|
||||
}
|
||||
dgSpinLock( &m_workToDoSpinLock );
|
||||
if ( m_workToDo > 0 )
|
||||
{
|
||||
break;
|
||||
}
|
||||
dgSpinUnlock( &m_workToDoSpinLock );
|
||||
}
|
||||
dgInterlockedDecrement( &m_workToDo );
|
||||
dgSpinUnlock( &m_workToDoSpinLock );
|
||||
if ( m_exit )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
dgSpinLock( &m_criticalSection );
|
||||
dgWorkerThread* cWorker = m_queue[m_bottomIndex];
|
||||
*job = cWorker;
|
||||
|
||||
m_bottomIndex = (m_bottomIndex+1) % (DG_MAXQUEUE);
|
||||
dgInterlockedIncrement( &m_emptySlot );
|
||||
dgSpinUnlock( &m_criticalSection );
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -413,49 +119,12 @@ void dgThreads::DoWork(dgInt32 mythreadIndex)
|
||||
{
|
||||
dgWorkerThread* job;
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifndef __USE_DOUBLE_PRECISION__
|
||||
dgUnsigned32 controlWorld;
|
||||
controlWorld = dgControlFP (0xffffffff, 0);
|
||||
dgControlFP(_PC_53, _MCW_PC);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (!m_getPerformanceCount)
|
||||
{
|
||||
while (GetWork(&job))
|
||||
{
|
||||
job->ThreadExecute();
|
||||
dgInterlockedDecrement(&m_workInProgress);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (GetWork(&job))
|
||||
{
|
||||
dgUnsigned32 ticks = m_getPerformanceCount();
|
||||
|
||||
job->ThreadExecute();
|
||||
dgInterlockedDecrement(&m_workInProgress);
|
||||
|
||||
m_localData[mythreadIndex].m_ticks += (m_getPerformanceCount() - ticks);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifndef __USE_DOUBLE_PRECISION__
|
||||
dgControlFP(controlWorld, _MCW_PC);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void dgThreads::SynchronizationBarrier()
|
||||
{
|
||||
while (m_workInProgress)
|
||||
{
|
||||
dgThreadYield();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void dgThreads::CalculateChunkSizes(dgInt32 elements,
|
||||
@ -483,7 +152,6 @@ void dgThreads::CalculateChunkSizes(dgInt32 elements,
|
||||
void dgThreads::dgGetLock() const
|
||||
{
|
||||
_ASSERTE(sizeof (dgInt32) == sizeof (long));
|
||||
dgSpinLock(&m_globalSpinLock);
|
||||
|
||||
//spinLock( &m_globalSpinLock );
|
||||
// linux and mac may need to yeald time
|
||||
@ -500,7 +168,6 @@ void dgThreads::dgReleaseLock() const
|
||||
void dgThreads::dgGetIndirectLock(dgInt32* lockVar)
|
||||
{
|
||||
_ASSERTE(sizeof (dgInt32) == sizeof (long));
|
||||
dgSpinLock(lockVar);
|
||||
}
|
||||
|
||||
void dgThreads::dgReleaseIndirectLock(dgInt32* lockVar)
|
||||
|
@ -71,11 +71,8 @@ private:
|
||||
void DoWork(dgInt32 threadIndex);
|
||||
dgInt32 GetWork(dgWorkerThread** cWork);
|
||||
|
||||
#ifdef _WIN32
|
||||
static dgUnsigned32 _stdcall ThreadExecute(void *Param);
|
||||
#else
|
||||
|
||||
static void* ThreadExecute(void *Param);
|
||||
#endif
|
||||
|
||||
dgInt32 m_numOfThreads;
|
||||
dgInt32 m_numberOfCPUCores;
|
||||
@ -84,22 +81,13 @@ private:
|
||||
dgInt32 m_workInProgress;
|
||||
mutable dgInt32 m_globalSpinLock;
|
||||
|
||||
#ifdef _WIN32
|
||||
HANDLE m_exit;
|
||||
HANDLE m_workToDo;
|
||||
HANDLE m_emptySlot;
|
||||
CRITICAL_SECTION m_criticalSection;
|
||||
dgWorkerThread* m_queue[DG_MAXQUEUE];
|
||||
HANDLE m_threadhandles[DG_MAXIMUN_THREADS];
|
||||
#else
|
||||
bool m_exit;
|
||||
dgInt32 m_emptySlot;
|
||||
dgInt32 m_workToDo;
|
||||
dgInt32 m_criticalSection;
|
||||
dgInt32 m_workToDoSpinLock;
|
||||
dgWorkerThread* m_queue[DG_MAXQUEUE];
|
||||
pthread_t m_threadhandles[DG_MAXIMUN_THREADS];
|
||||
#endif
|
||||
//pthread_t m_threadhandles[DG_MAXIMUN_THREADS];
|
||||
|
||||
OnGetPerformanceCountCallback m_getPerformanceCount;
|
||||
dgLocadData m_localData[DG_MAXIMUN_THREADS];
|
||||
|
@ -64,7 +64,6 @@
|
||||
#endif
|
||||
|
||||
#include <crtdbg.h>
|
||||
#include <windows.h>
|
||||
|
||||
// #include <mmsystem.h>
|
||||
|
||||
@ -729,15 +728,7 @@ typedef dgUnsigned32(dgApi *OnGetPerformanceCountCallback)();
|
||||
dgCpuClass dgApi dgGetCpuType();
|
||||
|
||||
inline dgInt32 dgAtomicAdd(dgInt32 *const addend, dgInt32 amount) {
|
||||
#ifdef _WIN32
|
||||
return InterlockedExchangeAdd((long *)addend, long(amount));
|
||||
#elif defined(__APPLE__)
|
||||
dgInt32 count = OSAtomicAdd32(amount, (int32_t *)addend);
|
||||
|
||||
return count - (*addend);
|
||||
#else
|
||||
return __sync_fetch_and_add((int32_t *)addend, amount);
|
||||
#endif
|
||||
return *addend += amount;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user