mirror of https://github.com/PCSX2/pcsx2.git
w32pthreads: maintenance work; applied patches inspired by the VLC guys that make the code a little more sensible where pointer types are concerned. Removed some obsolete ancient compiler crap regarding interlocked exchanges.
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@4100 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
375a766cf1
commit
4ebbe65c4f
|
@ -45,6 +45,9 @@
|
|||
|
||||
#include <windows.h>
|
||||
#include <intrin.h>
|
||||
#include <winsock.h>
|
||||
#include <malloc.h>
|
||||
#include <limits.h>
|
||||
|
||||
/*
|
||||
* In case windows.h doesn't define it (e.g. WinCE perhaps)
|
||||
|
@ -54,23 +57,10 @@ typedef VOID (APIENTRY *PAPCFUNC)(DWORD dwParam);
|
|||
#endif
|
||||
|
||||
/*
|
||||
* note: ETIMEDOUT is correctly defined in winsock.h
|
||||
*/
|
||||
#include <winsock.h>
|
||||
|
||||
/*
|
||||
* In case ETIMEDOUT hasn't been defined above somehow.
|
||||
* In case ETIMEDOUT hasn't been defined in winsock.h somehow.
|
||||
*/
|
||||
#ifndef ETIMEDOUT
|
||||
# define ETIMEDOUT 10060 /* This is the value in winsock.h. */
|
||||
#endif
|
||||
|
||||
#if !defined(malloc)
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
|
||||
#if !defined(INT_MAX)
|
||||
#include <limits.h>
|
||||
# define ETIMEDOUT 10060 /* This is the value in winsock.h. */
|
||||
#endif
|
||||
|
||||
/* use local include files during development */
|
||||
|
@ -83,14 +73,6 @@ typedef VOID (APIENTRY *PAPCFUNC)(DWORD dwParam);
|
|||
#define INLINE
|
||||
#endif
|
||||
|
||||
#if defined (__MINGW32__) || (_MSC_VER >= 1300)
|
||||
#define PTW32_INTERLOCKED_LONG long
|
||||
#define PTW32_INTERLOCKED_LPLONG long*
|
||||
#else
|
||||
#define PTW32_INTERLOCKED_LONG PVOID
|
||||
#define PTW32_INTERLOCKED_LPLONG PVOID*
|
||||
#endif
|
||||
|
||||
#if defined(__MINGW32__)
|
||||
#include <stdint.h>
|
||||
#elif defined(__BORLANDC__)
|
||||
|
@ -338,9 +320,9 @@ struct ptw32_mcs_node_t_
|
|||
{
|
||||
struct ptw32_mcs_node_t_ **lock; /* ptr to tail of queue */
|
||||
struct ptw32_mcs_node_t_ *next; /* ptr to successor in queue */
|
||||
LONG readyFlag; /* set after lock is released by
|
||||
HANDLE readyFlag; /* set after lock is released by
|
||||
predecessor */
|
||||
LONG nextFlag; /* set after 'next' ptr is set by
|
||||
HANDLE nextFlag; /* set after 'next' ptr is set by
|
||||
successor */
|
||||
};
|
||||
|
||||
|
@ -668,18 +650,32 @@ extern "C"
|
|||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Defaults. Could be overridden when building the inlined version of the dll.
|
||||
* See ptw32_InterlockedCompareExchange.c
|
||||
*/
|
||||
// Default to inlining the pthreads versions... (air)
|
||||
#ifndef PTW32_INTERLOCKED_COMPARE_EXCHANGE
|
||||
#define PTW32_INTERLOCKED_COMPARE_EXCHANGE _InterlockedCompareExchange
|
||||
static INLINE void* _InterlockedExchangePointer( void* volatile* target, void* value )
|
||||
{
|
||||
#ifdef _M_AMD64 // high-level atomic ops, please leave these 64 bit checks in place.
|
||||
return (void*)_InterlockedExchange64( (LONG_PTR*)target, value );
|
||||
#else
|
||||
return (void*)_InterlockedExchange( (LONG_PTR*)target, (LONG_PTR)value );
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef PTW32_INTERLOCKED_EXCHANGE
|
||||
#define PTW32_INTERLOCKED_EXCHANGE _InterlockedExchange
|
||||
static INLINE void* _InterlockedCompareExchangePointer( void* volatile* target, void* value, void* comparand )
|
||||
{
|
||||
#ifdef _M_AMD64 // high-level atomic ops, please leave these 64 bit checks in place.
|
||||
return (void*)_InterlockedCompareExchange64( (LONG_PTR*)target, value, comparand );
|
||||
#else
|
||||
return (void*)_InterlockedCompareExchange( (LONG_PTR*)target, (LONG_PTR)value, (LONG_PTR)comparand );
|
||||
#endif
|
||||
}
|
||||
|
||||
static INLINE void* _InterlockedExchangeAddPointer( void* volatile* target, void* value )
|
||||
{
|
||||
#ifdef _M_AMD64 // high-level atomic ops, please leave these 64 bit checks in place.
|
||||
return (void*)_InterlockedExchangeAdd64( (LONG_PTR*)target, (LONG_PTR)value );
|
||||
#else
|
||||
return (void*)_InterlockedExchangeAdd( (LONG_PTR*)target, (LONG_PTR)value );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
|
|
|
@ -306,8 +306,9 @@ enum {
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRUCT_TIMESPEC
|
||||
#if !defined( HAVE_STRUCT_TIMESPEC ) && !defined( _TIMESPEC_DEFINED )
|
||||
#define HAVE_STRUCT_TIMESPEC 1
|
||||
#define _TIMESPEC_DEFINED 1
|
||||
struct timespec {
|
||||
long tv_sec;
|
||||
long tv_nsec;
|
||||
|
|
|
@ -84,13 +84,8 @@ pthread_barrier_wait (pthread_barrier_t * barrier)
|
|||
*/
|
||||
if (0 == result)
|
||||
{
|
||||
result = ((PTW32_INTERLOCKED_LONG) step ==
|
||||
PTW32_INTERLOCKED_COMPARE_EXCHANGE ((PTW32_INTERLOCKED_LPLONG)
|
||||
& (b->iStep),
|
||||
(PTW32_INTERLOCKED_LONG)
|
||||
(1L - step),
|
||||
(PTW32_INTERLOCKED_LONG)
|
||||
step) ?
|
||||
result = ( step ==
|
||||
_InterlockedCompareExchange ( &(b->iStep), (1L - step), step) ?
|
||||
PTHREAD_BARRIER_SERIAL_THREAD : 0);
|
||||
}
|
||||
|
||||
|
|
|
@ -68,13 +68,9 @@ pthread_mutex_lock (pthread_mutex_t * mutex)
|
|||
|
||||
if (mx->kind == PTHREAD_MUTEX_NORMAL)
|
||||
{
|
||||
if ((LONG) PTW32_INTERLOCKED_EXCHANGE(
|
||||
(LPLONG) &mx->lock_idx,
|
||||
(LONG) 1) != 0)
|
||||
if (_InterlockedExchange( &mx->lock_idx, 1) != 0)
|
||||
{
|
||||
while ((LONG) PTW32_INTERLOCKED_EXCHANGE(
|
||||
(LPLONG) &mx->lock_idx,
|
||||
(LONG) -1) != 0)
|
||||
while (_InterlockedExchange( &mx->lock_idx, -1) != 0)
|
||||
{
|
||||
if (WAIT_OBJECT_0 != WaitForSingleObject (mx->event, INFINITE))
|
||||
{
|
||||
|
@ -88,10 +84,7 @@ pthread_mutex_lock (pthread_mutex_t * mutex)
|
|||
{
|
||||
pthread_t self = pthread_self();
|
||||
|
||||
if ((PTW32_INTERLOCKED_LONG) PTW32_INTERLOCKED_COMPARE_EXCHANGE(
|
||||
(PTW32_INTERLOCKED_LPLONG) &mx->lock_idx,
|
||||
(PTW32_INTERLOCKED_LONG) 1,
|
||||
(PTW32_INTERLOCKED_LONG) 0) == 0)
|
||||
if (_InterlockedCompareExchange(&mx->lock_idx, 1, 0) == 0)
|
||||
{
|
||||
mx->recursive_count = 1;
|
||||
mx->ownerThread = self;
|
||||
|
@ -111,9 +104,7 @@ pthread_mutex_lock (pthread_mutex_t * mutex)
|
|||
}
|
||||
else
|
||||
{
|
||||
while ((LONG) PTW32_INTERLOCKED_EXCHANGE(
|
||||
(LPLONG) &mx->lock_idx,
|
||||
(LONG) -1) != 0)
|
||||
while (_InterlockedExchange(&mx->lock_idx, -1) != 0)
|
||||
{
|
||||
if (WAIT_OBJECT_0 != WaitForSingleObject (mx->event, INFINITE))
|
||||
{
|
||||
|
|
|
@ -133,13 +133,9 @@ pthread_mutex_timedlock (pthread_mutex_t * mutex,
|
|||
|
||||
if (mx->kind == PTHREAD_MUTEX_NORMAL)
|
||||
{
|
||||
if ((LONG) PTW32_INTERLOCKED_EXCHANGE(
|
||||
(LPLONG) &mx->lock_idx,
|
||||
(LONG) 1) != 0)
|
||||
if (_InterlockedExchange(&mx->lock_idx, 1) != 0)
|
||||
{
|
||||
while ((LONG) PTW32_INTERLOCKED_EXCHANGE(
|
||||
(LPLONG) &mx->lock_idx,
|
||||
(LONG) -1) != 0)
|
||||
while (_InterlockedExchange(&mx->lock_idx, -1) != 0)
|
||||
{
|
||||
if (0 != (result = ptw32_timed_eventwait (mx->event, abstime)))
|
||||
{
|
||||
|
@ -152,10 +148,7 @@ pthread_mutex_timedlock (pthread_mutex_t * mutex,
|
|||
{
|
||||
pthread_t self = pthread_self();
|
||||
|
||||
if ((PTW32_INTERLOCKED_LONG) PTW32_INTERLOCKED_COMPARE_EXCHANGE(
|
||||
(PTW32_INTERLOCKED_LPLONG) &mx->lock_idx,
|
||||
(PTW32_INTERLOCKED_LONG) 1,
|
||||
(PTW32_INTERLOCKED_LONG) 0) == 0)
|
||||
if (_InterlockedCompareExchange(&mx->lock_idx, 1, 0) == 0)
|
||||
{
|
||||
mx->recursive_count = 1;
|
||||
mx->ownerThread = self;
|
||||
|
@ -175,9 +168,7 @@ pthread_mutex_timedlock (pthread_mutex_t * mutex,
|
|||
}
|
||||
else
|
||||
{
|
||||
while ((LONG) PTW32_INTERLOCKED_EXCHANGE(
|
||||
(LPLONG) &mx->lock_idx,
|
||||
(LONG) -1) != 0)
|
||||
while (_InterlockedExchange(&mx->lock_idx, -1) != 0)
|
||||
{
|
||||
if (0 != (result = ptw32_timed_eventwait (mx->event, abstime)))
|
||||
{
|
||||
|
|
|
@ -63,10 +63,7 @@ pthread_mutex_trylock (pthread_mutex_t * mutex)
|
|||
|
||||
mx = *mutex;
|
||||
|
||||
if (0 == (LONG) PTW32_INTERLOCKED_COMPARE_EXCHANGE (
|
||||
(PTW32_INTERLOCKED_LPLONG) &mx->lock_idx,
|
||||
(PTW32_INTERLOCKED_LONG) 1,
|
||||
(PTW32_INTERLOCKED_LONG) 0))
|
||||
if (0 == (LONG) _InterlockedCompareExchange(&mx->lock_idx, 1, 0))
|
||||
{
|
||||
if (mx->kind != PTHREAD_MUTEX_NORMAL)
|
||||
{
|
||||
|
|
|
@ -60,8 +60,7 @@ pthread_mutex_unlock (pthread_mutex_t * mutex)
|
|||
{
|
||||
LONG idx;
|
||||
|
||||
idx = (LONG) PTW32_INTERLOCKED_EXCHANGE ((LPLONG) &mx->lock_idx,
|
||||
(LONG) 0);
|
||||
idx = _InterlockedExchange (&mx->lock_idx, 0);
|
||||
if (idx != 0)
|
||||
{
|
||||
if (idx < 0)
|
||||
|
@ -92,8 +91,7 @@ pthread_mutex_unlock (pthread_mutex_t * mutex)
|
|||
{
|
||||
mx->ownerThread.p = NULL;
|
||||
|
||||
if ((LONG) PTW32_INTERLOCKED_EXCHANGE ((LPLONG) &mx->lock_idx,
|
||||
(LONG) 0) < 0)
|
||||
if (_InterlockedExchange (&mx->lock_idx, 0) < 0)
|
||||
{
|
||||
/* Someone may be waiting on that mutex */
|
||||
if (SetEvent (mx->event) == 0)
|
||||
|
|
|
@ -54,13 +54,8 @@ pthread_spin_destroy (pthread_spinlock_t * lock)
|
|||
{
|
||||
result = pthread_mutex_destroy (&(s->u.mutex));
|
||||
}
|
||||
else if ((PTW32_INTERLOCKED_LONG) PTW32_SPIN_UNLOCKED !=
|
||||
PTW32_INTERLOCKED_COMPARE_EXCHANGE ((PTW32_INTERLOCKED_LPLONG)
|
||||
& (s->interlock),
|
||||
(PTW32_INTERLOCKED_LONG)
|
||||
PTW32_OBJECT_INVALID,
|
||||
(PTW32_INTERLOCKED_LONG)
|
||||
PTW32_SPIN_UNLOCKED))
|
||||
else if (PTW32_SPIN_UNLOCKED !=
|
||||
_InterlockedCompareExchange(&(s->interlock), PTW32_OBJECT_INVALID, PTW32_SPIN_UNLOCKED))
|
||||
{
|
||||
result = EINVAL;
|
||||
}
|
||||
|
|
|
@ -59,13 +59,8 @@ pthread_spin_lock (pthread_spinlock_t * lock)
|
|||
|
||||
s = *lock;
|
||||
|
||||
while ((PTW32_INTERLOCKED_LONG) PTW32_SPIN_LOCKED ==
|
||||
PTW32_INTERLOCKED_COMPARE_EXCHANGE ((PTW32_INTERLOCKED_LPLONG) &
|
||||
(s->interlock),
|
||||
(PTW32_INTERLOCKED_LONG)
|
||||
PTW32_SPIN_LOCKED,
|
||||
(PTW32_INTERLOCKED_LONG)
|
||||
PTW32_SPIN_UNLOCKED))
|
||||
while (PTW32_SPIN_LOCKED ==
|
||||
_InterlockedCompareExchange(&(s->interlock), PTW32_SPIN_LOCKED, PTW32_SPIN_UNLOCKED))
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -60,12 +60,7 @@ pthread_spin_trylock (pthread_spinlock_t * lock)
|
|||
s = *lock;
|
||||
|
||||
switch ((long)
|
||||
PTW32_INTERLOCKED_COMPARE_EXCHANGE ((PTW32_INTERLOCKED_LPLONG) &
|
||||
(s->interlock),
|
||||
(PTW32_INTERLOCKED_LONG)
|
||||
PTW32_SPIN_LOCKED,
|
||||
(PTW32_INTERLOCKED_LONG)
|
||||
PTW32_SPIN_UNLOCKED))
|
||||
_InterlockedCompareExchange(&(s->interlock), PTW32_SPIN_LOCKED, PTW32_SPIN_UNLOCKED))
|
||||
{
|
||||
case PTW32_SPIN_UNLOCKED:
|
||||
return 0;
|
||||
|
|
|
@ -55,12 +55,7 @@ pthread_spin_unlock (pthread_spinlock_t * lock)
|
|||
}
|
||||
|
||||
switch ((long)
|
||||
PTW32_INTERLOCKED_COMPARE_EXCHANGE ((PTW32_INTERLOCKED_LPLONG) &
|
||||
(s->interlock),
|
||||
(PTW32_INTERLOCKED_LONG)
|
||||
PTW32_SPIN_UNLOCKED,
|
||||
(PTW32_INTERLOCKED_LONG)
|
||||
PTW32_SPIN_LOCKED))
|
||||
_InterlockedCompareExchange (&(s->interlock), PTW32_SPIN_UNLOCKED, PTW32_SPIN_LOCKED))
|
||||
{
|
||||
case PTW32_SPIN_LOCKED:
|
||||
return 0;
|
||||
|
|
|
@ -98,13 +98,11 @@
|
|||
* set flag to -1 otherwise. Note that -1 cannot be a valid handle value.
|
||||
*/
|
||||
INLINE void
|
||||
ptw32_mcs_flag_set (LONG * flag)
|
||||
ptw32_mcs_flag_set (HANDLE * flag)
|
||||
{
|
||||
HANDLE e = (HANDLE)PTW32_INTERLOCKED_COMPARE_EXCHANGE(
|
||||
(PTW32_INTERLOCKED_LPLONG)flag,
|
||||
(PTW32_INTERLOCKED_LONG)-1,
|
||||
(PTW32_INTERLOCKED_LONG)0);
|
||||
if ((HANDLE)0 != e)
|
||||
HANDLE e = (HANDLE)_InterlockedCompareExchangePointer(flag, (HANDLE)-1, (HANDLE)0);
|
||||
|
||||
if (e)
|
||||
{
|
||||
/* another thread has already stored an event handle in the flag */
|
||||
SetEvent(e);
|
||||
|
@ -118,24 +116,21 @@ ptw32_mcs_flag_set (LONG * flag)
|
|||
* set, and proceed without creating an event otherwise.
|
||||
*/
|
||||
INLINE void
|
||||
ptw32_mcs_flag_wait (LONG * flag)
|
||||
ptw32_mcs_flag_wait (HANDLE * flag)
|
||||
{
|
||||
if (0 == InterlockedExchangeAdd((LPLONG)flag, 0)) /* MBR fence */
|
||||
if (0 == _InterlockedExchangeAddPointer(flag, NULL)) /* MBR fence */
|
||||
{
|
||||
/* the flag is not set. create event. */
|
||||
|
||||
HANDLE e = CreateEvent(NULL, PTW32_FALSE, PTW32_FALSE, NULL);
|
||||
|
||||
if (0 == PTW32_INTERLOCKED_COMPARE_EXCHANGE(
|
||||
(PTW32_INTERLOCKED_LPLONG)flag,
|
||||
(PTW32_INTERLOCKED_LONG)e,
|
||||
(PTW32_INTERLOCKED_LONG)0))
|
||||
{
|
||||
/* stored handle in the flag. wait on it now. */
|
||||
WaitForSingleObject(e, INFINITE);
|
||||
}
|
||||
if (0 == _InterlockedCompareExchangePointer(flag, e, 0))
|
||||
{
|
||||
/* stored handle in the flag. wait on it now. */
|
||||
WaitForSingleObject(e, INFINITE);
|
||||
}
|
||||
|
||||
CloseHandle(e);
|
||||
CloseHandle(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -158,8 +153,7 @@ ptw32_mcs_lock_acquire (ptw32_mcs_lock_t * lock, ptw32_mcs_local_node_t * node)
|
|||
node->next = 0; /* initially, no successor */
|
||||
|
||||
/* queue for the lock */
|
||||
pred = (ptw32_mcs_local_node_t *)PTW32_INTERLOCKED_EXCHANGE((LPLONG)lock,
|
||||
(LONG)node);
|
||||
pred = (ptw32_mcs_local_node_t *)_InterlockedExchangePointer(lock, node);
|
||||
|
||||
if (0 != pred)
|
||||
{
|
||||
|
@ -190,9 +184,7 @@ ptw32_mcs_lock_release (ptw32_mcs_local_node_t * node)
|
|||
/* no known successor */
|
||||
|
||||
if (node == (ptw32_mcs_local_node_t *)
|
||||
PTW32_INTERLOCKED_COMPARE_EXCHANGE((PTW32_INTERLOCKED_LPLONG)lock,
|
||||
(PTW32_INTERLOCKED_LONG)0,
|
||||
(PTW32_INTERLOCKED_LONG)node))
|
||||
_InterlockedCompareExchangePointer(lock, 0, node))
|
||||
{
|
||||
/* no successor, lock is free now */
|
||||
return;
|
||||
|
@ -201,7 +193,7 @@ ptw32_mcs_lock_release (ptw32_mcs_local_node_t * node)
|
|||
/* wait for successor */
|
||||
ptw32_mcs_flag_wait(&node->nextFlag);
|
||||
next = (ptw32_mcs_local_node_t *)
|
||||
InterlockedExchangeAdd((LPLONG)&node->next, 0); /* MBR fence */
|
||||
_InterlockedExchangeAddPointer(&node->next, NULL); /* MBR fence */
|
||||
}
|
||||
|
||||
/* pass the lock */
|
||||
|
|
|
@ -73,7 +73,7 @@ ptw32_cancel_self (void)
|
|||
}
|
||||
|
||||
static void CALLBACK
|
||||
ptw32_cancel_callback (DWORD unused)
|
||||
ptw32_cancel_callback (DWORD_PTR unused)
|
||||
{
|
||||
ptw32_throw (PTW32_EPS_CANCEL);
|
||||
|
||||
|
|
|
@ -94,6 +94,9 @@ ptw32_processTerminate (void)
|
|||
tp = tpNext;
|
||||
}
|
||||
|
||||
ptw32_threadReuseTop = PTW32_THREAD_REUSE_EMPTY;
|
||||
ptw32_threadReuseBottom = PTW32_THREAD_REUSE_EMPTY;
|
||||
|
||||
LeaveCriticalSection (&ptw32_thread_reuse_lock);
|
||||
|
||||
/*
|
||||
|
|
|
@ -72,15 +72,15 @@ ptw32_throw (DWORD exception)
|
|||
* explicit thread exit here after cleaning up POSIX
|
||||
* residue (i.e. cleanup handlers, POSIX thread handle etc).
|
||||
*/
|
||||
unsigned exitCode = 0;
|
||||
void* exitCode = 0;
|
||||
|
||||
switch (exception)
|
||||
{
|
||||
case PTW32_EPS_CANCEL:
|
||||
exitCode = (unsigned) PTHREAD_CANCELED;
|
||||
exitCode = PTHREAD_CANCELED;
|
||||
break;
|
||||
case PTW32_EPS_EXIT:
|
||||
exitCode = (unsigned) sp->exitStatus;;
|
||||
exitCode = sp->exitStatus;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -91,7 +91,7 @@ ptw32_throw (DWORD exception)
|
|||
#endif
|
||||
|
||||
#if ! defined (__MINGW32__) || defined (__MSVCRT__) || defined (__DMC__)
|
||||
_endthreadex (exitCode);
|
||||
_endthreadex ((unsigned)exitCode);
|
||||
#else
|
||||
_endthread ();
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue