diff options
Diffstat (limited to 'pthreads/implement.h')
-rw-r--r-- | pthreads/implement.h | 193 |
1 files changed, 130 insertions, 63 deletions
diff --git a/pthreads/implement.h b/pthreads/implement.h index 6b9f42503..189c668e5 100644 --- a/pthreads/implement.h +++ b/pthreads/implement.h @@ -9,26 +9,26 @@ * * Pthreads-win32 - POSIX Threads Library for Win32 * Copyright(C) 1998 John E. Bossom - * Copyright(C) 1999,2005 Pthreads-win32 contributors - * + * Copyright(C) 1999,2012 Pthreads-win32 contributors + * * Contact Email: Ross.Johnson@homemail.com.au - * + * * The current list of contributors is contained * in the file CONTRIBUTORS included with the source * code distribution. The list can also be seen at the * following World Wide Web location: * http://sources.redhat.com/pthreads-win32/contributors.html - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library in the file COPYING.LIB; * if not, write to the Free Software Foundation, Inc., @@ -38,8 +38,12 @@ #if !defined(_IMPLEMENT_H) #define _IMPLEMENT_H +#if !defined(PTW32_CONFIG_H) && !defined(_PTHREAD_TEST_H_) +# error "config.h was not #included" +#endif + #if !defined(_WIN32_WINNT) -#define _WIN32_WINNT 0x0400 +# define _WIN32_WINNT 0x0400 #endif #include <windows.h> @@ -52,6 +56,39 @@ typedef VOID (APIENTRY *PAPCFUNC)(DWORD dwParam); #endif /* + * Designed to allow error values to be set and retrieved in builds where + * MSCRT libraries are statically linked to DLLs. + */ +#if ( defined(PTW32_CONFIG_MINGW) && __MSVCRT_VERSION__ >= 0x0800 ) || \ + ( defined(_MSC_VER) && _MSC_VER >= 1400 ) /* MSVC8+ */ +# if defined(PTW32_CONFIG_MINGW) +__attribute__((unused)) +# endif +static int ptw32_get_errno(void) { int err = 0; _get_errno(&err); return err; } +# define PTW32_GET_ERRNO() ptw32_get_errno() +# if defined(PTW32_USES_SEPARATE_CRT) +# if defined(PTW32_CONFIG_MINGW) +__attribute__((unused)) +# endif +static void ptw32_set_errno(int err) { _set_errno(err); SetLastError(err); } +# define PTW32_SET_ERRNO(err) ptw32_set_errno(err) +# else +# define PTW32_SET_ERRNO(err) _set_errno(err) +# endif +#else +# define PTW32_GET_ERRNO() (errno) +# if defined(PTW32_USES_SEPARATE_CRT) +# if defined(PTW32_CONFIG_MINGW) +__attribute__((unused)) +# endif +static void ptw32_set_errno(int err) { errno = err; SetLastError(err); } +# define PTW32_SET_ERRNO(err) ptw32_set_errno(err) +# else +# define PTW32_SET_ERRNO(err) (errno = (err)) +# endif +#endif + +/* * note: ETIMEDOUT is correctly defined in winsock.h */ #include <winsock.h> @@ -60,11 +97,11 @@ typedef VOID (APIENTRY *PAPCFUNC)(DWORD dwParam); * In case ETIMEDOUT hasn't been defined above somehow. */ #if !defined(ETIMEDOUT) -# define ETIMEDOUT 10060 /* This is the value in winsock.h. */ +# define ETIMEDOUT 10060 /* This is the value in winsock.h. */ #endif #if !defined(malloc) -#include <malloc.h> +# include <malloc.h> #endif #if defined(__CLEANUP_C) @@ -72,45 +109,62 @@ typedef VOID (APIENTRY *PAPCFUNC)(DWORD dwParam); #endif #if !defined(INT_MAX) -#include <limits.h> +# include <limits.h> #endif /* use local include files during development */ #include "semaphore.h" #include "sched.h" -#if defined(HAVE_C_INLINE) || defined(__cplusplus) -#define INLINE inline -#else +/* MSVC 7.1 doesn't like complex #if expressions */ #define INLINE +#if defined(PTW32_BUILD_INLINED) +# if defined(HAVE_C_INLINE) || defined(__cplusplus) +# undef INLINE +# define INLINE inline +# endif #endif -#if defined(_MSC_VER) && _MSC_VER < 1300 -/* - * MSVC 6 does not use the "volatile" qualifier - */ -#define PTW32_INTERLOCKED_VOLATILE +#if defined(PTW32_CONFIG_MSVC6) +# define PTW32_INTERLOCKED_VOLATILE #else -#define PTW32_INTERLOCKED_VOLATILE volatile +# define PTW32_INTERLOCKED_VOLATILE volatile #endif + #define PTW32_INTERLOCKED_LONG long -#define PTW32_INTERLOCKED_SIZE size_t #define PTW32_INTERLOCKED_PVOID PVOID #define PTW32_INTERLOCKED_LONGPTR PTW32_INTERLOCKED_VOLATILE long* -#define PTW32_INTERLOCKED_SIZEPTR PTW32_INTERLOCKED_VOLATILE size_t* #define PTW32_INTERLOCKED_PVOID_PTR PTW32_INTERLOCKED_VOLATILE PVOID* +#if defined(_WIN64) +# define PTW32_INTERLOCKED_SIZE LONGLONG +# define PTW32_INTERLOCKED_SIZEPTR PTW32_INTERLOCKED_VOLATILE LONGLONG* +#else +# define PTW32_INTERLOCKED_SIZE long +# define PTW32_INTERLOCKED_SIZEPTR PTW32_INTERLOCKED_VOLATILE long* +#endif -#if defined(__MINGW64__) || defined(__MINGW32__) +#if defined(PTW32_CONFIG_MINGW) # include <stdint.h> #elif defined(__BORLANDC__) # define int64_t ULONGLONG #else # define int64_t _int64 -# if defined(_MSC_VER) && _MSC_VER < 1300 +# if defined(PTW32_CONFIG_MSVC6) typedef long intptr_t; # endif #endif +/* + * Don't allow the linker to optimize away autostatic.obj in static builds. + */ +#if defined(PTW32_STATIC_LIB) && defined(PTW32_BUILD) + void ptw32_autostatic_anchor(void); +# if defined(PTW32_CONFIG_MINGW) + __attribute__((unused, used)) +# endif + static void (*local_autostatic_anchor)(void) = ptw32_autostatic_anchor; +#endif + typedef enum { /* @@ -122,7 +176,7 @@ typedef enum PThreadStateRunning, /* Thread alive & kicking */ PThreadStateSuspended, /* Thread alive but suspended */ PThreadStateCancelPending, /* Thread alive but */ - /* has cancelation pending. */ + /* has cancellation pending. */ PThreadStateCanceling, /* Thread alive but is */ /* in the process of terminating */ /* due to a cancellation request */ @@ -139,7 +193,6 @@ typedef struct ptw32_mcs_node_t_* ptw32_mcs_lock_t; typedef struct ptw32_robust_node_t_ ptw32_robust_node_t; typedef struct ptw32_thread_t_ ptw32_thread_t; - struct ptw32_thread_t_ { unsigned __int64 seqNumber; /* Process-unique thread sequence number */ @@ -170,7 +223,8 @@ struct ptw32_thread_t_ int cancelState; int cancelType; int implicit:1; - DWORD thread; /* Win32 thread ID */ + DWORD thread; /* Windows thread ID */ + size_t cpuset; /* Thread CPU affinity set */ #if defined(_UWIN) DWORD dummy[5]; #endif @@ -178,7 +232,7 @@ struct ptw32_thread_t_ }; -/* +/* * Special value to mark attribute objects as valid. */ #define PTW32_ATTR_VALID ((unsigned long) 0xC4C0FFEE) @@ -329,7 +383,7 @@ struct pthread_barrierattr_t_ struct pthread_key_t_ { DWORD key; - void (*destructor) (void *); + void (PTW32_CDECL *destructor) (void *); ptw32_mcs_lock_t keyLock; void *threads; }; @@ -340,7 +394,7 @@ typedef struct ThreadParms ThreadParms; struct ThreadParms { pthread_t tid; - void *(*start) (void *); + void *(PTW32_CDECL *start) (void *); void *arg; }; @@ -386,6 +440,12 @@ struct pthread_rwlockattr_t_ int pshared; }; +typedef union +{ + char cpuset[CPU_SETSIZE/8]; + size_t _cpuset; +} _sched_cpu_set_vector_; + typedef struct ThreadKeyAssoc ThreadKeyAssoc; struct ThreadKeyAssoc @@ -469,7 +529,7 @@ struct ThreadKeyAssoc * The pthread_key_t->threads attribute is the head of * a chain of associations that runs through the * nextThreads link. This chain provides the 1 to many - * relationship between a pthread_key_t and all the + * relationship between a pthread_key_t and all the * PThreads that have called pthread_setspecific for * this pthread_key_t. * @@ -557,7 +617,7 @@ struct ThreadKeyAssoc /* Declared in pthread_cancel.c */ -extern DWORD (*ptw32_register_cancelation) (PAPCFUNC, HANDLE, DWORD); +extern DWORD (*ptw32_register_cancellation) (PAPCFUNC, HANDLE, DWORD); /* Thread Reuse stack bottom marker. Must not be NULL or any valid pointer to memory. */ #define PTW32_THREAD_REUSE_EMPTY ((ptw32_thread_t *)(size_t) 1) @@ -607,13 +667,14 @@ extern "C" int ptw32_cond_check_need_init (pthread_cond_t * cond); int ptw32_mutex_check_need_init (pthread_mutex_t * mutex); int ptw32_rwlock_check_need_init (pthread_rwlock_t * rwlock); + int ptw32_spinlock_check_need_init (pthread_spinlock_t * lock); int ptw32_robust_mutex_inherit(pthread_mutex_t * mutex); void ptw32_robust_mutex_add(pthread_mutex_t* mutex, pthread_t self); void ptw32_robust_mutex_remove(pthread_mutex_t* mutex, ptw32_thread_t* otp); DWORD - ptw32_RegisterCancelation (PAPCFUNC callback, + ptw32_Registercancellation (PAPCFUNC callback, HANDLE threadH, DWORD callback_arg); int ptw32_processInitialize (void); @@ -636,7 +697,7 @@ extern "C" void ptw32_rwlock_cancelwrwait (void *arg); -#if ! (defined (__MINGW64__) || defined(__MINGW32__)) || (defined(__MSVCRT__) && ! defined(__DMC__)) +#if ! defined (PTW32_CONFIG_MINGW) || (defined (__MSVCRT__) && ! defined (__DMC__)) unsigned __stdcall #else void @@ -746,9 +807,15 @@ extern "C" * * The above aren't available in Mingw32 as of gcc 4.5.2 so define our own. */ +#if defined(__cplusplus) +# define PTW32_TO_VLONG64PTR(ptr) reinterpret_cast<volatile LONG64 *>(ptr) +#else +# define PTW32_TO_VLONG64PTR(ptr) (ptr) +#endif + #if defined(__GNUC__) # if defined(_WIN64) -# define PTW32_INTERLOCKED_COMPARE_EXCHANGE_64(location, value, comparand) \ +# define PTW32_INTERLOCKED_COMPARE_EXCHANGE_64(location, value, comparand) \ ({ \ __typeof (value) _result; \ __asm__ __volatile__ \ @@ -785,7 +852,7 @@ extern "C" }) # define PTW32_INTERLOCKED_INCREMENT_64(location) \ ({ \ - PTW32_INTERLOCKED_LONG _temp = 1; \ + PTW32_INTERLOCKED_LONG _temp = 1; \ __asm__ __volatile__ \ ( \ "lock\n\t" \ @@ -797,7 +864,7 @@ extern "C" }) # define PTW32_INTERLOCKED_DECREMENT_64(location) \ ({ \ - PTW32_INTERLOCKED_LONG _temp = -1; \ + PTW32_INTERLOCKED_LONG _temp = -1; \ __asm__ __volatile__ \ ( \ "lock\n\t" \ @@ -808,7 +875,7 @@ extern "C" --_temp; \ }) #endif -# define PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG(location, value, comparand) \ +# define PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG(location, value, comparand) \ ({ \ __typeof (value) _result; \ __asm__ __volatile__ \ @@ -845,7 +912,7 @@ extern "C" }) # define PTW32_INTERLOCKED_INCREMENT_LONG(location) \ ({ \ - PTW32_INTERLOCKED_LONG _temp = 1; \ + PTW32_INTERLOCKED_LONG _temp = 1; \ __asm__ __volatile__ \ ( \ "lock\n\t" \ @@ -857,7 +924,7 @@ extern "C" }) # define PTW32_INTERLOCKED_DECREMENT_LONG(location) \ ({ \ - PTW32_INTERLOCKED_LONG _temp = -1; \ + PTW32_INTERLOCKED_LONG _temp = -1; \ __asm__ __volatile__ \ ( \ "lock\n\t" \ @@ -876,48 +943,48 @@ extern "C" (PTW32_INTERLOCKED_SIZE)value) #else # if defined(_WIN64) -# define PTW32_INTERLOCKED_COMPARE_EXCHANGE_64 InterlockedCompareExchange64 -# define PTW32_INTERLOCKED_EXCHANGE_64 InterlockedExchange64 -# define PTW32_INTERLOCKED_EXCHANGE_ADD_64 InterlockedExchangeAdd64 -# define PTW32_INTERLOCKED_INCREMENT_64 InterlockedIncrement64 -# define PTW32_INTERLOCKED_DECREMENT_64 InterlockedDecrement64 +# define PTW32_INTERLOCKED_COMPARE_EXCHANGE_64(p,v,c) InterlockedCompareExchange64(PTW32_TO_VLONG64PTR(p),(v),(c)) +# define PTW32_INTERLOCKED_EXCHANGE_64(p,v) InterlockedExchange64(PTW32_TO_VLONG64PTR(p),(v)) +# define PTW32_INTERLOCKED_EXCHANGE_ADD_64(p,v) InterlockedExchangeAdd64(PTW32_TO_VLONG64PTR(p),(v)) +# define PTW32_INTERLOCKED_INCREMENT_64(p) InterlockedIncrement64(PTW32_TO_VLONG64PTR(p)) +# define PTW32_INTERLOCKED_DECREMENT_64(p) InterlockedDecrement64(PTW32_TO_VLONG64PTR(p)) # endif -# if defined(_MSC_VER) && _MSC_VER < 1300 && !defined(_WIN64) /* MSVC 6 */ +# if defined(PTW32_CONFIG_MSVC6) && !defined(_WIN64) # define PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG(location, value, comparand) \ ((LONG)InterlockedCompareExchange((PVOID *)(location), (PVOID)(value), (PVOID)(comparand))) # else # define PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG InterlockedCompareExchange # endif -# define PTW32_INTERLOCKED_EXCHANGE_LONG InterlockedExchange -# define PTW32_INTERLOCKED_EXCHANGE_ADD_LONG InterlockedExchangeAdd -# define PTW32_INTERLOCKED_INCREMENT_LONG InterlockedIncrement -# define PTW32_INTERLOCKED_DECREMENT_LONG InterlockedDecrement -# if defined(_MSC_VER) && _MSC_VER < 1300 && !defined(_WIN64) /* MSVC 6 */ +# define PTW32_INTERLOCKED_EXCHANGE_LONG(p,v) InterlockedExchange((p),(v)) +# define PTW32_INTERLOCKED_EXCHANGE_ADD_LONG(p,v) InterlockedExchangeAdd((p),(v)) +# define PTW32_INTERLOCKED_INCREMENT_LONG(p) InterlockedIncrement((p)) +# define PTW32_INTERLOCKED_DECREMENT_LONG(p) InterlockedDecrement((p)) +# if defined(PTW32_CONFIG_MSVC6) && !defined(_WIN64) # define PTW32_INTERLOCKED_COMPARE_EXCHANGE_PTR InterlockedCompareExchange # define PTW32_INTERLOCKED_EXCHANGE_PTR(location, value) \ ((PVOID)InterlockedExchange((LPLONG)(location), (LONG)(value))) # else -# define PTW32_INTERLOCKED_COMPARE_EXCHANGE_PTR InterlockedCompareExchangePointer -# define PTW32_INTERLOCKED_EXCHANGE_PTR InterlockedExchangePointer +# define PTW32_INTERLOCKED_COMPARE_EXCHANGE_PTR(p,v,c) InterlockedCompareExchangePointer((p),(v),(c)) +# define PTW32_INTERLOCKED_EXCHANGE_PTR(p,v) InterlockedExchangePointer((p),(v)) # endif #endif #if defined(_WIN64) -# define PTW32_INTERLOCKED_COMPARE_EXCHANGE_SIZE PTW32_INTERLOCKED_COMPARE_EXCHANGE_64 -# define PTW32_INTERLOCKED_EXCHANGE_SIZE PTW32_INTERLOCKED_EXCHANGE_64 -# define PTW32_INTERLOCKED_EXCHANGE_ADD_SIZE PTW32_INTERLOCKED_EXCHANGE_ADD_64 -# define PTW32_INTERLOCKED_INCREMENT_SIZE PTW32_INTERLOCKED_INCREMENT_64 -# define PTW32_INTERLOCKED_DECREMENT_SIZE PTW32_INTERLOCKED_DECREMENT_64 +# define PTW32_INTERLOCKED_COMPARE_EXCHANGE_SIZE(p,v,c) PTW32_INTERLOCKED_COMPARE_EXCHANGE_64(PTW32_TO_VLONG64PTR(p),(v),(c)) +# define PTW32_INTERLOCKED_EXCHANGE_SIZE(p,v) PTW32_INTERLOCKED_EXCHANGE_64(PTW32_TO_VLONG64PTR(p),(v)) +# define PTW32_INTERLOCKED_EXCHANGE_ADD_SIZE(p,v) PTW32_INTERLOCKED_EXCHANGE_ADD_64(PTW32_TO_VLONG64PTR(p),(v)) +# define PTW32_INTERLOCKED_INCREMENT_SIZE(p) PTW32_INTERLOCKED_INCREMENT_64(PTW32_TO_VLONG64PTR(p)) +# define PTW32_INTERLOCKED_DECREMENT_SIZE(p) PTW32_INTERLOCKED_DECREMENT_64(PTW32_TO_VLONG64PTR(p)) #else -# define PTW32_INTERLOCKED_COMPARE_EXCHANGE_SIZE PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG -# define PTW32_INTERLOCKED_EXCHANGE_SIZE PTW32_INTERLOCKED_EXCHANGE_LONG -# define PTW32_INTERLOCKED_EXCHANGE_ADD_SIZE PTW32_INTERLOCKED_EXCHANGE_ADD_LONG -# define PTW32_INTERLOCKED_INCREMENT_SIZE PTW32_INTERLOCKED_INCREMENT_LONG -# define PTW32_INTERLOCKED_DECREMENT_SIZE PTW32_INTERLOCKED_DECREMENT_LONG +# define PTW32_INTERLOCKED_COMPARE_EXCHANGE_SIZE(p,v,c) PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG((p),(v),(c)) +# define PTW32_INTERLOCKED_EXCHANGE_SIZE(p,v) PTW32_INTERLOCKED_EXCHANGE_LONG((p),(v)) +# define PTW32_INTERLOCKED_EXCHANGE_ADD_SIZE(p,v) PTW32_INTERLOCKED_EXCHANGE_ADD_LONG((p),(v)) +# define PTW32_INTERLOCKED_INCREMENT_SIZE(p) PTW32_INTERLOCKED_INCREMENT_LONG((p)) +# define PTW32_INTERLOCKED_DECREMENT_SIZE(p) PTW32_INTERLOCKED_DECREMENT_LONG((p)) #endif #if defined(NEED_CREATETHREAD) -/* +/* * Macro uses args so we can cast start_proc to LPTHREAD_START_ROUTINE * in order to avoid warnings because of return type */ |