aboutsummaryrefslogtreecommitdiff
path: root/pthreads/implement.h
diff options
context:
space:
mode:
Diffstat (limited to 'pthreads/implement.h')
-rw-r--r--pthreads/implement.h193
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
*/