15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * implement.h
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Definitions that don't need to be public.
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Keeps all the internals out of pthread.h
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * --------------------------------------------------------------------------
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *      Pthreads-win32 - POSIX Threads Library for Win32
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *      Copyright(C) 1998 John E. Bossom
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *      Copyright(C) 1999,2005 Pthreads-win32 contributors
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *      Contact Email: Ross.Johnson@homemail.com.au
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *      The current list of contributors is contained
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *      in the file CONTRIBUTORS included with the source
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *      code distribution. The list can also be seen at the
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *      following World Wide Web location:
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *      http://sources.redhat.com/pthreads-win32/contributors.html
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *      This library is free software; you can redistribute it and/or
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *      modify it under the terms of the GNU Lesser General Public
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *      License as published by the Free Software Foundation; either
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *      version 2 of the License, or (at your option) any later version.
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *      This library is distributed in the hope that it will be useful,
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *      but WITHOUT ANY WARRANTY; without even the implied warranty of
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *      Lesser General Public License for more details.
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *      You should have received a copy of the GNU Lesser General Public
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *      License along with this library in the file COPYING.LIB;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *      if not, write to the Free Software Foundation, Inc.,
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(_IMPLEMENT_H)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define _IMPLEMENT_H
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(_WIN32_WINNT)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define _WIN32_WINNT 0x0400
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <windows.h>
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * In case windows.h doesn't define it (e.g. WinCE perhaps)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(WINCE)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef VOID (APIENTRY *PAPCFUNC)(DWORD dwParam);
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * note: ETIMEDOUT is correctly defined in winsock.h
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <winsock.h>
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * In case ETIMEDOUT hasn't been defined above somehow.
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(ETIMEDOUT)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#  define ETIMEDOUT 10060	/* This is the value in winsock.h. */
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(malloc)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <malloc.h>
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(__CLEANUP_C)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# include <setjmp.h>
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(INT_MAX)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <limits.h>
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* use local include files during development */
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "semaphore.h"
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sched.h"
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(HAVE_C_INLINE) || defined(__cplusplus)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define INLINE inline
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define INLINE
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(_MSC_VER) && _MSC_VER < 1300
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * MSVC 6 does not use the "volatile" qualifier
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PTW32_INTERLOCKED_VOLATILE
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PTW32_INTERLOCKED_VOLATILE volatile
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PTW32_INTERLOCKED_LONG long
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PTW32_INTERLOCKED_SIZE size_t
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PTW32_INTERLOCKED_PVOID PVOID
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PTW32_INTERLOCKED_LONGPTR PTW32_INTERLOCKED_VOLATILE long*
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PTW32_INTERLOCKED_SIZEPTR PTW32_INTERLOCKED_VOLATILE size_t*
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PTW32_INTERLOCKED_PVOID_PTR PTW32_INTERLOCKED_VOLATILE PVOID*
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(__MINGW64__) || defined(__MINGW32__)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#  include <stdint.h>
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(__BORLANDC__)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#  define int64_t ULONGLONG
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#  define int64_t _int64
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#  if defined(_MSC_VER) && _MSC_VER < 1300
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     typedef long intptr_t;
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#  endif
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Don't allow the linker to optimize away autostatic.obj in static builds.
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(PTW32_STATIC_LIB)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ptw32_autostatic_anchor(void);
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   if defined(__MINGW64__) || defined(__MINGW32__)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    __attribute__((unused, used))
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   endif
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void (*local_autostatic_anchor)(void) = ptw32_autostatic_anchor;
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef enum
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /*
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   * This enumeration represents the state of the thread;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   * The thread is still "alive" if the numeric value of the
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   * state is greater or equal "PThreadStateRunning".
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   */
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PThreadStateInitial = 0,	/* Thread not running                   */
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PThreadStateRunning,		/* Thread alive & kicking               */
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PThreadStateSuspended,	/* Thread alive but suspended           */
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PThreadStateCancelPending,	/* Thread alive but                     */
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                /* has cancelation pending.             */
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PThreadStateCanceling,	/* Thread alive but is                  */
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                /* in the process of terminating        */
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                /* due to a cancellation request        */
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PThreadStateExiting,		/* Thread alive but exiting             */
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                /* due to an exception                  */
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PThreadStateLast,             /* All handlers have been run and now   */
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                /* final cleanup can be done.           */
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PThreadStateReuse             /* In reuse pool.                       */
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PThreadState;
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct ptw32_mcs_node_t_     ptw32_mcs_local_node_t;
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct ptw32_mcs_node_t_*    ptw32_mcs_lock_t;
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct ptw32_robust_node_t_  ptw32_robust_node_t;
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct ptw32_thread_t_       ptw32_thread_t;
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ptw32_thread_t_
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned __int64 seqNumber;	/* Process-unique thread sequence number */
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HANDLE threadH;		/* Win32 thread handle - POSIX thread is invalid if threadH == 0 */
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pthread_t ptHandle;		/* This thread's permanent pthread_t handle */
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ptw32_thread_t * prevReuse;	/* Links threads on reuse stack */
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  volatile PThreadState state;
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ptw32_mcs_lock_t threadLock;	/* Used for serialised access to public thread state */
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ptw32_mcs_lock_t stateLock;	/* Used for async-cancel safety */
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HANDLE cancelEvent;
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void *exitStatus;
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void *parms;
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void *keys;
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void *nextAssoc;
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(__CLEANUP_C)
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  jmp_buf start_mark;		/* Jump buffer follows void* so should be aligned */
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif				/* __CLEANUP_C */
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(HAVE_SIGSET_T)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sigset_t sigmask;
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif				/* HAVE_SIGSET_T */
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ptw32_mcs_lock_t
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              robustMxListLock; /* robustMxList lock */
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ptw32_robust_node_t*
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  robustMxList; /* List of currenty held robust mutexes */
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int ptErrno;
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int detachState;
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int sched_priority;		/* As set, not as currently is */
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int cancelState;
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int cancelType;
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int implicit:1;
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DWORD thread;			/* Win32 thread ID */
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(_UWIN)
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DWORD dummy[5];
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t align;			/* Force alignment if this struct is packed */
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Special value to mark attribute objects as valid.
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PTW32_ATTR_VALID ((unsigned long) 0xC4C0FFEE)
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct pthread_attr_t_
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned long valid;
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void *stackaddr;
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t stacksize;
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int detachstate;
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct sched_param param;
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int inheritsched;
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int contentionscope;
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(HAVE_SIGSET_T)
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sigset_t sigmask;
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif				/* HAVE_SIGSET_T */
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ====================
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ====================
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Semaphores, Mutexes and Condition Variables
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ====================
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ====================
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct sem_t_
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int value;
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pthread_mutex_t lock;
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HANDLE sem;
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(NEED_SEM)
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int leftToUnblock;
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PTW32_OBJECT_AUTO_INIT ((void *)(size_t) -1)
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PTW32_OBJECT_INVALID   NULL
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct pthread_mutex_t_
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LONG lock_idx;		/* Provides exclusive access to mutex state
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				   via the Interlocked* mechanism.
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				    0: unlocked/free.
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				    1: locked - no other waiters.
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				   -1: locked - with possible other waiters.
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				*/
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int recursive_count;		/* Number of unlocks a thread needs to perform
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				   before the lock is released (recursive
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				   mutexes only). */
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int kind;			/* Mutex type. */
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pthread_t ownerThread;
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HANDLE event;			/* Mutex release notification to waiting
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				   threads. */
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ptw32_robust_node_t*
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    robustNode; /* Extra state for robust mutexes  */
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum ptw32_robust_state_t_
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PTW32_ROBUST_CONSISTENT,
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PTW32_ROBUST_INCONSISTENT,
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PTW32_ROBUST_NOTRECOVERABLE
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef enum ptw32_robust_state_t_   ptw32_robust_state_t;
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Node used to manage per-thread lists of currently-held robust mutexes.
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ptw32_robust_node_t_
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pthread_mutex_t mx;
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ptw32_robust_state_t stateInconsistent;
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ptw32_robust_node_t* prev;
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ptw32_robust_node_t* next;
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct pthread_mutexattr_t_
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int pshared;
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int kind;
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int robustness;
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Possible values, other than PTW32_OBJECT_INVALID,
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * for the "interlock" element in a spinlock.
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * In this implementation, when a spinlock is initialised,
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the number of cpus available to the process is checked.
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If there is only one cpu then "interlock" is set equal to
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * PTW32_SPIN_USE_MUTEX and u.mutex is an initialised mutex.
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If the number of cpus is greater than 1 then "interlock"
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * is set equal to PTW32_SPIN_UNLOCKED and the number is
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * stored in u.cpus. This arrangement allows the spinlock
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * routines to attempt an InterlockedCompareExchange on "interlock"
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * immediately and, if that fails, to try the inferior mutex.
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * "u.cpus" isn't used for anything yet, but could be used at
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * some point to optimise spinlock behaviour.
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PTW32_SPIN_INVALID     (0)
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PTW32_SPIN_UNLOCKED    (1)
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PTW32_SPIN_LOCKED      (2)
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PTW32_SPIN_USE_MUTEX   (3)
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct pthread_spinlock_t_
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  long interlock;		/* Locking element for multi-cpus. */
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  union
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int cpus;			/* No. of cpus if multi cpus, or   */
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pthread_mutex_t mutex;	/* mutex if single cpu.            */
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } u;
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * MCS lock queue node - see ptw32_MCS_lock.c
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ptw32_mcs_node_t_
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct ptw32_mcs_node_t_ **lock;        /* ptr to tail of queue */
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct ptw32_mcs_node_t_  *next;        /* ptr to successor in queue */
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HANDLE                     readyFlag;   /* set after lock is released by
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             predecessor */
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HANDLE                     nextFlag;    /* set after 'next' ptr is set by
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             successor */
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct pthread_barrier_t_
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned int nCurrentBarrierHeight;
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned int nInitialBarrierHeight;
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int pshared;
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sem_t semBarrierBreeched;
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ptw32_mcs_lock_t lock;
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ptw32_mcs_local_node_t proxynode;
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct pthread_barrierattr_t_
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int pshared;
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct pthread_key_t_
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DWORD key;
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void (PTW32_CDECL *destructor) (void *);
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ptw32_mcs_lock_t keyLock;
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void *threads;
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct ThreadParms ThreadParms;
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ThreadParms
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pthread_t tid;
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void *(PTW32_CDECL *start) (void *);
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void *arg;
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct pthread_cond_t_
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  long nWaitersBlocked;		/* Number of threads blocked            */
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  long nWaitersGone;		/* Number of threads timed out          */
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  long nWaitersToUnblock;	/* Number of threads to unblock         */
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sem_t semBlockQueue;		/* Queue up threads waiting for the     */
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /*   condition to become signalled      */
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sem_t semBlockLock;		/* Semaphore that guards access to      */
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* | waiters blocked count/block queue  */
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* +-> Mandatory Sync.LEVEL-1           */
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pthread_mutex_t mtxUnblockLock;	/* Mutex that guards access to          */
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* | waiters (to)unblock(ed) counts     */
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* +-> Optional* Sync.LEVEL-2           */
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pthread_cond_t next;		/* Doubly linked list                   */
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pthread_cond_t prev;
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct pthread_condattr_t_
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int pshared;
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PTW32_RWLOCK_MAGIC 0xfacade2
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct pthread_rwlock_t_
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pthread_mutex_t mtxExclusiveAccess;
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pthread_mutex_t mtxSharedAccessCompleted;
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pthread_cond_t cndSharedAccessCompleted;
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int nSharedAccessCount;
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int nExclusiveAccessCount;
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int nCompletedSharedAccessCount;
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int nMagic;
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct pthread_rwlockattr_t_
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int pshared;
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct ThreadKeyAssoc ThreadKeyAssoc;
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ThreadKeyAssoc
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /*
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   * Purpose:
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *      This structure creates an association between a thread and a key.
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *      It is used to implement the implicit invocation of a user defined
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *      destroy routine for thread specific data registered by a user upon
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *      exiting a thread.
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *      Graphically, the arrangement is as follows, where:
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *         K - Key with destructor
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *            (head of chain is key->threads)
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *         T - Thread that has called pthread_setspecific(Kn)
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *            (head of chain is thread->keys)
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *         A - Association. Each association is a node at the
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *             intersection of two doubly-linked lists.
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *                 T1    T2    T3
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *                 |     |     |
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *                 |     |     |
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *         K1 -----+-----A-----A----->
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *                 |     |     |
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *                 |     |     |
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *         K2 -----A-----A-----+----->
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *                 |     |     |
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *                 |     |     |
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *         K3 -----A-----+-----A----->
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *                 |     |     |
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *                 |     |     |
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *                 V     V     V
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *      Access to the association is guarded by two locks: the key's
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *      general lock (guarding the row) and the thread's general
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *      lock (guarding the column). This avoids the need for a
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *      dedicated lock for each association, which not only consumes
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *      more handles but requires that the lock resources persist
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *      until both the key is deleted and the thread has called the
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *      destructor. The two-lock arrangement allows those resources
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *      to be freed as soon as either thread or key is concluded.
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *      To avoid deadlock, whenever both locks are required both the
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *      key and thread locks are acquired consistently in the order
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *      "key lock then thread lock". An exception to this exists
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *      when a thread calls the destructors, however, this is done
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *      carefully (but inelegantly) to avoid deadlock.
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *      An association is created when a thread first calls
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *      pthread_setspecific() on a key that has a specified
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *      destructor.
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *      An association is destroyed either immediately after the
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *      thread calls the key destructor function on thread exit, or
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *      when the key is deleted.
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   * Attributes:
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *      thread
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *              reference to the thread that owns the
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *              association. This is actually the pointer to the
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *              thread struct itself. Since the association is
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *              destroyed before the thread exits, this can never
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *              point to a different logical thread to the one that
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *              created the assoc, i.e. after thread struct reuse.
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *      key
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *              reference to the key that owns the association.
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *      nextKey
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *              The pthread_t->keys attribute is the head of a
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *              chain of associations that runs through the nextKey
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *              link. This chain provides the 1 to many relationship
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *              between a pthread_t and all pthread_key_t on which
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *              it called pthread_setspecific.
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *      prevKey
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *              Similarly.
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *      nextThread
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *              The pthread_key_t->threads attribute is the head of
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *              a chain of associations that runs through the
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *              nextThreads link. This chain provides the 1 to many
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *              relationship between a pthread_key_t and all the
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *              PThreads that have called pthread_setspecific for
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *              this pthread_key_t.
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *      prevThread
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *              Similarly.
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   * Notes:
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *      1)      As soon as either the key or the thread is no longer
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *              referencing the association, it can be destroyed. The
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *              association will be removed from both chains.
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *      2)      Under WIN32, an association is only created by
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *              pthread_setspecific if the user provided a
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *              destroyRoutine when they created the key.
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   */
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ptw32_thread_t * thread;
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pthread_key_t key;
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ThreadKeyAssoc *nextKey;
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ThreadKeyAssoc *nextThread;
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ThreadKeyAssoc *prevKey;
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ThreadKeyAssoc *prevThread;
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(__CLEANUP_SEH)
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * --------------------------------------------------------------
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * MAKE_SOFTWARE_EXCEPTION
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *      This macro constructs a software exception code following
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *      the same format as the standard Win32 error codes as defined
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *      in WINERROR.H
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *  Values are 32 bit values laid out as follows:
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *  +---+-+-+-----------------------+-------------------------------+
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *  |Sev|C|R|     Facility          |               Code            |
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *  +---+-+-+-----------------------+-------------------------------+
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Severity Values:
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SE_SUCCESS              0x00
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SE_INFORMATION          0x01
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SE_WARNING              0x02
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SE_ERROR                0x03
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAKE_SOFTWARE_EXCEPTION( _severity, _facility, _exception ) \
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)( (DWORD) ( ( (_severity) << 30 ) |     /* Severity code        */ \
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ( 1 << 29 ) |               /* MS=0, User=1         */ \
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ( 0 << 28 ) |               /* Reserved             */ \
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ( (_facility) << 16 ) |     /* Facility Code        */ \
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ( (_exception) <<  0 )      /* Exception Code       */ \
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ) )
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * We choose one specific Facility/Error code combination to
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * identify our software exceptions vs. WIN32 exceptions.
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * We store our actual component and error code within
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the optional information array.
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define EXCEPTION_PTW32_SERVICES        \
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     MAKE_SOFTWARE_EXCEPTION( SE_ERROR, \
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              PTW32_SERVICES_FACILITY, \
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              PTW32_SERVICES_ERROR )
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PTW32_SERVICES_FACILITY         0xBAD
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PTW32_SERVICES_ERROR            0xDEED
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* __CLEANUP_SEH */
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Services available through EXCEPTION_PTW32_SERVICES
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and also used [as parameters to ptw32_throw()] as
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * generic exception selectors.
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PTW32_EPS_EXIT                  (1)
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PTW32_EPS_CANCEL                (2)
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Useful macros */
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PTW32_MAX(a,b)  ((a)<(b)?(b):(a))
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PTW32_MIN(a,b)  ((a)>(b)?(b):(a))
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Declared in pthread_cancel.c */
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern DWORD (*ptw32_register_cancelation) (PAPCFUNC, HANDLE, DWORD);
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Thread Reuse stack bottom marker. Must not be NULL or any valid pointer to memory. */
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PTW32_THREAD_REUSE_EMPTY ((ptw32_thread_t *)(size_t) 1)
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern int ptw32_processInitialized;
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern ptw32_thread_t * ptw32_threadReuseTop;
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern ptw32_thread_t * ptw32_threadReuseBottom;
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern pthread_key_t ptw32_selfThreadKey;
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern pthread_key_t ptw32_cleanupKey;
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern pthread_cond_t ptw32_cond_list_head;
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern pthread_cond_t ptw32_cond_list_tail;
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern int ptw32_mutex_default_kind;
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern unsigned __int64 ptw32_threadSeqNumber;
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern int ptw32_concurrency;
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern int ptw32_features;
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern ptw32_mcs_lock_t ptw32_thread_reuse_lock;
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern ptw32_mcs_lock_t ptw32_mutex_test_init_lock;
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern ptw32_mcs_lock_t ptw32_cond_list_lock;
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern ptw32_mcs_lock_t ptw32_cond_test_init_lock;
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern ptw32_mcs_lock_t ptw32_rwlock_test_init_lock;
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern ptw32_mcs_lock_t ptw32_spinlock_test_init_lock;
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(_UWIN)
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern int pthread_count;
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(__cplusplus)
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern "C"
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif				/* __cplusplus */
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * =====================
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * =====================
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Forward Declarations
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * =====================
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * =====================
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int ptw32_is_attr (const pthread_attr_t * attr);
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int ptw32_cond_check_need_init (pthread_cond_t * cond);
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int ptw32_mutex_check_need_init (pthread_mutex_t * mutex);
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int ptw32_rwlock_check_need_init (pthread_rwlock_t * rwlock);
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int ptw32_spinlock_check_need_init (pthread_spinlock_t * lock);
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int ptw32_robust_mutex_inherit(pthread_mutex_t * mutex);
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ptw32_robust_mutex_add(pthread_mutex_t* mutex, pthread_t self);
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ptw32_robust_mutex_remove(pthread_mutex_t* mutex, ptw32_thread_t* otp);
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DWORD
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ptw32_RegisterCancelation (PAPCFUNC callback,
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			       HANDLE threadH, DWORD callback_arg);
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int ptw32_processInitialize (void);
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ptw32_processTerminate (void);
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ptw32_threadDestroy (pthread_t tid);
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ptw32_pop_cleanup_all (int execute);
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pthread_t ptw32_new (void);
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pthread_t ptw32_threadReusePop (void);
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ptw32_threadReusePush (pthread_t thread);
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int ptw32_getprocessors (int *count);
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int ptw32_setthreadpriority (pthread_t thread, int policy, int priority);
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ptw32_rwlock_cancelwrwait (void *arg);
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if ! (defined (__MINGW64__) || defined(__MINGW32__)) || (defined(__MSVCRT__) && ! defined(__DMC__))
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned __stdcall
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ptw32_threadStart (void *vthreadParms);
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ptw32_callUserDestroyRoutines (pthread_t thread);
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int ptw32_tkAssocCreate (ptw32_thread_t * thread, pthread_key_t key);
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ptw32_tkAssocDestroy (ThreadKeyAssoc * assoc);
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int ptw32_semwait (sem_t * sem);
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DWORD ptw32_relmillisecs (const struct timespec * abstime);
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ptw32_mcs_lock_acquire (ptw32_mcs_lock_t * lock, ptw32_mcs_local_node_t * node);
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int ptw32_mcs_lock_try_acquire (ptw32_mcs_lock_t * lock, ptw32_mcs_local_node_t * node);
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ptw32_mcs_lock_release (ptw32_mcs_local_node_t * node);
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ptw32_mcs_node_transfer (ptw32_mcs_local_node_t * new_node, ptw32_mcs_local_node_t * old_node);
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(NEED_FTIME)
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ptw32_timespec_to_filetime (const struct timespec *ts, FILETIME * ft);
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ptw32_filetime_to_timespec (const FILETIME * ft, struct timespec *ts);
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Declared in misc.c */
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(NEED_CALLOC)
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define calloc(n, s) ptw32_calloc(n, s)
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void *ptw32_calloc (size_t n, size_t s);
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Declared in private.c */
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(_MSC_VER)
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Ignore the warning:
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * "C++ exception specification ignored except to indicate that
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the function is not __declspec(nothrow)."
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#pragma warning(disable:4290)
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ptw32_throw (DWORD exception)
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(__CLEANUP_CXX)
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    throw(ptw32_exception_cancel,ptw32_exception_exit)
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles);
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(__cplusplus)
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif				/* __cplusplus */
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(_UWIN_)
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   if defined(_MT)
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#       if defined(__cplusplus)
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern "C"
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#       endif
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  _CRTIMP unsigned long __cdecl _beginthread (void (__cdecl *) (void *),
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					      unsigned, void *);
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  _CRTIMP void __cdecl _endthread (void);
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  _CRTIMP unsigned long __cdecl _beginthreadex (void *, unsigned,
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)						unsigned (__stdcall *) (void *),
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)						void *, unsigned, unsigned *);
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  _CRTIMP void __cdecl _endthreadex (unsigned);
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#       if defined(__cplusplus)
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#       endif
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   endif
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#       include <process.h>
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   endif
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Use intrinsic versions wherever possible. VC will do this
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * automatically where possible and GCC define these if available:
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * __GCC_HAVE_SYNC_COMPARE_AND_SWAP_16
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The full set of Interlocked intrinsics in GCC are (check versions):
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * type __sync_fetch_and_add (type *ptr, type value, ...)
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * type __sync_fetch_and_sub (type *ptr, type value, ...)
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * type __sync_fetch_and_or (type *ptr, type value, ...)
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * type __sync_fetch_and_and (type *ptr, type value, ...)
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * type __sync_fetch_and_xor (type *ptr, type value, ...)
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * type __sync_fetch_and_nand (type *ptr, type value, ...)
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * type __sync_add_and_fetch (type *ptr, type value, ...)
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * type __sync_sub_and_fetch (type *ptr, type value, ...)
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * type __sync_or_and_fetch (type *ptr, type value, ...)
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * type __sync_and_and_fetch (type *ptr, type value, ...)
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * type __sync_xor_and_fetch (type *ptr, type value, ...)
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * type __sync_nand_and_fetch (type *ptr, type value, ...)
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * bool __sync_bool_compare_and_swap (type *ptr, type oldval type newval, ...)
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * type __sync_val_compare_and_swap (type *ptr, type oldval type newval, ...)
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * __sync_synchronize (...) // Full memory barrier
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * type __sync_lock_test_and_set (type *ptr, type value, ...) // Acquire barrier
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * void __sync_lock_release (type *ptr, ...) // Release barrier
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * These are all overloaded and take 1,2,4,8 byte scalar or pointer types.
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The above aren't available in Mingw32 as of gcc 4.5.2 so define our own.
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(__cplusplus)
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# define PTW32_TO_VLONG64PTR(ptr) reinterpret_cast<volatile LONG64 *>(ptr)
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# define PTW32_TO_VLONG64PTR(ptr) (ptr)
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(__GNUC__)
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# if defined(_WIN64)
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# define PTW32_INTERLOCKED_COMPARE_EXCHANGE_64(location, value, comparand)    \
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ({                                                                     \
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      __typeof (value) _result;                                            \
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      __asm__ __volatile__                                                 \
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (                                                                    \
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "lock\n\t"                                                         \
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "cmpxchgq      %2,(%1)"                                            \
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        :"=a" (_result)                                                    \
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        :"r"  (location), "r" (value), "a" (comparand)                     \
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        :"memory", "cc");                                                  \
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      _result;                                                             \
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    })
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# define PTW32_INTERLOCKED_EXCHANGE_64(location, value)                    \
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ({                                                                     \
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      __typeof (value) _result;                                            \
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      __asm__ __volatile__                                                 \
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (                                                                    \
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "xchgq	 %0,(%1)"                                                  \
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        :"=r" (_result)                                                    \
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        :"r" (location), "0" (value)                                       \
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        :"memory", "cc");                                                  \
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      _result;                                                             \
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    })
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# define PTW32_INTERLOCKED_EXCHANGE_ADD_64(location, value)                \
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ({                                                                     \
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      __typeof (value) _result;                                            \
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      __asm__ __volatile__                                                 \
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (                                                                    \
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "lock\n\t"                                                         \
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "xaddq	 %0,(%1)"                                                  \
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        :"=r" (_result)                                                    \
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        :"r" (location), "0" (value)                                       \
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        :"memory", "cc");                                                  \
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      _result;                                                             \
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    })
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# define PTW32_INTERLOCKED_INCREMENT_64(location)                          \
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ({                                                                     \
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PTW32_INTERLOCKED_LONG _temp = 1;                                   \
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      __asm__ __volatile__                                                 \
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (                                                                    \
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "lock\n\t"                                                         \
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "xaddq	 %0,(%1)"                                                  \
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        :"+r" (_temp)                                                      \
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        :"r" (location)                                                    \
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        :"memory", "cc");                                                  \
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ++_temp;                                                             \
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    })
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# define PTW32_INTERLOCKED_DECREMENT_64(location)                          \
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ({                                                                     \
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PTW32_INTERLOCKED_LONG _temp = -1;                                  \
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      __asm__ __volatile__                                                 \
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (                                                                    \
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "lock\n\t"                                                         \
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "xaddq	 %2,(%1)"                                                  \
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        :"+r" (_temp)                                                      \
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        :"r" (location)                                                    \
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        :"memory", "cc");                                                  \
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      --_temp;                                                             \
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    })
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# define PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG(location, value, comparand)    \
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ({                                                                     \
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      __typeof (value) _result;                                            \
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      __asm__ __volatile__                                                 \
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (                                                                    \
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "lock\n\t"                                                         \
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "cmpxchgl       %2,(%1)"                                           \
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        :"=a" (_result)                                                    \
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        :"r"  (location), "r" (value), "a" (comparand)                     \
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        :"memory", "cc");                                                  \
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      _result;                                                             \
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    })
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# define PTW32_INTERLOCKED_EXCHANGE_LONG(location, value)                  \
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ({                                                                     \
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      __typeof (value) _result;                                            \
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      __asm__ __volatile__                                                 \
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (                                                                    \
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "xchgl	 %0,(%1)"                                                  \
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        :"=r" (_result)                                                    \
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        :"r" (location), "0" (value)                                       \
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        :"memory", "cc");                                                  \
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      _result;                                                             \
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    })
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# define PTW32_INTERLOCKED_EXCHANGE_ADD_LONG(location, value)              \
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ({                                                                     \
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      __typeof (value) _result;                                            \
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      __asm__ __volatile__                                                 \
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (                                                                    \
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "lock\n\t"                                                         \
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "xaddl	 %0,(%1)"                                                  \
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        :"=r" (_result)                                                    \
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        :"r" (location), "0" (value)                                       \
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        :"memory", "cc");                                                  \
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      _result;                                                             \
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    })
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# define PTW32_INTERLOCKED_INCREMENT_LONG(location)                        \
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ({                                                                     \
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PTW32_INTERLOCKED_LONG _temp = 1;                                   \
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      __asm__ __volatile__                                                 \
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (                                                                    \
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "lock\n\t"                                                         \
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "xaddl	 %0,(%1)"                                                  \
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        :"+r" (_temp)                                                      \
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        :"r" (location)                                                    \
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        :"memory", "cc");                                                  \
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ++_temp;                                                             \
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    })
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# define PTW32_INTERLOCKED_DECREMENT_LONG(location)                        \
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ({                                                                     \
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PTW32_INTERLOCKED_LONG _temp = -1;                                  \
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      __asm__ __volatile__                                                 \
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (                                                                    \
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "lock\n\t"                                                         \
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "xaddl	 %0,(%1)"                                                  \
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        :"+r" (_temp)                                                      \
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        :"r" (location)                                                    \
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        :"memory", "cc");                                                  \
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      --_temp;                                                             \
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    })
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# define PTW32_INTERLOCKED_COMPARE_EXCHANGE_PTR(location, value, comparand) \
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PTW32_INTERLOCKED_COMPARE_EXCHANGE_SIZE((PTW32_INTERLOCKED_SIZEPTR)location, \
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            (PTW32_INTERLOCKED_SIZE)value, \
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            (PTW32_INTERLOCKED_SIZE)comparand)
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# define PTW32_INTERLOCKED_EXCHANGE_PTR(location, value) \
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PTW32_INTERLOCKED_EXCHANGE_SIZE((PTW32_INTERLOCKED_SIZEPTR)location, \
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    (PTW32_INTERLOCKED_SIZE)value)
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# if defined(_WIN64)
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   define PTW32_INTERLOCKED_COMPARE_EXCHANGE_64(p,v,c) InterlockedCompareExchange64(PTW32_TO_VLONG64PTR(p),(v),(c))
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   define PTW32_INTERLOCKED_EXCHANGE_64(p,v) InterlockedExchange64(PTW32_TO_VLONG64PTR(p),(v))
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   define PTW32_INTERLOCKED_EXCHANGE_ADD_64(p,v) InterlockedExchangeAdd64(PTW32_TO_VLONG64PTR(p),(v))
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   define PTW32_INTERLOCKED_INCREMENT_64(p) InterlockedIncrement64(PTW32_TO_VLONG64PTR(p))
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   define PTW32_INTERLOCKED_DECREMENT_64(p) InterlockedDecrement64(PTW32_TO_VLONG64PTR(p))
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# endif
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# if defined(_MSC_VER) && _MSC_VER < 1300 && !defined(_WIN64) /* MSVC 6 */
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#  define PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG(location, value, comparand) \
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ((LONG)InterlockedCompareExchange((PVOID *)(location), (PVOID)(value), (PVOID)(comparand)))
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# else
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#  define PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG InterlockedCompareExchange
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# endif
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# define PTW32_INTERLOCKED_EXCHANGE_LONG(p,v) InterlockedExchange((p),(v))
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# define PTW32_INTERLOCKED_EXCHANGE_ADD_LONG(p,v) InterlockedExchangeAdd((p),(v))
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# define PTW32_INTERLOCKED_INCREMENT_LONG(p) InterlockedIncrement((p))
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# define PTW32_INTERLOCKED_DECREMENT_LONG(p) InterlockedDecrement((p))
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# if defined(_MSC_VER) && _MSC_VER < 1300 && !defined(_WIN64) /* MSVC 6 */
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#  define PTW32_INTERLOCKED_COMPARE_EXCHANGE_PTR InterlockedCompareExchange
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#  define PTW32_INTERLOCKED_EXCHANGE_PTR(location, value) \
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ((PVOID)InterlockedExchange((LPLONG)(location), (LONG)(value)))
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# else
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#  define PTW32_INTERLOCKED_COMPARE_EXCHANGE_PTR(p,v,c) InterlockedCompareExchangePointer((p),(v),(c))
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#  define PTW32_INTERLOCKED_EXCHANGE_PTR(p,v) InterlockedExchangePointer((p),(v))
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# endif
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(_WIN64)
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   define PTW32_INTERLOCKED_COMPARE_EXCHANGE_SIZE(p,v,c) PTW32_INTERLOCKED_COMPARE_EXCHANGE_64(PTW32_TO_VLONG64PTR(p),(v),(c))
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   define PTW32_INTERLOCKED_EXCHANGE_SIZE(p,v) PTW32_INTERLOCKED_EXCHANGE_64(PTW32_TO_VLONG64PTR(p),(v))
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   define PTW32_INTERLOCKED_EXCHANGE_ADD_SIZE(p,v) PTW32_INTERLOCKED_EXCHANGE_ADD_64(PTW32_TO_VLONG64PTR(p),(v))
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   define PTW32_INTERLOCKED_INCREMENT_SIZE(p) PTW32_INTERLOCKED_INCREMENT_64(PTW32_TO_VLONG64PTR(p))
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   define PTW32_INTERLOCKED_DECREMENT_SIZE(p) PTW32_INTERLOCKED_DECREMENT_64(PTW32_TO_VLONG64PTR(p))
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   define PTW32_INTERLOCKED_COMPARE_EXCHANGE_SIZE(p,v,c) PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG((p),(v),(c))
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   define PTW32_INTERLOCKED_EXCHANGE_SIZE(p,v) PTW32_INTERLOCKED_EXCHANGE_LONG((p),(v))
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   define PTW32_INTERLOCKED_EXCHANGE_ADD_SIZE(p,v) PTW32_INTERLOCKED_EXCHANGE_ADD_LONG((p),(v))
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   define PTW32_INTERLOCKED_INCREMENT_SIZE(p) PTW32_INTERLOCKED_INCREMENT_LONG((p))
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   define PTW32_INTERLOCKED_DECREMENT_SIZE(p) PTW32_INTERLOCKED_DECREMENT_LONG((p))
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(NEED_CREATETHREAD)
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Macro uses args so we can cast start_proc to LPTHREAD_START_ROUTINE
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * in order to avoid warnings because of return type
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define _beginthreadex(security, \
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       stack_size, \
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       start_proc, \
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       arg, \
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       flags, \
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       pid) \
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        CreateThread(security, \
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     stack_size, \
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     (LPTHREAD_START_ROUTINE) start_proc, \
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     arg, \
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     flags, \
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     pid)
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define _endthreadex ExitThread
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif				/* NEED_CREATETHREAD */
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif				/* _IMPLEMENT_H */
963