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