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:
Jake.Stine 2010-12-19 08:31:35 +00:00
parent 375a766cf1
commit 4ebbe65c4f
15 changed files with 74 additions and 130 deletions

View File

@ -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
}
/*

View File

@ -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;

View File

@ -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);
}

View File

@ -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))
{

View File

@ -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)))
{

View File

@ -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)
{

View File

@ -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)

View File

@ -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;
}

View File

@ -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))
{
}

View File

@ -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;

View File

@ -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;

View File

@ -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 */

View File

@ -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);

View File

@ -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);
/*

View File

@ -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