Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
tsoc
openmm
Commits
6cf75568
Commit
6cf75568
authored
May 15, 2015
by
peastman
Browse files
Switched over to new Windows pthreads library
parent
08945326
Changes
16
Show whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
1409 additions
and
3127 deletions
+1409
-3127
CMakeLists.txt
CMakeLists.txt
+2
-19
libraries/pthreads-2/include/pthread.h
libraries/pthreads-2/include/pthread.h
+0
-1625
libraries/pthreads-2/src/pthread.c
libraries/pthreads-2/src/pthread.c
+0
-15
libraries/pthreads/include/pthread.h
libraries/pthreads/include/pthread.h
+1388
-1122
libraries/pthreads/include/sched.h
libraries/pthreads/include/sched.h
+0
-178
libraries/pthreads/include/semaphore.h
libraries/pthreads/include/semaphore.h
+0
-166
libraries/pthreads/lib/pthreadVC2.dll
libraries/pthreads/lib/pthreadVC2.dll
+0
-0
libraries/pthreads/lib/pthreadVC2.lib
libraries/pthreads/lib/pthreadVC2.lib
+0
-0
libraries/pthreads/lib/pthreadVC2_static_mt.lib
libraries/pthreads/lib/pthreadVC2_static_mt.lib
+0
-0
libraries/pthreads/lib/pthreadVC2_x64.dll
libraries/pthreads/lib/pthreadVC2_x64.dll
+0
-0
libraries/pthreads/lib/pthreadVC2_x64.lib
libraries/pthreads/lib/pthreadVC2_x64.lib
+0
-0
libraries/pthreads/src/pthread.cpp
libraries/pthreads/src/pthread.cpp
+15
-0
platforms/cpu/src/gmx_atomic.h
platforms/cpu/src/gmx_atomic.h
+1
-0
platforms/cuda/include/CudaContext.h
platforms/cuda/include/CudaContext.h
+1
-1
platforms/opencl/include/OpenCLContext.h
platforms/opencl/include/OpenCLContext.h
+1
-1
plugins/cpupme/src/CpuPmeKernels.h
plugins/cpupme/src/CpuPmeKernels.h
+1
-0
No files found.
CMakeLists.txt
View file @
6cf75568
...
@@ -81,20 +81,6 @@ ENDIF(${CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT})
...
@@ -81,20 +81,6 @@ ENDIF(${CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT})
SET
(
OPENMM_SOURCE_SUBDIRS . openmmapi olla libraries/jama libraries/quern libraries/lepton libraries/sfmt libraries/lbfgs libraries/hilbert libraries/csha1 platforms/reference serialization libraries/validate libraries/irrxml
)
SET
(
OPENMM_SOURCE_SUBDIRS . openmmapi olla libraries/jama libraries/quern libraries/lepton libraries/sfmt libraries/lbfgs libraries/hilbert libraries/csha1 platforms/reference serialization libraries/validate libraries/irrxml
)
IF
(
WIN32
)
IF
(
WIN32
)
SET
(
OPENMM_SOURCE_SUBDIRS
${
OPENMM_SOURCE_SUBDIRS
}
libraries/pthreads
)
SET
(
OPENMM_SOURCE_SUBDIRS
${
OPENMM_SOURCE_SUBDIRS
}
libraries/pthreads
)
ADD_CUSTOM_TARGET
(
PthreadsLibraries ALL
)
FILE
(
GLOB PTHREADS_LIBRARIES libraries/pthreads/lib/*.dll libraries/pthreads/lib/*.lib
)
ADD_CUSTOM_COMMAND
(
TARGET PthreadsLibraries COMMAND
${
CMAKE_COMMAND
}
ARGS -E make_directory
"
${
CMAKE_CURRENT_BINARY_DIR
}
/
${
CMAKE_CFG_INTDIR
}
/"
)
FOREACH
(
lib
${
PTHREADS_LIBRARIES
}
)
ADD_CUSTOM_COMMAND
(
TARGET PthreadsLibraries COMMAND
${
CMAKE_COMMAND
}
ARGS -E copy
${
lib
}
"
${
CMAKE_CURRENT_BINARY_DIR
}
/
${
CMAKE_CFG_INTDIR
}
/"
)
INSTALL
(
FILES
${
lib
}
DESTINATION
"lib/"
)
ENDFOREACH
(
lib
)
LINK_DIRECTORIES
(
"
${
CMAKE_CURRENT_BINARY_DIR
}
/
${
CMAKE_CFG_INTDIR
}
"
)
IF
(
CMAKE_SIZEOF_VOID_P EQUAL 8
)
SET
(
PTHREADS_LIB pthreadVC2_x64
)
ELSE
(
CMAKE_SIZEOF_VOID_P EQUAL 8
)
SET
(
PTHREADS_LIB pthreadVC2
)
SET
(
PTHREADS_LIB_STATIC pthreadVC2_static_mt
)
ENDIF
(
CMAKE_SIZEOF_VOID_P EQUAL 8
)
ELSE
(
WIN32
)
ELSE
(
WIN32
)
IF
(
NOT ANDROID
)
IF
(
NOT ANDROID
)
SET
(
PTHREADS_LIB pthread
)
SET
(
PTHREADS_LIB pthread
)
...
@@ -301,17 +287,14 @@ ENDIF (CMAKE_SYSTEM_NAME MATCHES "Linux")
...
@@ -301,17 +287,14 @@ ENDIF (CMAKE_SYSTEM_NAME MATCHES "Linux")
IF
(
OPENMM_BUILD_SHARED_LIB
)
IF
(
OPENMM_BUILD_SHARED_LIB
)
ADD_LIBRARY
(
${
SHARED_TARGET
}
SHARED
${
SOURCE_FILES
}
${
SOURCE_INCLUDE_FILES
}
${
API_ABS_INCLUDE_FILES
}
)
ADD_LIBRARY
(
${
SHARED_TARGET
}
SHARED
${
SOURCE_FILES
}
${
SOURCE_INCLUDE_FILES
}
${
API_ABS_INCLUDE_FILES
}
)
SET_TARGET_PROPERTIES
(
${
SHARED_TARGET
}
PROPERTIES LINK_FLAGS
"
${
EXTRA_LINK_FLAGS
}
"
COMPILE_FLAGS
"
${
EXTRA_COMPILE_FLAGS
}
-DOPENMM_BUILDING_SHARED_LIBRARY -DLEPTON_BUILDING_SHARED_LIBRARY -DOPENMM_VALIDATE_BUILDING_SHARED_LIBRARY"
)
SET_TARGET_PROPERTIES
(
${
SHARED_TARGET
}
PROPERTIES LINK_FLAGS
"
${
EXTRA_LINK_FLAGS
}
"
COMPILE_FLAGS
"
${
EXTRA_COMPILE_FLAGS
}
-DOPENMM_BUILDING_SHARED_LIBRARY -DLEPTON_BUILDING_SHARED_LIBRARY -DOPENMM_VALIDATE_BUILDING_SHARED_LIBRARY -DPTHREAD_BUILDING_SHARED_LIBRARY"
)
IF
(
WIN32
)
ADD_DEPENDENCIES
(
${
SHARED_TARGET
}
PthreadsLibraries
)
ENDIF
(
WIN32
)
ENDIF
(
OPENMM_BUILD_SHARED_LIB
)
ENDIF
(
OPENMM_BUILD_SHARED_LIB
)
SET
(
OPENMM_BUILD_STATIC_LIB OFF CACHE BOOL
"Whether to build static OpenMM libraries"
)
SET
(
OPENMM_BUILD_STATIC_LIB OFF CACHE BOOL
"Whether to build static OpenMM libraries"
)
IF
(
OPENMM_BUILD_STATIC_LIB
)
IF
(
OPENMM_BUILD_STATIC_LIB
)
ADD_LIBRARY
(
${
STATIC_TARGET
}
STATIC
${
SOURCE_FILES
}
${
SOURCE_INCLUDE_FILES
}
${
API_ABS_INCLUDE_FILES
}
)
ADD_LIBRARY
(
${
STATIC_TARGET
}
STATIC
${
SOURCE_FILES
}
${
SOURCE_INCLUDE_FILES
}
${
API_ABS_INCLUDE_FILES
}
)
SET
(
EXTRA_COMPILE_FLAGS
"
${
EXTRA_COMPILE_FLAGS
}
-DOPENMM_USE_STATIC_LIBRARIES -DLEPTON_USE_STATIC_LIBRARIES -DPTW32_STATIC_LIB"
)
SET
(
EXTRA_COMPILE_FLAGS
"
${
EXTRA_COMPILE_FLAGS
}
-DOPENMM_USE_STATIC_LIBRARIES -DLEPTON_USE_STATIC_LIBRARIES -DPTW32_STATIC_LIB"
)
SET_TARGET_PROPERTIES
(
${
STATIC_TARGET
}
PROPERTIES LINK_FLAGS
"
${
EXTRA_LINK_FLAGS
}
"
COMPILE_FLAGS
"
${
EXTRA_COMPILE_FLAGS
}
-DOPENMM_BUILDING_STATIC_LIBRARY -DLEPTON_BUILDING_STATIC_LIBRARY -DOPENMMM_VALIDATE_BUILDING_STATIC_LIBRARY -DOPENMM_VALIDATE_BUILDING_STATIC_LIBRARY"
)
SET_TARGET_PROPERTIES
(
${
STATIC_TARGET
}
PROPERTIES LINK_FLAGS
"
${
EXTRA_LINK_FLAGS
}
"
COMPILE_FLAGS
"
${
EXTRA_COMPILE_FLAGS
}
-DOPENMM_BUILDING_STATIC_LIBRARY -DLEPTON_BUILDING_STATIC_LIBRARY -DOPENMMM_VALIDATE_BUILDING_STATIC_LIBRARY -DOPENMM_VALIDATE_BUILDING_STATIC_LIBRARY
-DPTHREAD_BUILDING_STATIC_LIBRARY
"
)
ENDIF
(
OPENMM_BUILD_STATIC_LIB
)
ENDIF
(
OPENMM_BUILD_STATIC_LIB
)
IF
(
OPENMM_BUILD_C_AND_FORTRAN_WRAPPERS
)
IF
(
OPENMM_BUILD_C_AND_FORTRAN_WRAPPERS
)
...
...
libraries/pthreads-2/include/pthread.h
deleted
100644 → 0
View file @
08945326
/*
* Posix Threads library for Microsoft Windows
*
* Use at own risk, there is no implied warranty to this code.
* It uses undocumented features of Microsoft Windows that can change
* at any time in the future.
*
* (C) 2010 Lockless Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of Lockless Inc. nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AN
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* You may want to use the MingW64 winpthreads library instead.
* It is based on this, but adds error checking.
*/
/*
* Version 1.0.1 Released 2 Feb 2012
* Fixes pthread_barrier_destroy() to wait for threads to exit the barrier.
*/
#ifndef WIN_PTHREADS
#define WIN_PTHREADS
#include <windows.h>
#include <intrin.h>
#include <setjmp.h>
#include <errno.h>
#include <sys/timeb.h>
#include <process.h>
#define ETIMEDOUT 110
#define ENOTSUP 134
#define PTHREAD_CANCEL_DISABLE 0
#define PTHREAD_CANCEL_ENABLE 0x01
#define PTHREAD_CANCEL_DEFERRED 0
#define PTHREAD_CANCEL_ASYNCHRONOUS 0x02
#define PTHREAD_CREATE_JOINABLE 0
#define PTHREAD_CREATE_DETACHED 0x04
#define PTHREAD_EXPLICT_SCHED 0
#define PTHREAD_INHERIT_SCHED 0x08
#define PTHREAD_SCOPE_PROCESS 0
#define PTHREAD_SCOPE_SYSTEM 0x10
#define PTHREAD_DEFAULT_ATTR (PTHREAD_CANCEL_ENABLE)
#define PTHREAD_CANCELED ((void *) 0xDEADBEEF)
#define PTHREAD_ONCE_INIT 0
#define PTHREAD_MUTEX_INITIALIZER {(void*)-1,-1,0,0,0,0}
#define PTHREAD_RWLOCK_INITIALIZER {0}
#define PTHREAD_COND_INITIALIZER {0}
#define PTHREAD_BARRIER_INITIALIZER \
{0,0,PTHREAD_MUTEX_INITIALIZER,PTHREAD_COND_INITIALIZER}
#define PTHREAD_SPINLOCK_INITIALIZER 0
#define PTHREAD_DESTRUCTOR_ITERATIONS 256
#define PTHREAD_KEYS_MAX (1<<20)
#define PTHREAD_MUTEX_NORMAL 0
#define PTHREAD_MUTEX_ERRORCHECK 1
#define PTHREAD_MUTEX_RECURSIVE 2
#define PTHREAD_MUTEX_DEFAULT 3
#define PTHREAD_MUTEX_SHARED 4
#define PTHREAD_MUTEX_PRIVATE 0
#define PTHREAD_PRIO_NONE 0
#define PTHREAD_PRIO_INHERIT 8
#define PTHREAD_PRIO_PROTECT 16
#define PTHREAD_PRIO_MULT 32
#define PTHREAD_PROCESS_SHARED 0
#define PTHREAD_PROCESS_PRIVATE 1
#define PTHREAD_BARRIER_SERIAL_THREAD 1
#ifdef _X86_
#define INTERLOCKED_COMPARE_EXCHANGE(destination, exchange, comparand) _InterlockedCompareExchange((volatile long*) destination, (long) exchange, (long) comparand)
#else
#define INTERLOCKED_COMPARE_EXCHANGE(destination, exchange, comparand) _InterlockedCompareExchangePointer((volatile PVOID*) destination, (void*) exchange, (void*) comparand)
#endif
/* Windows doesn't have this, so declare it ourselves. */
struct
timespec
{
/* long long in windows is the same as long in unix for 64bit */
long
long
tv_sec
;
long
long
tv_nsec
;
};
typedef
struct
_pthread_cleanup
_pthread_cleanup
;
struct
_pthread_cleanup
{
void
(
*
func
)(
void
*
);
void
*
arg
;
_pthread_cleanup
*
next
;
};
struct
_pthread_v
{
void
*
ret_arg
;
void
*
(
*
func
)(
void
*
);
_pthread_cleanup
*
clean
;
HANDLE
h
;
int
cancelled
;
unsigned
p_state
;
int
keymax
;
void
**
keyval
;
jmp_buf
jb
;
};
typedef
struct
_pthread_v
*
pthread_t
;
typedef
struct
pthread_barrier_t
pthread_barrier_t
;
struct
pthread_barrier_t
{
int
count
;
int
total
;
CRITICAL_SECTION
m
;
CONDITION_VARIABLE
cv
;
};
typedef
struct
pthread_attr_t
pthread_attr_t
;
struct
pthread_attr_t
{
unsigned
p_state
;
void
*
stack
;
size_t
s_size
;
};
typedef
long
pthread_once_t
;
typedef
unsigned
pthread_mutexattr_t
;
typedef
SRWLOCK
pthread_rwlock_t
;
typedef
CRITICAL_SECTION
pthread_mutex_t
;
typedef
unsigned
pthread_key_t
;
typedef
void
*
pthread_barrierattr_t
;
typedef
long
pthread_spinlock_t
;
typedef
int
pthread_condattr_t
;
typedef
CONDITION_VARIABLE
pthread_cond_t
;
typedef
int
pthread_rwlockattr_t
;
extern
volatile
long
_pthread_cancelling
;
extern
int
_pthread_concur
;
/* Will default to zero as needed */
extern
pthread_once_t
_pthread_tls_once
;
extern
DWORD
_pthread_tls
;
/* Note initializer is zero, so this works */
extern
pthread_rwlock_t
_pthread_key_lock
;
extern
long
_pthread_key_max
;
extern
long
_pthread_key_sch
;
extern
void
(
**
_pthread_key_dest
)(
void
*
);
#define pthread_cleanup_push(F, A)\
{\
const _pthread_cleanup _pthread_cup = {(F), (A), pthread_self()->clean};\
_ReadWriteBarrier();\
pthread_self()->clean = (_pthread_cleanup *) &_pthread_cup;\
_ReadWriteBarrier()
/* Note that if async cancelling is used, then there is a race here */
#define pthread_cleanup_pop(E)\
(pthread_self()->clean = _pthread_cup.next, (E?_pthread_cup.func(_pthread_cup.arg):0));}
static
void
_pthread_once_cleanup
(
pthread_once_t
*
o
)
{
*
o
=
0
;
}
static
pthread_t
pthread_self
(
void
);
static
int
pthread_once
(
pthread_once_t
*
o
,
void
(
*
func
)(
void
))
{
long
state
=
*
o
;
_ReadWriteBarrier
();
while
(
state
!=
1
)
{
if
(
!
state
)
{
if
(
!
_InterlockedCompareExchange
(
o
,
2
,
0
))
{
/* Success */
#ifdef __cplusplus
pthread_cleanup_push
(
reinterpret_cast
<
void
(
__cdecl
*
)(
void
*
)
>
(
_pthread_once_cleanup
),
o
);
#else
pthread_cleanup_push
(
_pthread_once_cleanup
,
o
);
#endif
func
();
pthread_cleanup_pop
(
0
);
/* Mark as done */
*
o
=
1
;
return
0
;
}
}
YieldProcessor
();
_ReadWriteBarrier
();
state
=
*
o
;
}
/* Done */
return
0
;
}
static
int
_pthread_once_raw
(
pthread_once_t
*
o
,
void
(
*
func
)(
void
))
{
long
state
=
*
o
;
_ReadWriteBarrier
();
while
(
state
!=
1
)
{
if
(
!
state
)
{
if
(
!
_InterlockedCompareExchange
(
o
,
2
,
0
))
{
/* Success */
func
();
/* Mark as done */
*
o
=
1
;
return
0
;
}
}
YieldProcessor
();
_ReadWriteBarrier
();
state
=
*
o
;
}
/* Done */
return
0
;
}
static
int
pthread_mutex_lock
(
pthread_mutex_t
*
m
)
{
EnterCriticalSection
(
m
);
return
0
;
}
static
int
pthread_mutex_unlock
(
pthread_mutex_t
*
m
)
{
LeaveCriticalSection
(
m
);
return
0
;
}
static
int
pthread_mutex_trylock
(
pthread_mutex_t
*
m
)
{
return
TryEnterCriticalSection
(
m
)
?
0
:
EBUSY
;
}
static
int
pthread_mutex_init
(
pthread_mutex_t
*
m
,
pthread_mutexattr_t
*
a
)
{
(
void
)
a
;
InitializeCriticalSection
(
m
);
return
0
;
}
static
int
pthread_mutex_destroy
(
pthread_mutex_t
*
m
)
{
DeleteCriticalSection
(
m
);
return
0
;
}
#define pthread_mutex_getprioceiling(M, P) ENOTSUP
#define pthread_mutex_setprioceiling(M, P) ENOTSUP
static
int
pthread_equal
(
pthread_t
t1
,
pthread_t
t2
)
{
return
t1
==
t2
;
}
static
void
pthread_testcancel
(
void
);
static
int
pthread_rwlock_init
(
pthread_rwlock_t
*
l
,
pthread_rwlockattr_t
*
a
)
{
(
void
)
a
;
InitializeSRWLock
(
l
);
return
0
;
}
static
int
pthread_rwlock_destroy
(
pthread_rwlock_t
*
l
)
{
(
void
)
*
l
;
return
0
;
}
static
int
pthread_rwlock_rdlock
(
pthread_rwlock_t
*
l
)
{
pthread_testcancel
();
AcquireSRWLockShared
(
l
);
return
0
;
}
static
int
pthread_rwlock_wrlock
(
pthread_rwlock_t
*
l
)
{
pthread_testcancel
();
AcquireSRWLockExclusive
(
l
);
return
0
;
}
static
void
pthread_tls_init
(
void
)
{
_pthread_tls
=
TlsAlloc
();
/* Cannot continue if out of indexes */
if
(
_pthread_tls
==
TLS_OUT_OF_INDEXES
)
abort
();
}
static
int
pthread_rwlock_unlock
(
pthread_rwlock_t
*
l
)
{
void
*
state
=
*
(
void
**
)
l
;
if
(
state
==
(
void
*
)
1
)
{
/* Known to be an exclusive lock */
ReleaseSRWLockExclusive
(
l
);
}
else
{
/* A shared unlock will work */
ReleaseSRWLockShared
(
l
);
}
return
0
;
}
static
void
_pthread_cleanup_dest
(
pthread_t
t
)
{
int
i
,
j
;
for
(
j
=
0
;
j
<
PTHREAD_DESTRUCTOR_ITERATIONS
;
j
++
)
{
int
flag
=
0
;
for
(
i
=
0
;
i
<
t
->
keymax
;
i
++
)
{
void
*
val
=
t
->
keyval
[
i
];
if
(
val
)
{
pthread_rwlock_rdlock
(
&
_pthread_key_lock
);
if
((
uintptr_t
)
_pthread_key_dest
[
i
]
>
1
)
{
/* Call destructor */
t
->
keyval
[
i
]
=
NULL
;
_pthread_key_dest
[
i
](
val
);
flag
=
1
;
}
pthread_rwlock_unlock
(
&
_pthread_key_lock
);
}
}
/* Nothing to do? */
if
(
!
flag
)
return
;
}
}
static
pthread_t
pthread_self
(
void
)
{
pthread_t
t
;
_pthread_once_raw
(
&
_pthread_tls_once
,
pthread_tls_init
);
t
=
(
pthread_t
)
TlsGetValue
(
_pthread_tls
);
/* Main thread? */
if
(
!
t
)
{
t
=
(
pthread_t
)
malloc
(
sizeof
(
struct
_pthread_v
));
/* If cannot initialize main thread, then the only thing we can do is abort */
if
(
!
t
)
abort
();
t
->
ret_arg
=
NULL
;
t
->
func
=
NULL
;
t
->
clean
=
NULL
;
t
->
cancelled
=
0
;
t
->
p_state
=
PTHREAD_DEFAULT_ATTR
;
t
->
keymax
=
0
;
t
->
keyval
=
NULL
;
t
->
h
=
GetCurrentThread
();
/* Save for later */
TlsSetValue
(
_pthread_tls
,
t
);
if
(
setjmp
(
t
->
jb
))
{
/* Make sure we free ourselves if we are detached */
if
(
!
t
->
h
)
free
(
t
);
/* Time to die */
_endthreadex
(
0
);
}
}
return
t
;
}
static
int
pthread_rwlock_tryrdlock
(
pthread_rwlock_t
*
l
)
{
/* Get the current state of the lock */
void
*
state
=
*
(
void
**
)
l
;
if
(
!
state
)
{
/* Unlocked to locked */
if
(
!
INTERLOCKED_COMPARE_EXCHANGE
((
volatile
PVOID
*
)
l
,
(
void
*
)
0x11
,
NULL
))
return
0
;
return
EBUSY
;
}
/* A single writer exists */
if
(
state
==
(
void
*
)
1
)
return
EBUSY
;
/* Multiple writers exist? */
if
((
uintptr_t
)
state
&
14
)
return
EBUSY
;
if
((
void
*
)
INTERLOCKED_COMPARE_EXCHANGE
((
volatile
PVOID
*
)
l
,
(
void
*
)
((
uintptr_t
)
state
+
16
),
state
)
==
state
)
return
0
;
return
EBUSY
;
}
static
int
pthread_rwlock_trywrlock
(
pthread_rwlock_t
*
l
)
{
/* Try to grab lock if it has no users */
if
(
!
INTERLOCKED_COMPARE_EXCHANGE
((
volatile
PVOID
*
)
l
,
(
void
*
)
1
,
NULL
))
return
0
;
return
EBUSY
;
}
static
unsigned
long
long
_pthread_time_in_ms
(
void
)
{
struct
__timeb64
tb
;
_ftime64
(
&
tb
);
return
tb
.
time
*
1000
+
tb
.
millitm
;
}
static
unsigned
long
long
_pthread_time_in_ms_from_timespec
(
const
struct
timespec
*
ts
)
{
unsigned
long
long
t
=
ts
->
tv_sec
*
1000
;
t
+=
ts
->
tv_nsec
/
1000000
;
return
t
;
}
static
unsigned
long
long
_pthread_rel_time_in_ms
(
const
struct
timespec
*
ts
)
{
unsigned
long
long
t1
=
_pthread_time_in_ms_from_timespec
(
ts
);
unsigned
long
long
t2
=
_pthread_time_in_ms
();
/* Prevent underflow */
if
(
t1
<
t2
)
return
0
;
return
t1
-
t2
;
}
static
int
pthread_rwlock_timedrdlock
(
pthread_rwlock_t
*
l
,
const
struct
timespec
*
ts
)
{
unsigned
long
long
ct
=
_pthread_time_in_ms
();
unsigned
long
long
t
=
_pthread_time_in_ms_from_timespec
(
ts
);
pthread_testcancel
();
/* Use a busy-loop */
while
(
1
)
{
/* Try to grab lock */
if
(
!
pthread_rwlock_tryrdlock
(
l
))
return
0
;
/* Get current time */
ct
=
_pthread_time_in_ms
();
/* Have we waited long enough? */
if
(
ct
>
t
)
return
ETIMEDOUT
;
}
}
static
int
pthread_rwlock_timedwrlock
(
pthread_rwlock_t
*
l
,
const
struct
timespec
*
ts
)
{
unsigned
long
long
ct
=
_pthread_time_in_ms
();
unsigned
long
long
t
=
_pthread_time_in_ms_from_timespec
(
ts
);
pthread_testcancel
();
/* Use a busy-loop */
while
(
1
)
{
/* Try to grab lock */
if
(
!
pthread_rwlock_trywrlock
(
l
))
return
0
;
/* Get current time */
ct
=
_pthread_time_in_ms
();
/* Have we waited long enough? */
if
(
ct
>
t
)
return
ETIMEDOUT
;
}
}
static
int
pthread_get_concurrency
(
int
*
val
)
{
*
val
=
_pthread_concur
;
return
0
;
}
static
int
pthread_set_concurrency
(
int
val
)
{
_pthread_concur
=
val
;
return
0
;
}
#define pthread_getschedparam(T, P, S) ENOTSUP
#define pthread_setschedparam(T, P, S) ENOTSUP
#define pthread_getcpuclockid(T, C) ENOTSUP
static
int
pthread_exit
(
void
*
res
)
{
pthread_t
t
=
pthread_self
();
t
->
ret_arg
=
res
;
_pthread_cleanup_dest
(
t
);
longjmp
(
t
->
jb
,
1
);
}
static
void
_pthread_invoke_cancel
(
void
)
{
_pthread_cleanup
*
pcup
;
_InterlockedDecrement
(
&
_pthread_cancelling
);
/* Call cancel queue */
for
(
pcup
=
pthread_self
()
->
clean
;
pcup
;
pcup
=
pcup
->
next
)
{
pcup
->
func
(
pcup
->
arg
);
}
pthread_exit
(
PTHREAD_CANCELED
);
}
static
void
pthread_testcancel
(
void
)
{
if
(
_pthread_cancelling
)
{
pthread_t
t
=
pthread_self
();
if
(
t
->
cancelled
&&
(
t
->
p_state
&
PTHREAD_CANCEL_ENABLE
))
{
_pthread_invoke_cancel
();
}
}
}
static
int
pthread_cancel
(
pthread_t
t
)
{
if
(
t
->
p_state
&
PTHREAD_CANCEL_ASYNCHRONOUS
)
{
/* Dangerous asynchronous cancelling */
CONTEXT
ctxt
;
/* Already done? */
if
(
t
->
cancelled
)
return
ESRCH
;
ctxt
.
ContextFlags
=
CONTEXT_CONTROL
;
SuspendThread
(
t
->
h
);
GetThreadContext
(
t
->
h
,
&
ctxt
);
#ifdef _M_X64
ctxt
.
Rip
=
(
uintptr_t
)
_pthread_invoke_cancel
;
#else
ctxt
.
Eip
=
(
uintptr_t
)
_pthread_invoke_cancel
;
#endif
SetThreadContext
(
t
->
h
,
&
ctxt
);
/* Also try deferred Cancelling */
t
->
cancelled
=
1
;
/* Notify everyone to look */
_InterlockedIncrement
(
&
_pthread_cancelling
);
ResumeThread
(
t
->
h
);
}
else
{
/* Safe deferred Cancelling */
t
->
cancelled
=
1
;
/* Notify everyone to look */
_InterlockedIncrement
(
&
_pthread_cancelling
);
}
return
0
;
}
static
unsigned
_pthread_get_state
(
pthread_attr_t
*
attr
,
unsigned
flag
)
{
return
attr
->
p_state
&
flag
;
}
static
int
_pthread_set_state
(
pthread_attr_t
*
attr
,
unsigned
flag
,
unsigned
val
)
{
if
(
~
flag
&
val
)
return
EINVAL
;
attr
->
p_state
&=
~
flag
;
attr
->
p_state
|=
val
;
return
0
;
}
static
int
pthread_attr_init
(
pthread_attr_t
*
attr
)
{
attr
->
p_state
=
PTHREAD_DEFAULT_ATTR
;
attr
->
stack
=
NULL
;
attr
->
s_size
=
0
;
return
0
;
}
static
int
pthread_attr_destroy
(
pthread_attr_t
*
attr
)
{
/* No need to do anything */
return
0
;
}
static
int
pthread_attr_setdetachstate
(
pthread_attr_t
*
a
,
int
flag
)
{
return
_pthread_set_state
(
a
,
PTHREAD_CREATE_DETACHED
,
flag
);
}
static
int
pthread_attr_getdetachstate
(
pthread_attr_t
*
a
,
int
*
flag
)
{
*
flag
=
_pthread_get_state
(
a
,
PTHREAD_CREATE_DETACHED
);
return
0
;
}
static
int
pthread_attr_setinheritsched
(
pthread_attr_t
*
a
,
int
flag
)
{
return
_pthread_set_state
(
a
,
PTHREAD_INHERIT_SCHED
,
flag
);
}
static
int
pthread_attr_getinheritsched
(
pthread_attr_t
*
a
,
int
*
flag
)
{
*
flag
=
_pthread_get_state
(
a
,
PTHREAD_INHERIT_SCHED
);
return
0
;
}
static
int
pthread_attr_setscope
(
pthread_attr_t
*
a
,
int
flag
)
{
return
_pthread_set_state
(
a
,
PTHREAD_SCOPE_SYSTEM
,
flag
);
}
static
int
pthread_attr_getscope
(
pthread_attr_t
*
a
,
int
*
flag
)
{
*
flag
=
_pthread_get_state
(
a
,
PTHREAD_SCOPE_SYSTEM
);
return
0
;
}
static
int
pthread_attr_getstackaddr
(
pthread_attr_t
*
attr
,
void
**
stack
)
{
*
stack
=
attr
->
stack
;
return
0
;
}
static
int
pthread_attr_setstackaddr
(
pthread_attr_t
*
attr
,
void
*
stack
)
{
attr
->
stack
=
stack
;
return
0
;
}
static
int
pthread_attr_getstacksize
(
pthread_attr_t
*
attr
,
size_t
*
size
)
{
*
size
=
attr
->
s_size
;
return
0
;
}
static
int
pthread_attr_setstacksize
(
pthread_attr_t
*
attr
,
size_t
size
)
{
attr
->
s_size
=
size
;
return
0
;
}
#define pthread_attr_getguardsize(A, S) ENOTSUP
#define pthread_attr_setgaurdsize(A, S) ENOTSUP
#define pthread_attr_getschedparam(A, S) ENOTSUP
#define pthread_attr_setschedparam(A, S) ENOTSUP
#define pthread_attr_getschedpolicy(A, S) ENOTSUP
#define pthread_attr_setschedpolicy(A, S) ENOTSUP
static
int
pthread_setcancelstate
(
int
state
,
int
*
oldstate
)
{
pthread_t
t
=
pthread_self
();
if
((
state
&
PTHREAD_CANCEL_ENABLE
)
!=
state
)
return
EINVAL
;
if
(
oldstate
)
*
oldstate
=
t
->
p_state
&
PTHREAD_CANCEL_ENABLE
;
t
->
p_state
&=
~
PTHREAD_CANCEL_ENABLE
;
t
->
p_state
|=
state
;
return
0
;
}
static
int
pthread_setcanceltype
(
int
type
,
int
*
oldtype
)
{
pthread_t
t
=
pthread_self
();
if
((
type
&
PTHREAD_CANCEL_ASYNCHRONOUS
)
!=
type
)
return
EINVAL
;
if
(
oldtype
)
*
oldtype
=
t
->
p_state
&
PTHREAD_CANCEL_ASYNCHRONOUS
;
t
->
p_state
&=
~
PTHREAD_CANCEL_ASYNCHRONOUS
;
t
->
p_state
|=
type
;
return
0
;
}
static
int
pthread_create_wrapper
(
void
*
args
)
{
struct
_pthread_v
*
tv
=
(
_pthread_v
*
)
args
;
int
i
,
j
;
_pthread_once_raw
(
&
_pthread_tls_once
,
pthread_tls_init
);
TlsSetValue
(
_pthread_tls
,
tv
);
if
(
!
setjmp
(
tv
->
jb
))
{
/* Call function and save return value */
tv
->
ret_arg
=
tv
->
func
(
tv
->
ret_arg
);
/* Clean up destructors */
_pthread_cleanup_dest
(
tv
);
}
/* If we exit too early, then we can race with create */
while
(
tv
->
h
==
(
HANDLE
)
-
1
)
{
YieldProcessor
();
_ReadWriteBarrier
();
}
/* Make sure we free ourselves if we are detached */
if
(
!
tv
->
h
)
free
(
tv
);
return
0
;
}
static
int
pthread_create
(
pthread_t
*
th
,
pthread_attr_t
*
attr
,
void
*
(
*
func
)(
void
*
),
void
*
arg
)
{
struct
_pthread_v
*
tv
=
(
_pthread_v
*
)
malloc
(
sizeof
(
struct
_pthread_v
));
unsigned
ssize
=
0
;
if
(
!
tv
)
return
1
;
*
th
=
tv
;
/* Save data in pthread_t */
tv
->
ret_arg
=
arg
;
tv
->
func
=
func
;
tv
->
clean
=
NULL
;
tv
->
cancelled
=
0
;
tv
->
p_state
=
PTHREAD_DEFAULT_ATTR
;
tv
->
keymax
=
0
;
tv
->
keyval
=
NULL
;
tv
->
h
=
(
HANDLE
)
-
1
;
if
(
attr
)
{
tv
->
p_state
=
attr
->
p_state
;
ssize
=
attr
->
s_size
;
}
/* Make sure tv->h has value of -1 */
_ReadWriteBarrier
();
#ifdef __cplusplus
tv
->
h
=
(
HANDLE
)
_beginthreadex
(
NULL
,
ssize
,
reinterpret_cast
<
unsigned
int
(
__stdcall
*
)(
void
*
)
>
(
pthread_create_wrapper
),
tv
,
0
,
NULL
);
#else
tv
->
h
=
(
HANDLE
)
_beginthreadex
(
NULL
,
ssize
,
pthread_create_wrapper
,
tv
,
0
,
NULL
);
#endif
/* Failed */
if
(
!
tv
->
h
)
return
1
;
if
(
tv
->
p_state
&
PTHREAD_CREATE_DETACHED
)
{
CloseHandle
(
tv
->
h
);
_ReadWriteBarrier
();
tv
->
h
=
0
;
}
return
0
;
}
static
int
pthread_join
(
pthread_t
t
,
void
**
res
)
{
struct
_pthread_v
*
tv
=
t
;
pthread_testcancel
();
WaitForSingleObject
(
tv
->
h
,
INFINITE
);
CloseHandle
(
tv
->
h
);
/* Obtain return value */
if
(
res
)
*
res
=
tv
->
ret_arg
;
free
(
tv
);
return
0
;
}
static
int
pthread_detach
(
pthread_t
t
)
{
struct
_pthread_v
*
tv
=
t
;
/*
* This can't race with thread exit because
* our call would be undefined if called on a dead thread.
*/
CloseHandle
(
tv
->
h
);
_ReadWriteBarrier
();
tv
->
h
=
0
;
return
0
;
}
static
int
pthread_mutexattr_init
(
pthread_mutexattr_t
*
a
)
{
*
a
=
0
;
return
0
;
}
static
int
pthread_mutexattr_destroy
(
pthread_mutexattr_t
*
a
)
{
(
void
)
a
;
return
0
;
}
static
int
pthread_mutexattr_gettype
(
pthread_mutexattr_t
*
a
,
int
*
type
)
{
*
type
=
*
a
&
3
;
return
0
;
}
static
int
pthread_mutexattr_settype
(
pthread_mutexattr_t
*
a
,
int
type
)
{
if
((
unsigned
)
type
>
3
)
return
EINVAL
;
*
a
&=
~
3
;
*
a
|=
type
;
return
0
;
}
static
int
pthread_mutexattr_getpshared
(
pthread_mutexattr_t
*
a
,
int
*
type
)
{
*
type
=
*
a
&
4
;
return
0
;
}
static
int
pthread_mutexattr_setpshared
(
pthread_mutexattr_t
*
a
,
int
type
)
{
if
((
type
&
4
)
!=
type
)
return
EINVAL
;
*
a
&=
~
4
;
*
a
|=
type
;
return
0
;
}
static
int
pthread_mutexattr_getprotocol
(
pthread_mutexattr_t
*
a
,
int
*
type
)
{
*
type
=
*
a
&
(
8
+
16
);
return
0
;
}
static
int
pthread_mutexattr_setprotocol
(
pthread_mutexattr_t
*
a
,
int
type
)
{
if
((
type
&
(
8
+
16
))
!=
8
+
16
)
return
EINVAL
;
*
a
&=
~
(
8
+
16
);
*
a
|=
type
;
return
0
;
}
static
int
pthread_mutexattr_getprioceiling
(
pthread_mutexattr_t
*
a
,
int
*
prio
)
{
*
prio
=
*
a
/
PTHREAD_PRIO_MULT
;
return
0
;
}
static
int
pthread_mutexattr_setprioceiling
(
pthread_mutexattr_t
*
a
,
int
prio
)
{
*
a
&=
(
PTHREAD_PRIO_MULT
-
1
);
*
a
+=
prio
*
PTHREAD_PRIO_MULT
;
return
0
;
}
static
int
pthread_mutex_timedlock
(
pthread_mutex_t
*
m
,
struct
timespec
*
ts
)
{
unsigned
long
long
t
,
ct
;
struct
_pthread_crit_t
{
void
*
debug
;
LONG
count
;
LONG
r_count
;
HANDLE
owner
;
HANDLE
sem
;
ULONG_PTR
spin
;
};
/* Try to lock it without waiting */
if
(
!
pthread_mutex_trylock
(
m
))
return
0
;
ct
=
_pthread_time_in_ms
();
t
=
_pthread_time_in_ms_from_timespec
(
ts
);
while
(
1
)
{
/* Have we waited long enough? */
if
(
ct
>
t
)
return
ETIMEDOUT
;
/* Wait on semaphore within critical section */
WaitForSingleObject
(((
struct
_pthread_crit_t
*
)
m
)
->
sem
,
t
-
ct
);
/* Try to grab lock */
if
(
!
pthread_mutex_trylock
(
m
))
return
0
;
/* Get current time */
ct
=
_pthread_time_in_ms
();
}
}
#define _PTHREAD_BARRIER_FLAG (1<<30)
static
int
pthread_barrier_destroy
(
pthread_barrier_t
*
b
)
{
EnterCriticalSection
(
&
b
->
m
);
while
(
b
->
total
>
_PTHREAD_BARRIER_FLAG
)
{
/* Wait until everyone exits the barrier */
SleepConditionVariableCS
(
&
b
->
cv
,
&
b
->
m
,
INFINITE
);
}
LeaveCriticalSection
(
&
b
->
m
);
DeleteCriticalSection
(
&
b
->
m
);
return
0
;
}
static
int
pthread_barrier_init
(
pthread_barrier_t
*
b
,
void
*
attr
,
int
count
)
{
/* Ignore attr */
(
void
)
attr
;
b
->
count
=
count
;
b
->
total
=
0
;
InitializeCriticalSection
(
&
b
->
m
);
InitializeConditionVariable
(
&
b
->
cv
);
return
0
;
}
static
int
pthread_barrier_wait
(
pthread_barrier_t
*
b
)
{
EnterCriticalSection
(
&
b
->
m
);
while
(
b
->
total
>
_PTHREAD_BARRIER_FLAG
)
{
/* Wait until everyone exits the barrier */
SleepConditionVariableCS
(
&
b
->
cv
,
&
b
->
m
,
INFINITE
);
}
/* Are we the first to enter? */
if
(
b
->
total
==
_PTHREAD_BARRIER_FLAG
)
b
->
total
=
0
;
b
->
total
++
;
if
(
b
->
total
==
b
->
count
)
{
b
->
total
+=
_PTHREAD_BARRIER_FLAG
-
1
;
WakeAllConditionVariable
(
&
b
->
cv
);
LeaveCriticalSection
(
&
b
->
m
);
return
1
;
}
else
{
while
(
b
->
total
<
_PTHREAD_BARRIER_FLAG
)
{
/* Wait until enough threads enter the barrier */
SleepConditionVariableCS
(
&
b
->
cv
,
&
b
->
m
,
INFINITE
);
}
b
->
total
--
;
/* Get entering threads to wake up */
if
(
b
->
total
==
_PTHREAD_BARRIER_FLAG
)
WakeAllConditionVariable
(
&
b
->
cv
);
LeaveCriticalSection
(
&
b
->
m
);
return
0
;
}
}
static
int
pthread_barrierattr_init
(
void
**
attr
)
{
*
attr
=
NULL
;
return
0
;
}
static
int
pthread_barrierattr_destroy
(
void
**
attr
)
{
/* Ignore attr */
(
void
)
attr
;
return
0
;
}
static
int
pthread_barrierattr_setpshared
(
void
**
attr
,
int
s
)
{
*
attr
=
(
void
*
)
s
;
return
0
;
}
static
int
pthread_barrierattr_getpshared
(
void
**
attr
,
int
*
s
)
{
*
s
=
(
int
)
(
size_t
)
*
attr
;
return
0
;
}
static
int
pthread_key_create
(
pthread_key_t
*
key
,
void
(
*
dest
)(
void
*
))
{
int
i
;
long
nmax
;
void
(
**
d
)(
void
*
);
if
(
!
key
)
return
EINVAL
;
pthread_rwlock_wrlock
(
&
_pthread_key_lock
);
for
(
i
=
_pthread_key_sch
;
i
<
_pthread_key_max
;
i
++
)
{
if
(
!
_pthread_key_dest
[
i
])
{
*
key
=
i
;
if
(
dest
)
{
_pthread_key_dest
[
i
]
=
dest
;
}
else
{
_pthread_key_dest
[
i
]
=
(
void
(
*
)(
void
*
))
1
;
}
pthread_rwlock_unlock
(
&
_pthread_key_lock
);
return
0
;
}
}
for
(
i
=
0
;
i
<
_pthread_key_sch
;
i
++
)
{
if
(
!
_pthread_key_dest
[
i
])
{
*
key
=
i
;
if
(
dest
)
{
_pthread_key_dest
[
i
]
=
dest
;
}
else
{
_pthread_key_dest
[
i
]
=
(
void
(
*
)(
void
*
))
1
;
}
pthread_rwlock_unlock
(
&
_pthread_key_lock
);
return
0
;
}
}
if
(
!
_pthread_key_max
)
_pthread_key_max
=
1
;
if
(
_pthread_key_max
==
PTHREAD_KEYS_MAX
)
{
pthread_rwlock_unlock
(
&
_pthread_key_lock
);
return
ENOMEM
;
}
nmax
=
_pthread_key_max
*
2
;
if
(
nmax
>
PTHREAD_KEYS_MAX
)
nmax
=
PTHREAD_KEYS_MAX
;
/* No spare room anywhere */
#ifdef __cplusplus
d
=
reinterpret_cast
<
void
(
__cdecl
**
)(
void
*
)
>
(
realloc
(
_pthread_key_dest
,
nmax
*
sizeof
(
*
d
)));
#else
d
=
realloc
(
_pthread_key_dest
,
nmax
*
sizeof
(
*
d
));
#endif
if
(
!
d
)
{
pthread_rwlock_unlock
(
&
_pthread_key_lock
);
return
ENOMEM
;
}
/* Clear new region */
memset
((
void
*
)
&
d
[
_pthread_key_max
],
0
,
(
nmax
-
_pthread_key_max
)
*
sizeof
(
void
*
));
/* Use new region */
_pthread_key_dest
=
d
;
_pthread_key_sch
=
_pthread_key_max
+
1
;
*
key
=
_pthread_key_max
;
_pthread_key_max
=
nmax
;
if
(
dest
)
{
_pthread_key_dest
[
*
key
]
=
dest
;
}
else
{
_pthread_key_dest
[
*
key
]
=
(
void
(
*
)(
void
*
))
1
;
}
pthread_rwlock_unlock
(
&
_pthread_key_lock
);
return
0
;
}
static
int
pthread_key_delete
(
pthread_key_t
key
)
{
if
(
key
>
_pthread_key_max
)
return
EINVAL
;
if
(
!
_pthread_key_dest
)
return
EINVAL
;
pthread_rwlock_wrlock
(
&
_pthread_key_lock
);
_pthread_key_dest
[
key
]
=
NULL
;
/* Start next search from our location */
if
(
_pthread_key_sch
>
key
)
_pthread_key_sch
=
key
;
pthread_rwlock_unlock
(
&
_pthread_key_lock
);
return
0
;
}
static
void
*
pthread_getspecific
(
pthread_key_t
key
)
{
pthread_t
t
=
pthread_self
();
if
(
key
>=
t
->
keymax
)
return
NULL
;
return
t
->
keyval
[
key
];
}
static
int
pthread_setspecific
(
pthread_key_t
key
,
const
void
*
value
)
{
pthread_t
t
=
pthread_self
();
if
(
key
>
t
->
keymax
)
{
int
keymax
=
(
key
+
1
)
*
2
;
void
**
kv
=
(
void
**
)
realloc
(
t
->
keyval
,
keymax
*
sizeof
(
void
*
));
if
(
!
kv
)
return
ENOMEM
;
/* Clear new region */
memset
(
&
kv
[
t
->
keymax
],
0
,
(
keymax
-
t
->
keymax
)
*
sizeof
(
void
*
));
t
->
keyval
=
kv
;
t
->
keymax
=
keymax
;
}
t
->
keyval
[
key
]
=
(
void
*
)
value
;
return
0
;
}
static
int
pthread_spin_init
(
pthread_spinlock_t
*
l
,
int
pshared
)
{
(
void
)
pshared
;
*
l
=
0
;
return
0
;
}
static
int
pthread_spin_destroy
(
pthread_spinlock_t
*
l
)
{
(
void
)
l
;
return
0
;
}
/* No-fair spinlock due to lack of knowledge of thread number */
static
int
pthread_spin_lock
(
pthread_spinlock_t
*
l
)
{
while
(
_InterlockedExchange
(
l
,
EBUSY
))
{
/* Don't lock the bus whilst waiting */
while
(
*
l
)
{
YieldProcessor
();
/* Compiler barrier. Prevent caching of *l */
_ReadWriteBarrier
();
}
}
return
0
;
}
static
int
pthread_spin_trylock
(
pthread_spinlock_t
*
l
)
{
return
_InterlockedExchange
(
l
,
EBUSY
);
}
static
int
pthread_spin_unlock
(
pthread_spinlock_t
*
l
)
{
/* Compiler barrier. The store below acts with release symmantics */
_ReadWriteBarrier
();
*
l
=
0
;
return
0
;
}
static
int
pthread_cond_init
(
pthread_cond_t
*
c
,
pthread_condattr_t
*
a
)
{
(
void
)
a
;
InitializeConditionVariable
(
c
);
return
0
;
}
static
int
pthread_cond_signal
(
pthread_cond_t
*
c
)
{
WakeConditionVariable
(
c
);
return
0
;
}
static
int
pthread_cond_broadcast
(
pthread_cond_t
*
c
)
{
WakeAllConditionVariable
(
c
);
return
0
;
}
static
int
pthread_cond_wait
(
pthread_cond_t
*
c
,
pthread_mutex_t
*
m
)
{
pthread_testcancel
();
SleepConditionVariableCS
(
c
,
m
,
INFINITE
);
return
0
;
}
static
int
pthread_cond_destroy
(
pthread_cond_t
*
c
)
{
(
void
)
c
;
return
0
;
}
static
int
pthread_cond_timedwait
(
pthread_cond_t
*
c
,
pthread_mutex_t
*
m
,
struct
timespec
*
t
)
{
unsigned
long
long
tm
=
_pthread_rel_time_in_ms
(
t
);
pthread_testcancel
();
if
(
!
SleepConditionVariableCS
(
c
,
m
,
tm
))
return
ETIMEDOUT
;
/* We can have a spurious wakeup after the timeout */
if
(
!
_pthread_rel_time_in_ms
(
t
))
return
ETIMEDOUT
;
return
0
;
}
static
int
pthread_condattr_destroy
(
pthread_condattr_t
*
a
)
{
(
void
)
a
;
return
0
;
}
#define pthread_condattr_getclock(A, C) ENOTSUP
#define pthread_condattr_setclock(A, C) ENOTSUP
static
int
pthread_condattr_init
(
pthread_condattr_t
*
a
)
{
*
a
=
0
;
return
0
;
}
static
int
pthread_condattr_getpshared
(
pthread_condattr_t
*
a
,
int
*
s
)
{
*
s
=
*
a
;
return
0
;
}
static
int
pthread_condattr_setpshared
(
pthread_condattr_t
*
a
,
int
s
)
{
*
a
=
s
;
return
0
;
}
static
int
pthread_rwlockattr_destroy
(
pthread_rwlockattr_t
*
a
)
{
(
void
)
a
;
return
0
;
}
static
int
pthread_rwlockattr_init
(
pthread_rwlockattr_t
*
a
)
{
*
a
=
0
;
}
static
int
pthread_rwlockattr_getpshared
(
pthread_rwlockattr_t
*
a
,
int
*
s
)
{
*
s
=
*
a
;
return
0
;
}
static
int
pthread_rwlockattr_setpshared
(
pthread_rwlockattr_t
*
a
,
int
s
)
{
*
a
=
s
;
return
0
;
}
/* No fork() in windows - so ignore this */
#define pthread_atfork(F1,F2,F3) 0
/* Windows has rudimentary signals support */
#define pthread_kill(T, S) 0
#define pthread_sigmask(H, S1, S2) 0
/* Wrap cancellation points */
/*
#define accept(...) (pthread_testcancel(), accept(__VA_ARGS__))
#define aio_suspend(...) (pthread_testcancel(), aio_suspend(__VA_ARGS__))
#define clock_nanosleep(...) (pthread_testcancel(), clock_nanosleep(__VA_ARGS__))
#define close(...) (pthread_testcancel(), close(__VA_ARGS__))
#define connect(...) (pthread_testcancel(), connect(__VA_ARGS__))
#define creat(...) (pthread_testcancel(), creat(__VA_ARGS__))
#define fcntl(...) (pthread_testcancel(), fcntl(__VA_ARGS__))
#define fdatasync(...) (pthread_testcancel(), fdatasync(__VA_ARGS__))
#define fsync(...) (pthread_testcancel(), fsync(__VA_ARGS__))
#define getmsg(...) (pthread_testcancel(), getmsg(__VA_ARGS__))
#define getpmsg(...) (pthread_testcancel(), getpmsg(__VA_ARGS__))
#define lockf(...) (pthread_testcancel(), lockf(__VA_ARGS__))
#define mg_receive(...) (pthread_testcancel(), mg_receive(__VA_ARGS__))
#define mg_send(...) (pthread_testcancel(), mg_send(__VA_ARGS__))
#define mg_timedreceive(...) (pthread_testcancel(), mg_timedreceive(__VA_ARGS__))
#define mg_timessend(...) (pthread_testcancel(), mg_timedsend(__VA_ARGS__))
#define msgrcv(...) (pthread_testcancel(), msgrecv(__VA_ARGS__))
#define msgsnd(...) (pthread_testcancel(), msgsnd(__VA_ARGS__))
#define msync(...) (pthread_testcancel(), msync(__VA_ARGS__))
#define nanosleep(...) (pthread_testcancel(), nanosleep(__VA_ARGS__))
#define open(...) (pthread_testcancel(), open(__VA_ARGS__))
#define pause(...) (pthread_testcancel(), pause(__VA_ARGS__))
#define poll(...) (pthread_testcancel(), poll(__VA_ARGS__))
#define pread(...) (pthread_testcancel(), pread(__VA_ARGS__))
#define pselect(...) (pthread_testcancel(), pselect(__VA_ARGS__))
#define putmsg(...) (pthread_testcancel(), putmsg(__VA_ARGS__))
#define putpmsg(...) (pthread_testcancel(), putpmsg(__VA_ARGS__))
#define pwrite(...) (pthread_testcancel(), pwrite(__VA_ARGS__))
#define read(...) (pthread_testcancel(), read(__VA_ARGS__))
#define readv(...) (pthread_testcancel(), readv(__VA_ARGS__))
#define recv(...) (pthread_testcancel(), recv(__VA_ARGS__))
#define recvfrom(...) (pthread_testcancel(), recvfrom(__VA_ARGS__))
#define recvmsg(...) (pthread_testcancel(), recvmsg(__VA_ARGS__))
#define select(...) (pthread_testcancel(), select(__VA_ARGS__))
#define sem_timedwait(...) (pthread_testcancel(), sem_timedwait(__VA_ARGS__))
#define sem_wait(...) (pthread_testcancel(), sem_wait(__VA_ARGS__))
#define send(...) (pthread_testcancel(), send(__VA_ARGS__))
#define sendmsg(...) (pthread_testcancel(), sendmsg(__VA_ARGS__))
#define sendto(...) (pthread_testcancel(), sendto(__VA_ARGS__))
#define sigpause(...) (pthread_testcancel(), sigpause(__VA_ARGS__))
#define sigsuspend(...) (pthread_testcancel(), sigsuspend(__VA_ARGS__))
#define sigwait(...) (pthread_testcancel(), sigwait(__VA_ARGS__))
#define sigwaitinfo(...) (pthread_testcancel(), sigwaitinfo(__VA_ARGS__))
#define sleep(...) (pthread_testcancel(), sleep(__VA_ARGS__))
//#define Sleep(...) (pthread_testcancel(), Sleep(__VA_ARGS__))
#define system(...) (pthread_testcancel(), system(__VA_ARGS__))
#define access(...) (pthread_testcancel(), access(__VA_ARGS__))
#define asctime(...) (pthread_testcancel(), asctime(__VA_ARGS__))
#define asctime_r(...) (pthread_testcancel(), asctime_r(__VA_ARGS__))
#define catclose(...) (pthread_testcancel(), catclose(__VA_ARGS__))
#define catgets(...) (pthread_testcancel(), catgets(__VA_ARGS__))
#define catopen(...) (pthread_testcancel(), catopen(__VA_ARGS__))
#define closedir(...) (pthread_testcancel(), closedir(__VA_ARGS__))
#define closelog(...) (pthread_testcancel(), closelog(__VA_ARGS__))
#define ctermid(...) (pthread_testcancel(), ctermid(__VA_ARGS__))
#define ctime(...) (pthread_testcancel(), ctime(__VA_ARGS__))
#define ctime_r(...) (pthread_testcancel(), ctime_r(__VA_ARGS__))
#define dbm_close(...) (pthread_testcancel(), dbm_close(__VA_ARGS__))
#define dbm_delete(...) (pthread_testcancel(), dbm_delete(__VA_ARGS__))
#define dbm_fetch(...) (pthread_testcancel(), dbm_fetch(__VA_ARGS__))
#define dbm_nextkey(...) (pthread_testcancel(), dbm_nextkey(__VA_ARGS__))
#define dbm_open(...) (pthread_testcancel(), dbm_open(__VA_ARGS__))
#define dbm_store(...) (pthread_testcancel(), dbm_store(__VA_ARGS__))
#define dlclose(...) (pthread_testcancel(), dlclose(__VA_ARGS__))
#define dlopen(...) (pthread_testcancel(), dlopen(__VA_ARGS__))
#define endgrent(...) (pthread_testcancel(), endgrent(__VA_ARGS__))
#define endhostent(...) (pthread_testcancel(), endhostent(__VA_ARGS__))
#define endnetent(...) (pthread_testcancel(), endnetent(__VA_ARGS__))
#define endprotoent(...) (pthread_testcancel(), endprotoend(__VA_ARGS__))
#define endpwent(...) (pthread_testcancel(), endpwent(__VA_ARGS__))
#define endservent(...) (pthread_testcancel(), endservent(__VA_ARGS__))
#define endutxent(...) (pthread_testcancel(), endutxent(__VA_ARGS__))
#define fclose(...) (pthread_testcancel(), fclose(__VA_ARGS__))
#define fflush(...) (pthread_testcancel(), fflush(__VA_ARGS__))
#define fgetc(...) (pthread_testcancel(), fgetc(__VA_ARGS__))
#define fgetpos(...) (pthread_testcancel(), fgetpos(__VA_ARGS__))
#define fgets(...) (pthread_testcancel(), fgets(__VA_ARGS__))
#define fgetwc(...) (pthread_testcancel(), fgetwc(__VA_ARGS__))
#define fgetws(...) (pthread_testcancel(), fgetws(__VA_ARGS__))
#define fmtmsg(...) (pthread_testcancel(), fmtmsg(__VA_ARGS__))
#define fopen(...) (pthread_testcancel(), fopen(__VA_ARGS__))
#define fpathconf(...) (pthread_testcancel(), fpathconf(__VA_ARGS__))
#define fprintf(...) (pthread_testcancel(), fprintf(__VA_ARGS__))
#define fputc(...) (pthread_testcancel(), fputc(__VA_ARGS__))
#define fputs(...) (pthread_testcancel(), fputs(__VA_ARGS__))
#define fputwc(...) (pthread_testcancel(), fputwc(__VA_ARGS__))
#define fputws(...) (pthread_testcancel(), fputws(__VA_ARGS__))
#define fread(...) (pthread_testcancel(), fread(__VA_ARGS__))
#define freopen(...) (pthread_testcancel(), freopen(__VA_ARGS__))
#define fscanf(...) (pthread_testcancel(), fscanf(__VA_ARGS__))
#define fseek(...) (pthread_testcancel(), fseek(__VA_ARGS__))
#define fseeko(...) (pthread_testcancel(), fseeko(__VA_ARGS__))
#define fsetpos(...) (pthread_testcancel(), fsetpos(__VA_ARGS__))
#define fstat(...) (pthread_testcancel(), fstat(__VA_ARGS__))
#define ftell(...) (pthread_testcancel(), ftell(__VA_ARGS__))
#define ftello(...) (pthread_testcancel(), ftello(__VA_ARGS__))
#define ftw(...) (pthread_testcancel(), ftw(__VA_ARGS__))
#define fwprintf(...) (pthread_testcancel(), fwprintf(__VA_ARGS__))
#define fwrite(...) (pthread_testcancel(), fwrite(__VA_ARGS__))
#define fwscanf(...) (pthread_testcancel(), fwscanf(__VA_ARGS__))
#define getaddrinfo(...) (pthread_testcancel(), getaddrinfo(__VA_ARGS__))
#define getc(...) (pthread_testcancel(), getc(__VA_ARGS__))
#define getc_unlocked(...) (pthread_testcancel(), getc_unlocked(__VA_ARGS__))
#define getchar(...) (pthread_testcancel(), getchar(__VA_ARGS__))
#define getchar_unlocked(...) (pthread_testcancel(), getchar_unlocked(__VA_ARGS__))
#define getcwd(...) (pthread_testcancel(), getcwd(__VA_ARGS__))
#define getdate(...) (pthread_testcancel(), getdate(__VA_ARGS__))
#define getgrent(...) (pthread_testcancel(), getgrent(__VA_ARGS__))
#define getgrgid(...) (pthread_testcancel(), getgrgid(__VA_ARGS__))
#define getgrgid_r(...) (pthread_testcancel(), getgrgid_r(__VA_ARGS__))
#define gergrnam(...) (pthread_testcancel(), getgrnam(__VA_ARGS__))
#define getgrnam_r(...) (pthread_testcancel(), getgrnam_r(__VA_ARGS__))
#define gethostbyaddr(...) (pthread_testcancel(), gethostbyaddr(__VA_ARGS__))
#define gethostbyname(...) (pthread_testcancel(), gethostbyname(__VA_ARGS__))
#define gethostent(...) (pthread_testcancel(), gethostent(__VA_ARGS__))
#define gethostid(...) (pthread_testcancel(), gethostid(__VA_ARGS__))
#define gethostname(...) (pthread_testcancel(), gethostname(__VA_ARGS__))
#define getlogin(...) (pthread_testcancel(), getlogin(__VA_ARGS__))
#define getlogin_r(...) (pthread_testcancel(), getlogin_r(__VA_ARGS__))
#define getnameinfo(...) (pthread_testcancel(), getnameinfo(__VA_ARGS__))
#define getnetbyaddr(...) (pthread_testcancel(), getnetbyaddr(__VA_ARGS__))
#define getnetbyname(...) (pthread_testcancel(), getnetbyname(__VA_ARGS__))
#define getnetent(...) (pthread_testcancel(), getnetent(__VA_ARGS__))
#define getopt(...) (pthread_testcancel(), getopt(__VA_ARGS__))
#define getprotobyname(...) (pthread_testcancel(), getprotobyname(__VA_ARGS__))
#define getprotobynumber(...) (pthread_testcancel(), getprotobynumber(__VA_ARGS__))
#define getprotoent(...) (pthread_testcancel(), getprotoent(__VA_ARGS__))
#define getpwent(...) (pthread_testcancel(), getpwent(__VA_ARGS__))
#define getpwnam(...) (pthread_testcancel(), getpwnam(__VA_ARGS__))
#define getpwnam_r(...) (pthread_testcancel(), getpwnam_r(__VA_ARGS__))
#define getpwuid(...) (pthread_testcancel(), getpwuid(__VA_ARGS__))
#define getpwuid_r(...) (pthread_testcancel(), getpwuid_r(__VA_ARGS__))
#define gets(...) (pthread_testcancel(), gets(__VA_ARGS__))
#define getservbyname(...) (pthread_testcancel(), getservbyname(__VA_ARGS__))
#define getservbyport(...) (pthread_testcancel(), getservbyport(__VA_ARGS__))
#define getservent(...) (pthread_testcancel(), getservent(__VA_ARGS__))
#define getutxent(...) (pthread_testcancel(), getutxent(__VA_ARGS__))
#define getutxid(...) (pthread_testcancel(), getutxid(__VA_ARGS__))
#define getutxline(...) (pthread_testcancel(), getutxline(__VA_ARGS__))
#undef getwc
#define getwc(...) (pthread_testcancel(), getwc(__VA_ARGS__))
#undef getwchar
#define getwchar(...) (pthread_testcancel(), getwchar(__VA_ARGS__))
#define getwd(...) (pthread_testcancel(), getwd(__VA_ARGS__))
#define glob(...) (pthread_testcancel(), glob(__VA_ARGS__))
#define iconv_close(...) (pthread_testcancel(), iconv_close(__VA_ARGS__))
#define iconv_open(...) (pthread_testcancel(), iconv_open(__VA_ARGS__))
#define ioctl(...) (pthread_testcancel(), ioctl(__VA_ARGS__))
#define link(...) (pthread_testcancel(), link(__VA_ARGS__))
#define localtime(...) (pthread_testcancel(), localtime(__VA_ARGS__))
#define localtime_r(...) (pthread_testcancel(), localtime_r(__VA_ARGS__))
#define lseek(...) (pthread_testcancel(), lseek(__VA_ARGS__))
#define lstat(...) (pthread_testcancel(), lstat(__VA_ARGS__))
#define mkstemp(...) (pthread_testcancel(), mkstemp(__VA_ARGS__))
#define nftw(...) (pthread_testcancel(), nftw(__VA_ARGS__))
#define opendir(...) (pthread_testcancel(), opendir(__VA_ARGS__))
#define openlog(...) (pthread_testcancel(), openlog(__VA_ARGS__))
#define pathconf(...) (pthread_testcancel(), pathconf(__VA_ARGS__))
#define pclose(...) (pthread_testcancel(), pclose(__VA_ARGS__))
#define perror(...) (pthread_testcancel(), perror(__VA_ARGS__))
#define popen(...) (pthread_testcancel(), popen(__VA_ARGS__))
#define posix_fadvise(...) (pthread_testcancel(), posix_fadvise(__VA_ARGS__))
#define posix_fallocate(...) (pthread_testcancel(), posix_fallocate(__VA_ARGS__))
#define posix_madvise(...) (pthread_testcancel(), posix_madvise(__VA_ARGS__))
#define posix_openpt(...) (pthread_testcancel(), posix_openpt(__VA_ARGS__))
#define posix_spawn(...) (pthread_testcancel(), posix_spawn(__VA_ARGS__))
#define posix_spawnp(...) (pthread_testcancel(), posix_spawnp(__VA_ARGS__))
#define posix_trace_clear(...) (pthread_testcancel(), posix_trace_clear(__VA_ARGS__))
#define posix_trace_close(...) (pthread_testcancel(), posix_trace_close(__VA_ARGS__))
#define posix_trace_create(...) (pthread_testcancel(), posix_trace_create(__VA_ARGS__))
#define posix_trace_create_withlog(...) (pthread_testcancel(), posix_trace_create_withlog(__VA_ARGS__))
#define posix_trace_eventtypelist_getne(...) (pthread_testcancel(), posix_trace_eventtypelist_getne(__VA_ARGS__))
#define posix_trace_eventtypelist_rewin(...) (pthread_testcancel(), posix_trace_eventtypelist_rewin(__VA_ARGS__))
#define posix_trace_flush(...) (pthread_testcancel(), posix_trace_flush(__VA_ARGS__))
#define posix_trace_get_attr(...) (pthread_testcancel(), posix_trace_get_attr(__VA_ARGS__))
#define posix_trace_get_filter(...) (pthread_testcancel(), posix_trace_get_filter(__VA_ARGS__))
#define posix_trace_get_status(...) (pthread_testcancel(), posix_trace_get_status(__VA_ARGS__))
#define posix_trace_getnext_event(...) (pthread_testcancel(), posix_trace_getnext_event(__VA_ARGS__))
#define posix_trace_open(...) (pthread_testcancel(), posix_trace_open(__VA_ARGS__))
#define posix_trace_rewind(...) (pthread_testcancel(), posix_trace_rewind(__VA_ARGS__))
#define posix_trace_setfilter(...) (pthread_testcancel(), posix_trace_setfilter(__VA_ARGS__))
#define posix_trace_shutdown(...) (pthread_testcancel(), posix_trace_shutdown(__VA_ARGS__))
#define posix_trace_timedgetnext_event(...) (pthread_testcancel(), posix_trace_timedgetnext_event(__VA_ARGS__))
#define posix_typed_mem_open(...) (pthread_testcancel(), posix_typed_mem_open(__VA_ARGS__))
#define printf(...) (pthread_testcancel(), printf(__VA_ARGS__))
#define putc(...) (pthread_testcancel(), putc(__VA_ARGS__))
#define putc_unlocked(...) (pthread_testcancel(), putc_unlocked(__VA_ARGS__))
#define putchar(...) (pthread_testcancel(), putchar(__VA_ARGS__))
#define putchar_unlocked(...) (pthread_testcancel(), putchar_unlocked(__VA_ARGS__))
#define puts(...) (pthread_testcancel(), puts(__VA_ARGS__))
#define pututxline(...) (pthread_testcancel(), pututxline(__VA_ARGS__))
#undef putwc
#define putwc(...) (pthread_testcancel(), putwc(__VA_ARGS__))
#undef putwchar
#define putwchar(...) (pthread_testcancel(), putwchar(__VA_ARGS__))
#define readdir(...) (pthread_testcancel(), readdir(__VA_ARSG__))
#define readdir_r(...) (pthread_testcancel(), readdir_r(__VA_ARGS__))
#define remove(...) (pthread_testcancel(), remove(__VA_ARGS__))
#define rename(...) (pthread_testcancel(), rename(__VA_ARGS__))
#define rewind(...) (pthread_testcancel(), rewind(__VA_ARGS__))
#define rewinddir(...) (pthread_testcancel(), rewinddir(__VA_ARGS__))
#define scanf(...) (pthread_testcancel(), scanf(__VA_ARGS__))
#define seekdir(...) (pthread_testcancel(), seekdir(__VA_ARGS__))
#define semop(...) (pthread_testcancel(), semop(__VA_ARGS__))
#define setgrent(...) (pthread_testcancel(), setgrent(__VA_ARGS__))
#define sethostent(...) (pthread_testcancel(), sethostemt(__VA_ARGS__))
#define setnetent(...) (pthread_testcancel(), setnetent(__VA_ARGS__))
#define setprotoent(...) (pthread_testcancel(), setprotoent(__VA_ARGS__))
#define setpwent(...) (pthread_testcancel(), setpwent(__VA_ARGS__))
#define setservent(...) (pthread_testcancel(), setservent(__VA_ARGS__))
#define setutxent(...) (pthread_testcancel(), setutxent(__VA_ARGS__))
#define stat(...) (pthread_testcancel(), stat(__VA_ARGS__))
#define strerror(...) (pthread_testcancel(), strerror(__VA_ARGS__))
#define strerror_r(...) (pthread_testcancel(), strerror_r(__VA_ARGS__))
#define strftime(...) (pthread_testcancel(), strftime(__VA_ARGS__))
#define symlink(...) (pthread_testcancel(), symlink(__VA_ARGS__))
#define sync(...) (pthread_testcancel(), sync(__VA_ARGS__))
#define syslog(...) (pthread_testcancel(), syslog(__VA_ARGS__))
#define tmpfile(...) (pthread_testcancel(), tmpfile(__VA_ARGS__))
#define tmpnam(...) (pthread_testcancel(), tmpnam(__VA_ARGS__))
#define ttyname(...) (pthread_testcancel(), ttyname(__VA_ARGS__))
#define ttyname_r(...) (pthread_testcancel(), ttyname_r(__VA_ARGS__))
#define tzset(...) (pthread_testcancel(), tzset(__VA_ARGS__))
#define ungetc(...) (pthread_testcancel(), ungetc(__VA_ARGS__))
#define ungetwc(...) (pthread_testcancel(), ungetwc(__VA_ARGS__))
#define unlink(...) (pthread_testcancel(), unlink(__VA_ARGS__))
#define vfprintf(...) (pthread_testcancel(), vfprintf(__VA_ARGS__))
#define vfwprintf(...) (pthread_testcancel(), vfwprintf(__VA_ARGS__))
#define vprintf(...) (pthread_testcancel(), vprintf(__VA_ARGS__))
#define vwprintf(...) (pthread_testcancel(), vwprintf(__VA_ARGS__))
#define wcsftime(...) (pthread_testcancel(), wcsftime(__VA_ARGS__))
#define wordexp(...) (pthread_testcancel(), wordexp(__VA_ARGS__))
#define wprintf(...) (pthread_testcancel(), wprintf(__VA_ARGS__))
#define wscanf(...) (pthread_testcancel(), wscanf(__VA_ARGS__))
*/
#endif
/* WIN_PTHREADS */
libraries/pthreads-2/src/pthread.c
deleted
100644 → 0
View file @
08945326
#include "pthread.h"
volatile
long
_pthread_cancelling
;
int
_pthread_concur
;
/* Will default to zero as needed */
pthread_once_t
_pthread_tls_once
;
DWORD
_pthread_tls
;
/* Note initializer is zero, so this works */
pthread_rwlock_t
_pthread_key_lock
;
long
_pthread_key_max
;
long
_pthread_key_sch
;
void
(
**
_pthread_key_dest
)(
void
*
);
\ No newline at end of file
libraries/pthreads/include/pthread.h
View file @
6cf75568
/* This is an implementation of the threads API of POSIX 1003.1-2001.
/*
*
* Posix Threads library for Microsoft Windows
* --------------------------------------------------------------------------
*
*
*
P
thre
ads-win32 - POSIX Threads Library for Win32
*
Use at own risk,
th
e
re
is no implied warranty to this code.
*
Copyright(C) 1998 John E. Bossom
*
It uses undocumented features of Microsoft Windows that can change
*
Copyright(C) 1999,2005 Pthreads-win32 contributors
*
at any time in the future.
*
*
* Contact Email: rpj@callisto.canberra.edu.au
* (C) 2010 Lockless Inc.
* All rights reserved.
*
*
* The current list of contributors is contained
* Redistribution and use in source and binary forms, with or without modification,
* in the file CONTRIBUTORS included with the source
* are permitted provided that the following conditions are met:
* 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,
* * Redistributions of source code must retain the above copyright notice,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* this list of conditions and the following disclaimer.
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* * Redistributions in binary form must reproduce the above copyright notice,
* Lesser General Public License for more details.
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of Lockless Inc. nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
*
* You should have received a copy of the GNU Lesser General Public
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AN
* License along with this library in the file COPYING.LIB;
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* if not, write to the Free Software Foundation, Inc.,
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
*/
#if !defined( PTHREAD_H )
#define PTHREAD_H
/*
/*
* See the README file for an explanation of the pthreads-win32 version
* You may want to use the MingW64 winpthreads library instead.
* numbering scheme and how the DLL is named etc.
* It is based on this, but adds error checking.
*/
#define PTW32_VERSION 2,8,0,0
#define PTW32_VERSION_STRING "2, 8, 0, 0\0"
/* There are three implementations of cancel cleanup.
* Note that pthread.h is included in both application
* compilation units and also internally for the library.
* The code here and within the library aims to work
* for all reasonable combinations of environments.
*
* The three implementations are:
*
* WIN32 SEH
* C
* C++
*
* Please note that exiting a push/pop block via
* "return", "exit", "break", or "continue" will
* lead to different behaviour amongst applications
* depending upon whether the library was built
* using SEH, C++, or C. For example, a library built
* with SEH will call the cleanup routine, while both
* C++ and C built versions will not.
*/
*/
/*
/*
* Define defaults for cleanup code.
* Version 1.0.1 Released 2 Feb 2012
* Note: Unless the build explicitly defines one of the following, then
* Fixes pthread_barrier_destroy() to wait for threads to exit the barrier.
* we default to standard C style cleanup. This style uses setjmp/longjmp
* in the cancelation and thread exit implementations and therefore won't
* do stack unwinding if linked to applications that have it (e.g.
* C++ apps). This is currently consistent with most/all commercial Unix
* POSIX threads implementations.
*/
*/
#if !defined( __CLEANUP_SEH ) && !defined( __CLEANUP_CXX ) && !defined( __CLEANUP_C )
# define __CLEANUP_C
#endif
#if defined( __CLEANUP_SEH ) && ( !defined( _MSC_VER ) && !defined(PTW32_RC_MSC))
#ifndef WIN_PTHREADS
#error ERROR [__FILE__, line __LINE__]: SEH is not supported for this compiler.
#define WIN_PTHREADS
#endif
/*
* Stop here if we are being included by the resource compiler.
*/
#ifndef RC_INVOKED
#undef PTW32_LEVEL
#include <windows.h>
#include <intrin.h>
#include <setjmp.h>
#include <errno.h>
#include <sys/timeb.h>
#include <process.h>
#if defined(_POSIX_SOURCE)
#define ETIMEDOUT 110
#define PTW32_LEVEL 0
#define ENOTSUP 134
/* Early POSIX */
#endif
#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309
#undef PTW32_LEVEL
#define PTW32_LEVEL 1
/* Include 1b, 1c and 1d */
#endif
#if defined(INCLUDE_NP)
#define PTHREAD_CANCEL_DISABLE 0
#undef PTW32_LEVEL
#define PTHREAD_CANCEL_ENABLE 0x01
#define PTW32_LEVEL 2
/* Include Non-Portable extensions */
#endif
#define PTW32_LEVEL_MAX 3
#define PTHREAD_CANCEL_DEFERRED 0
#define PTHREAD_CANCEL_ASYNCHRONOUS 0x02
#if !defined(PTW32_LEVEL)
#define PTHREAD_CREATE_JOINABLE 0
#define PTW32_LEVEL PTW32_LEVEL_MAX
#define PTHREAD_CREATE_DETACHED 0x04
/* Include everything */
#endif
#ifdef _UWIN
#define PTHREAD_EXPLICT_SCHED 0
# define HAVE_STRUCT_TIMESPEC 1
#define PTHREAD_INHERIT_SCHED 0x08
# define HAVE_SIGNAL_H 1
# undef HAVE_CONFIG_H
# pragma comment(lib, "pthread")
#endif
/*
#define PTHREAD_SCOPE_PROCESS 0
* -------------------------------------------------------------
#define PTHREAD_SCOPE_SYSTEM 0x10
*
*
* Module: pthread.h
*
* Purpose:
* Provides an implementation of PThreads based upon the
* standard:
*
* POSIX 1003.1-2001
* and
* The Single Unix Specification version 3
*
* (these two are equivalent)
*
* in order to enhance code portability between Windows,
* various commercial Unix implementations, and Linux.
*
* See the ANNOUNCE file for a full list of conforming
* routines and defined constants, and a list of missing
* routines and constants not defined in this implementation.
*
* Authors:
* There have been many contributors to this library.
* The initial implementation was contributed by
* John Bossom, and several others have provided major
* sections or revisions of parts of the implementation.
* Often significant effort has been contributed to
* find and fix important bugs and other problems to
* improve the reliability of the library, which sometimes
* is not reflected in the amount of code which changed as
* result.
* As much as possible, the contributors are acknowledged
* in the ChangeLog file in the source code distribution
* where their changes are noted in detail.
*
* Contributors are listed in the CONTRIBUTORS file.
*
* As usual, all bouquets go to the contributors, and all
* brickbats go to the project maintainer.
*
* Maintainer:
* The code base for this project is coordinated and
* eventually pre-tested, packaged, and made available by
*
* Ross Johnson <rpj@callisto.canberra.edu.au>
*
* QA Testers:
* Ultimately, the library is tested in the real world by
* a host of competent and demanding scientists and
* engineers who report bugs and/or provide solutions
* which are then fixed or incorporated into subsequent
* versions of the library. Each time a bug is fixed, a
* test case is written to prove the fix and ensure
* that later changes to the code don't reintroduce the
* same error. The number of test cases is slowly growing
* and therefore so is the code reliability.
*
* Compliance:
* See the file ANNOUNCE for the list of implemented
* and not-implemented routines and defined options.
* Of course, these are all defined is this file as well.
*
* Web site:
* The source code and other information about this library
* are available from
*
* http://sources.redhat.com/pthreads-win32/
*
* -------------------------------------------------------------
*/
/* Try to avoid including windows.h */
#define PTHREAD_DEFAULT_ATTR (PTHREAD_CANCEL_ENABLE)
#if defined(__MINGW32__) && defined(__cplusplus)
#define PTW32_INCLUDE_WINDOWS_H
#endif
#ifdef PTW32_INCLUDE_WINDOWS_H
#define PTHREAD_CANCELED ((void *) 0xDEADBEEF)
#include <windows.h>
#define PTHREAD_ONCE_INIT 0
#define PTHREAD_MUTEX_INITIALIZER {(void*)-1,-1,0,0,0,0}
#define PTHREAD_RWLOCK_INITIALIZER {0}
#define PTHREAD_COND_INITIALIZER {0}
#define PTHREAD_BARRIER_INITIALIZER \
{0,0,PTHREAD_MUTEX_INITIALIZER,PTHREAD_COND_INITIALIZER}
#define PTHREAD_SPINLOCK_INITIALIZER 0
#define PTHREAD_DESTRUCTOR_ITERATIONS 256
#define PTHREAD_KEYS_MAX (1<<20)
#define PTHREAD_MUTEX_NORMAL 0
#define PTHREAD_MUTEX_ERRORCHECK 1
#define PTHREAD_MUTEX_RECURSIVE 2
#define PTHREAD_MUTEX_DEFAULT 3
#define PTHREAD_MUTEX_SHARED 4
#define PTHREAD_MUTEX_PRIVATE 0
#define PTHREAD_PRIO_NONE 0
#define PTHREAD_PRIO_INHERIT 8
#define PTHREAD_PRIO_PROTECT 16
#define PTHREAD_PRIO_MULT 32
#define PTHREAD_PROCESS_SHARED 0
#define PTHREAD_PROCESS_PRIVATE 1
#define PTHREAD_BARRIER_SERIAL_THREAD 1
#ifdef _X86_
#define INTERLOCKED_COMPARE_EXCHANGE(destination, exchange, comparand) _InterlockedCompareExchange((volatile long*) destination, (long) exchange, (long) comparand)
#else
#define INTERLOCKED_COMPARE_EXCHANGE(destination, exchange, comparand) _InterlockedCompareExchangePointer((volatile PVOID*) destination, (void*) exchange, (void*) comparand)
#endif
#endif
#if defined(_MSC_VER) && _MSC_VER < 1300 || defined(__DMC__)
#if defined(PTHREAD_BUILDING_SHARED_LIBRARY)
/*
#define PTHREAD_EXPORT __declspec(dllexport)
* VC++6.0 or early compiler's header has no DWORD_PTR type.
#elif defined(PTHREAD_BUILDING_STATIC_LIBRARY)
*/
#define PTHREAD_EXPORT
typedef
unsigned
long
DWORD_PTR
;
#else
#define PTHREAD_EXPORT __declspec(dllimport)
#endif
#endif
/*
* -----------------
* autoconf switches
* -----------------
*/
#if HAVE_CONFIG_H
#include "config.h"
#endif
/* HAVE_CONFIG_H */
#ifndef NEED_FTIME
/* Windows doesn't have this, so declare it ourselves. */
#include <time.h>
struct
timespec
#else
/* NEED_FTIME */
{
/* use native WIN32 time API */
/* long long in windows is the same as long in unix for 64bit */
#endif
/* NEED_FTIME */
long
long
tv_sec
;
long
long
tv_nsec
;
};
#if HAVE_SIGNAL_H
typedef
struct
_pthread_cleanup
_pthread_cleanup
;
#include <signal.h>
struct
_pthread_cleanup
#endif
/* HAVE_SIGNAL_H */
{
void
(
*
func
)(
void
*
);
void
*
arg
;
_pthread_cleanup
*
next
;
};
#include <setjmp.h>
struct
_pthread_v
#include <limits.h>
{
void
*
ret_arg
;
void
*
(
*
func
)(
void
*
);
_pthread_cleanup
*
clean
;
HANDLE
h
;
int
cancelled
;
unsigned
p_state
;
int
keymax
;
void
**
keyval
;
jmp_buf
jb
;
};
/*
typedef
struct
_pthread_v
*
pthread_t
;
* Boolean values to make us independent of system includes.
*/
typedef
struct
pthread_barrier_t
pthread_barrier_t
;
enum
{
struct
pthread_barrier_t
PTW32_FALSE
=
0
,
{
PTW32_TRUE
=
(
!
PTW32_FALSE
)
int
count
;
int
total
;
CRITICAL_SECTION
m
;
CONDITION_VARIABLE
cv
;
};
};
/*
typedef
struct
pthread_attr_t
pthread_attr_t
;
* This is a duplicate of what is in the autoconf config.h,
struct
pthread_attr_t
* which is only used when building the pthread-win32 libraries.
{
*/
unsigned
p_state
;
void
*
stack
;
size_t
s_size
;
};
#ifndef PTW32_CONFIG_H
typedef
long
pthread_once_t
;
# if defined(WINCE)
typedef
unsigned
pthread_mutexattr_t
;
# define NEED_ERRNO
typedef
SRWLOCK
pthread_rwlock_t
;
# define NEED_SEM
typedef
CRITICAL_SECTION
pthread_mutex_t
;
# endif
typedef
unsigned
pthread_key_t
;
# if defined(_UWIN) || defined(__MINGW32__)
typedef
void
*
pthread_barrierattr_t
;
# define HAVE_MODE_T
typedef
long
pthread_spinlock_t
;
# endif
typedef
int
pthread_condattr_t
;
#endif
typedef
CONDITION_VARIABLE
pthread_cond_t
;
typedef
int
pthread_rwlockattr_t
;
/*
extern
PTHREAD_EXPORT
volatile
long
_pthread_cancelling
;
*
*/
#if PTW32_LEVEL >= PTW32_LEVEL_MAX
extern
PTHREAD_EXPORT
int
_pthread_concur
;
#ifdef NEED_ERRNO
#include "need_errno.h"
#else
#include <errno.h>
#endif
#endif
/* PTW32_LEVEL >= PTW32_LEVEL_MAX */
/*
/* Will default to zero as needed */
* Several systems don't define some error numbers.
extern
PTHREAD_EXPORT
pthread_once_t
_pthread_tls_once
;
*/
extern
PTHREAD_EXPORT
DWORD
_pthread_tls
;
#ifndef ENOTSUP
# define ENOTSUP 48
/* This is the value in Solaris. */
#endif
#ifndef ETIMEDOUT
/* Note initializer is zero, so this works */
# define ETIMEDOUT 10060
/* This is the value in winsock.h. */
extern
PTHREAD_EXPORT
pthread_rwlock_t
_pthread_key_lock
;
#endif
extern
PTHREAD_EXPORT
long
_pthread_key_max
;
extern
PTHREAD_EXPORT
long
_pthread_key_sch
;
extern
PTHREAD_EXPORT
void
(
**
_pthread_key_dest
)(
void
*
);
#ifndef ENOSYS
# define ENOSYS 140
/* Semi-arbitrary value */
#endif
#ifndef EDEADLK
#define pthread_cleanup_push(F, A)\
# ifdef EDEADLOCK
{\
# define EDEADLK EDEADLOCK
const _pthread_cleanup _pthread_cup = {(F), (A), pthread_self()->clean};\
# else
_ReadWriteBarrier();\
# define EDEADLK 36
/* This is the value in MSVC. */
pthread_self()->clean = (_pthread_cleanup *) &_pthread_cup;\
# endif
_ReadWriteBarrier()
#endif
#include <sched.h>
/* Note that if async cancelling is used, then there is a race here */
#define pthread_cleanup_pop(E)\
(pthread_self()->clean = _pthread_cup.next, (E?_pthread_cup.func(_pthread_cup.arg):0));}
/*
static
void
_pthread_once_cleanup
(
pthread_once_t
*
o
)
* To avoid including windows.h we define only those things that we
{
* actually need from it.
*
o
=
0
;
*/
}
#ifndef PTW32_INCLUDE_WINDOWS_H
#ifndef HANDLE
static
pthread_t
pthread_self
(
void
);
# define PTW32__HANDLE_DEF
static
int
pthread_once
(
pthread_once_t
*
o
,
void
(
*
func
)(
void
))
# define HANDLE void *
{
#endif
long
state
=
*
o
;
#ifndef DWORD
# define PTW32__DWORD_DEF
_ReadWriteBarrier
();
# define DWORD unsigned long
#endif
while
(
state
!=
1
)
{
if
(
!
state
)
{
if
(
!
_InterlockedCompareExchange
(
o
,
2
,
0
))
{
/* Success */
#ifdef __cplusplus
pthread_cleanup_push
(
reinterpret_cast
<
void
(
__cdecl
*
)(
void
*
)
>
(
_pthread_once_cleanup
),
o
);
#else
pthread_cleanup_push
(
_pthread_once_cleanup
,
o
);
#endif
#endif
func
();
pthread_cleanup_pop
(
0
);
#ifndef HAVE_STRUCT_TIMESPEC
/* Mark as done */
#define HAVE_STRUCT_TIMESPEC 1
*
o
=
1
;
struct
timespec
{
long
tv_sec
;
long
tv_nsec
;
};
#endif
/* HAVE_STRUCT_TIMESPEC */
#ifndef SIG_BLOCK
return
0
;
#define SIG_BLOCK 0
}
#endif
/* SIG_BLOCK */
}
#ifndef SIG_UNBLOCK
YieldProcessor
();
#define SIG_UNBLOCK 1
#endif
/* SIG_UNBLOCK */
#ifndef SIG_SETMASK
_ReadWriteBarrier
();
#define SIG_SETMASK 2
#endif
/* SIG_SETMASK */
#ifdef __cplusplus
state
=
*
o
;
extern
"C"
}
/* Done */
return
0
;
}
static
int
_pthread_once_raw
(
pthread_once_t
*
o
,
void
(
*
func
)(
void
))
{
{
#endif
/* __cplusplus */
long
state
=
*
o
;
/*
_ReadWriteBarrier
();
* -------------------------------------------------------------
*
* POSIX 1003.1-2001 Options
* =========================
*
* Options are normally set in <unistd.h>, which is not provided
* with pthreads-win32.
*
* For conformance with the Single Unix Specification (version 3), all of the
* options below are defined, and have a value of either -1 (not supported)
* or 200112L (supported).
*
* These options can neither be left undefined nor have a value of 0, because
* either indicates that sysconf(), which is not implemented, may be used at
* runtime to check the status of the option.
*
* _POSIX_THREADS (== 200112L)
* If == 200112L, you can use threads
*
* _POSIX_THREAD_ATTR_STACKSIZE (== 200112L)
* If == 200112L, you can control the size of a thread's
* stack
* pthread_attr_getstacksize
* pthread_attr_setstacksize
*
* _POSIX_THREAD_ATTR_STACKADDR (== -1)
* If == 200112L, you can allocate and control a thread's
* stack. If not supported, the following functions
* will return ENOSYS, indicating they are not
* supported:
* pthread_attr_getstackaddr
* pthread_attr_setstackaddr
*
* _POSIX_THREAD_PRIORITY_SCHEDULING (== -1)
* If == 200112L, you can use realtime scheduling.
* This option indicates that the behaviour of some
* implemented functions conforms to the additional TPS
* requirements in the standard. E.g. rwlocks favour
* writers over readers when threads have equal priority.
*
* _POSIX_THREAD_PRIO_INHERIT (== -1)
* If == 200112L, you can create priority inheritance
* mutexes.
* pthread_mutexattr_getprotocol +
* pthread_mutexattr_setprotocol +
*
* _POSIX_THREAD_PRIO_PROTECT (== -1)
* If == 200112L, you can create priority ceiling mutexes
* Indicates the availability of:
* pthread_mutex_getprioceiling
* pthread_mutex_setprioceiling
* pthread_mutexattr_getprioceiling
* pthread_mutexattr_getprotocol +
* pthread_mutexattr_setprioceiling
* pthread_mutexattr_setprotocol +
*
* _POSIX_THREAD_PROCESS_SHARED (== -1)
* If set, you can create mutexes and condition
* variables that can be shared with another
* process.If set, indicates the availability
* of:
* pthread_mutexattr_getpshared
* pthread_mutexattr_setpshared
* pthread_condattr_getpshared
* pthread_condattr_setpshared
*
* _POSIX_THREAD_SAFE_FUNCTIONS (== 200112L)
* If == 200112L you can use the special *_r library
* functions that provide thread-safe behaviour
*
* _POSIX_READER_WRITER_LOCKS (== 200112L)
* If == 200112L, you can use read/write locks
*
* _POSIX_SPIN_LOCKS (== 200112L)
* If == 200112L, you can use spin locks
*
* _POSIX_BARRIERS (== 200112L)
* If == 200112L, you can use barriers
*
* + These functions provide both 'inherit' and/or
* 'protect' protocol, based upon these macro
* settings.
*
* -------------------------------------------------------------
*/
/*
while
(
state
!=
1
)
* POSIX Options
{
*/
if
(
!
state
)
#undef _POSIX_THREADS
{
#define _POSIX_THREADS 200112L
if
(
!
_InterlockedCompareExchange
(
o
,
2
,
0
))
{
/* Success */
func
();
/* Mark as done */
*
o
=
1
;
#undef _POSIX_READER_WRITER_LOCKS
return
0
;
#define _POSIX_READER_WRITER_LOCKS 200112L
}
}
#undef _POSIX_SPIN_LOCKS
YieldProcessor
();
#define _POSIX_SPIN_LOCKS 200112L
#undef _POSIX_BARRIERS
_ReadWriteBarrier
();
#define _POSIX_BARRIERS 200112L
#undef _POSIX_THREAD_SAFE_FUNCTIONS
state
=
*
o
;
#define _POSIX_THREAD_SAFE_FUNCTIONS 200112L
}
#undef _POSIX_THREAD_ATTR_STACKSIZE
/* Done */
#define _POSIX_THREAD_ATTR_STACKSIZE 200112L
return
0
;
}
/*
static
int
pthread_mutex_lock
(
pthread_mutex_t
*
m
)
* The following options are not supported
{
*/
EnterCriticalSection
(
m
);
#undef _POSIX_THREAD_ATTR_STACKADDR
return
0
;
#define _POSIX_THREAD_ATTR_STACKADDR -1
}
#undef _POSIX_THREAD_PRIO_INHERIT
static
int
pthread_mutex_unlock
(
pthread_mutex_t
*
m
)
#define _POSIX_THREAD_PRIO_INHERIT -1
{
LeaveCriticalSection
(
m
);
return
0
;
}
#undef _POSIX_THREAD_PRIO_PROTECT
static
int
pthread_mutex_trylock
(
pthread_mutex_t
*
m
)
#define _POSIX_THREAD_PRIO_PROTECT -1
{
return
TryEnterCriticalSection
(
m
)
?
0
:
EBUSY
;
}
/* TPS is not fully supported. */
static
int
pthread_mutex_init
(
pthread_mutex_t
*
m
,
pthread_mutexattr_t
*
a
)
#undef _POSIX_THREAD_PRIORITY_SCHEDULING
{
#define _POSIX_THREAD_PRIORITY_SCHEDULING -1
(
void
)
a
;
InitializeCriticalSection
(
m
);
#undef _POSIX_THREAD_PROCESS_SHARED
return
0
;
#define _POSIX_THREAD_PROCESS_SHARED -1
}
static
int
pthread_mutex_destroy
(
pthread_mutex_t
*
m
)
{
DeleteCriticalSection
(
m
);
return
0
;
}
/*
#define pthread_mutex_getprioceiling(M, P) ENOTSUP
* POSIX 1003.1-2001 Limits
#define pthread_mutex_setprioceiling(M, P) ENOTSUP
* ===========================
*
* These limits are normally set in <limits.h>, which is not provided with
* pthreads-win32.
*
* PTHREAD_DESTRUCTOR_ITERATIONS
* Maximum number of attempts to destroy
* a thread's thread-specific data on
* termination (must be at least 4)
*
* PTHREAD_KEYS_MAX
* Maximum number of thread-specific data keys
* available per process (must be at least 128)
*
* PTHREAD_STACK_MIN
* Minimum supported stack size for a thread
*
* PTHREAD_THREADS_MAX
* Maximum number of threads supported per
* process (must be at least 64).
*
* SEM_NSEMS_MAX
* The maximum number of semaphores a process can have.
* (must be at least 256)
*
* SEM_VALUE_MAX
* The maximum value a semaphore can have.
* (must be at least 32767)
*
*/
#undef _POSIX_THREAD_DESTRUCTOR_ITERATIONS
#define _POSIX_THREAD_DESTRUCTOR_ITERATIONS 4
#undef PTHREAD_DESTRUCTOR_ITERATIONS
static
int
pthread_equal
(
pthread_t
t1
,
pthread_t
t2
)
#define PTHREAD_DESTRUCTOR_ITERATIONS _POSIX_THREAD_DESTRUCTOR_ITERATIONS
{
return
t1
==
t2
;
}
#undef _POSIX_THREAD_KEYS_MAX
static
void
pthread_testcancel
(
void
);
#define _POSIX_THREAD_KEYS_MAX 128
#undef PTHREAD_KEYS_MAX
static
int
pthread_rwlock_init
(
pthread_rwlock_t
*
l
,
pthread_rwlockattr_t
*
a
)
#define PTHREAD_KEYS_MAX _POSIX_THREAD_KEYS_MAX
{
(
void
)
a
;
InitializeSRWLock
(
l
);
#undef PTHREAD_STACK_MIN
return
0
;
#define PTHREAD_STACK_MIN 0
}
#undef _POSIX_THREAD_THREADS_MAX
static
int
pthread_rwlock_destroy
(
pthread_rwlock_t
*
l
)
#define _POSIX_THREAD_THREADS_MAX 64
{
(
void
)
*
l
;
return
0
;
}
/* Arbitrary value */
static
int
pthread_rwlock_rdlock
(
pthread_rwlock_t
*
l
)
#undef PTHREAD_THREADS_MAX
{
#define PTHREAD_THREADS_MAX 2019
pthread_testcancel
();
AcquireSRWLockShared
(
l
);
#undef _POSIX_SEM_NSEMS_MAX
return
0
;
#define _POSIX_SEM_NSEMS_MAX 256
}
/* Arbitrary value */
static
int
pthread_rwlock_wrlock
(
pthread_rwlock_t
*
l
)
#undef SEM_NSEMS_MAX
{
#define SEM_NSEMS_MAX 1024
pthread_testcancel
();
AcquireSRWLockExclusive
(
l
);
#undef _POSIX_SEM_VALUE_MAX
return
0
;
#define _POSIX_SEM_VALUE_MAX 32767
}
#undef SEM_VALUE_MAX
static
void
pthread_tls_init
(
void
)
#define SEM_VALUE_MAX INT_MAX
{
_pthread_tls
=
TlsAlloc
();
/* Cannot continue if out of indexes */
if
(
_pthread_tls
==
TLS_OUT_OF_INDEXES
)
abort
();
}
#if __GNUC__ && ! defined (__declspec
)
static
int
pthread_rwlock_unlock
(
pthread_rwlock_t
*
l
)
# error Please upgrade your GNU compiler to one that supports __declspec.
{
#endif
void
*
state
=
*
(
void
**
)
l
;
/*
if
(
state
==
(
void
*
)
1
)
* When building the DLL code, you should define PTW32_BUILD so that
{
* the variables/functions are exported correctly. When using the DLL,
/* Known to be an exclusive lock */
* do NOT define PTW32_BUILD, and then the variables/functions will
ReleaseSRWLockExclusive
(
l
);
* be imported correctly.
}
*/
else
#ifndef PTW32_STATIC_LIB
{
# ifdef PTW32_BUILD
/* A shared unlock will work */
# define PTW32_DLLPORT __declspec (dllexport)
ReleaseSRWLockShared
(
l
);
# else
}
# define PTW32_DLLPORT __declspec (dllimport)
# endif
#else
# define PTW32_DLLPORT
#endif
/*
return
0
;
* The Open Watcom C/C++ compiler uses a non-standard calling convention
}
* that passes function args in registers unless __cdecl is explicitly specified
* in exposed function prototypes.
*
* We force all calls to cdecl even though this could slow Watcom code down
* slightly. If you know that the Watcom compiler will be used to build both
* the DLL and application, then you can probably define this as a null string.
* Remember that pthread.h (this file) is used for both the DLL and application builds.
*/
#define PTW32_CDECL __cdecl
#if defined(_UWIN) && PTW32_LEVEL >= PTW32_LEVEL_MAX
static
void
_pthread_cleanup_dest
(
pthread_t
t
)
# include <sys/types.h>
{
#else
int
i
,
j
;
/*
* Generic handle type - intended to extend uniqueness beyond
* that available with a simple pointer. It should scale for either
* IA-32 or IA-64.
*/
typedef
struct
{
void
*
p
;
/* Pointer to actual object */
unsigned
int
x
;
/* Extra information - reuse count etc */
}
ptw32_handle_t
;
typedef
ptw32_handle_t
pthread_t
;
typedef
struct
pthread_attr_t_
*
pthread_attr_t
;
typedef
struct
pthread_once_t_
pthread_once_t
;
typedef
struct
pthread_key_t_
*
pthread_key_t
;
typedef
struct
pthread_mutex_t_
*
pthread_mutex_t
;
typedef
struct
pthread_mutexattr_t_
*
pthread_mutexattr_t
;
typedef
struct
pthread_cond_t_
*
pthread_cond_t
;
typedef
struct
pthread_condattr_t_
*
pthread_condattr_t
;
#endif
typedef
struct
pthread_rwlock_t_
*
pthread_rwlock_t
;
typedef
struct
pthread_rwlockattr_t_
*
pthread_rwlockattr_t
;
typedef
struct
pthread_spinlock_t_
*
pthread_spinlock_t
;
typedef
struct
pthread_barrier_t_
*
pthread_barrier_t
;
typedef
struct
pthread_barrierattr_t_
*
pthread_barrierattr_t
;
/*
for
(
j
=
0
;
j
<
PTHREAD_DESTRUCTOR_ITERATIONS
;
j
++
)
* ====================
{
* ====================
int
flag
=
0
;
* POSIX Threads
* ====================
* ====================
*/
enum
{
for
(
i
=
0
;
i
<
t
->
keymax
;
i
++
)
/*
{
* pthread_attr_{get,set}detachstate
void
*
val
=
t
->
keyval
[
i
];
*/
PTHREAD_CREATE_JOINABLE
=
0
,
/* Default */
PTHREAD_CREATE_DETACHED
=
1
,
/*
if
(
val
)
* pthread_attr_{get,set}inheritsched
{
*/
pthread_rwlock_rdlock
(
&
_pthread_key_lock
);
PTHREAD_INHERIT_SCHED
=
0
,
if
((
uintptr_t
)
_pthread_key_dest
[
i
]
>
1
)
PTHREAD_EXPLICIT_SCHED
=
1
,
/* Default */
{
/* Call destructor */
t
->
keyval
[
i
]
=
NULL
;
_pthread_key_dest
[
i
](
val
);
flag
=
1
;
}
pthread_rwlock_unlock
(
&
_pthread_key_lock
);
}
}
/*
/* Nothing to do? */
* pthread_{get,set}scope
if
(
!
flag
)
return
;
*/
}
PTHREAD_SCOPE_PROCESS
=
0
,
}
PTHREAD_SCOPE_SYSTEM
=
1
,
/* Default */
/*
static
pthread_t
pthread_self
(
void
)
* pthread_setcancelstate paramters
{
*/
pthread_t
t
;
PTHREAD_CANCEL_ENABLE
=
0
,
/* Default */
PTHREAD_CANCEL_DISABLE
=
1
,
/*
_pthread_once_raw
(
&
_pthread_tls_once
,
pthread_tls_init
);
* pthread_setcanceltype parameters
*/
PTHREAD_CANCEL_ASYNCHRONOUS
=
0
,
PTHREAD_CANCEL_DEFERRED
=
1
,
/* Default */
/*
t
=
(
pthread_t
)
TlsGetValue
(
_pthread_tls
);
* pthread_mutexattr_{get,set}pshared
* pthread_condattr_{get,set}pshared
*/
PTHREAD_PROCESS_PRIVATE
=
0
,
PTHREAD_PROCESS_SHARED
=
1
,
/*
/* Main thread? */
* pthread_barrier_wait
if
(
!
t
)
*/
{
PTHREAD_BARRIER_SERIAL_THREAD
=
-
1
t
=
(
pthread_t
)
malloc
(
sizeof
(
struct
_pthread_v
));
};
/*
/* If cannot initialize main thread, then the only thing we can do is abort */
* ====================
if
(
!
t
)
abort
();
* ====================
* Cancelation
* ====================
* ====================
*/
#define PTHREAD_CANCELED ((void *) -1)
t
->
ret_arg
=
NULL
;
t
->
func
=
NULL
;
t
->
clean
=
NULL
;
t
->
cancelled
=
0
;
t
->
p_state
=
PTHREAD_DEFAULT_ATTR
;
t
->
keymax
=
0
;
t
->
keyval
=
NULL
;
t
->
h
=
GetCurrentThread
();
/*
/* Save for later */
* ====================
TlsSetValue
(
_pthread_tls
,
t
);
* ====================
* Once Key
if
(
setjmp
(
t
->
jb
))
* ====================
{
* ====================
/* Make sure we free ourselves if we are detached */
*/
if
(
!
t
->
h
)
free
(
t
);
#define PTHREAD_ONCE_INIT { PTW32_FALSE, 0, 0, 0}
/* Time to die */
_endthreadex
(
0
);
}
}
return
t
;
}
struct
pthread_once_t_
static
int
pthread_rwlock_tryrdlock
(
pthread_rwlock_t
*
l
)
{
{
int
done
;
/* indicates if user function has been executed */
/* Get the current state of the lock */
void
*
lock
;
void
*
state
=
*
(
void
**
)
l
;
int
reserved1
;
int
reserved2
;
};
if
(
!
state
)
{
/* Unlocked to locked */
if
(
!
INTERLOCKED_COMPARE_EXCHANGE
((
volatile
PVOID
*
)
l
,
(
void
*
)
0x11
,
NULL
))
return
0
;
return
EBUSY
;
}
/*
/* A single writer exists */
* ====================
if
(
state
==
(
void
*
)
1
)
return
EBUSY
;
* ====================
* Object initialisers
* ====================
* ====================
*/
#define PTHREAD_MUTEX_INITIALIZER ((pthread_mutex_t) -1)
#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER ((pthread_mutex_t) -2)
#define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER ((pthread_mutex_t) -3)
/*
/* Multiple writers exist? */
* Compatibility with LinuxThreads
if
((
uintptr_t
)
state
&
14
)
return
EBUSY
;
*/
#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP PTHREAD_RECURSIVE_MUTEX_INITIALIZER
#define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP PTHREAD_ERRORCHECK_MUTEX_INITIALIZER
#define PTHREAD_COND_INITIALIZER ((pthread_cond_t) -1)
if
((
void
*
)
INTERLOCKED_COMPARE_EXCHANGE
((
volatile
PVOID
*
)
l
,
(
void
*
)
((
uintptr_t
)
state
+
16
),
state
)
==
state
)
return
0
;
#define PTHREAD_RWLOCK_INITIALIZER ((pthread_rwlock_t) -1)
return
EBUSY
;
}
#define PTHREAD_SPINLOCK_INITIALIZER ((pthread_spinlock_t) -1)
static
int
pthread_rwlock_trywrlock
(
pthread_rwlock_t
*
l
)
{
/* Try to grab lock if it has no users */
if
(
!
INTERLOCKED_COMPARE_EXCHANGE
((
volatile
PVOID
*
)
l
,
(
void
*
)
1
,
NULL
))
return
0
;
return
EBUSY
;
}
/*
static
unsigned
long
long
_pthread_time_in_ms
(
void
)
* Mutex types.
{
*/
struct
__timeb64
tb
;
enum
{
/* Compatibility with LinuxThreads */
PTHREAD_MUTEX_FAST_NP
,
PTHREAD_MUTEX_RECURSIVE_NP
,
PTHREAD_MUTEX_ERRORCHECK_NP
,
PTHREAD_MUTEX_TIMED_NP
=
PTHREAD_MUTEX_FAST_NP
,
PTHREAD_MUTEX_ADAPTIVE_NP
=
PTHREAD_MUTEX_FAST_NP
,
/* For compatibility with POSIX */
PTHREAD_MUTEX_NORMAL
=
PTHREAD_MUTEX_FAST_NP
,
PTHREAD_MUTEX_RECURSIVE
=
PTHREAD_MUTEX_RECURSIVE_NP
,
PTHREAD_MUTEX_ERRORCHECK
=
PTHREAD_MUTEX_ERRORCHECK_NP
,
PTHREAD_MUTEX_DEFAULT
=
PTHREAD_MUTEX_NORMAL
};
_ftime64
(
&
tb
);
typedef
struct
ptw32_cleanup_t
ptw32_cleanup_t
;
return
tb
.
time
*
1000
+
tb
.
millitm
;
}
#if defined(_MSC_VER
)
static
unsigned
long
long
_pthread_time_in_ms_from_timespec
(
const
struct
timespec
*
ts
)
/* Disable MSVC 'anachronism used' warning */
{
#pragma warning( disable : 4229 )
unsigned
long
long
t
=
ts
->
tv_sec
*
1000
;
#endif
t
+=
ts
->
tv_nsec
/
1000000
;
typedef
void
(
*
PTW32_CDECL
ptw32_cleanup_callback_t
)(
void
*
);
return
t
;
}
#if defined(_MSC_VER)
static
unsigned
long
long
_pthread_rel_time_in_ms
(
const
struct
timespec
*
ts
)
#pragma warning( default : 4229 )
{
#endif
unsigned
long
long
t1
=
_pthread_time_in_ms_from_timespec
(
ts
);
unsigned
long
long
t2
=
_pthread_time_in_ms
();
/* Prevent underflow */
if
(
t1
<
t2
)
return
0
;
return
t1
-
t2
;
}
st
ruct
ptw32_cleanup_t
st
atic
int
pthread_rwlock_timedrdlock
(
pthread_rwlock_t
*
l
,
const
struct
timespec
*
ts
)
{
{
ptw32_cleanup_callback_t
routine
;
unsigned
long
long
ct
=
_pthread_time_in_ms
();
void
*
arg
;
unsigned
long
long
t
=
_pthread_time_in_ms_from_timespec
(
ts
);
struct
ptw32_cleanup_t
*
prev
;
};
#ifdef __CLEANUP_SEH
pthread_testcancel
();
/*
* WIN32 SEH version of cancel cleanup.
*/
#define pthread_cleanup_push( _rout, _arg ) \
/* Use a busy-loop */
{ \
while
(
1
)
ptw32_cleanup_t _cleanup; \
{
\
/* Try to grab lock */
_cleanup.routine = (ptw32_cleanup_callback_t)(_rout); \
if
(
!
pthread_rwlock_tryrdlock
(
l
))
return
0
;
_cleanup.arg = (_arg); \
__try \
/* Get current time */
{ \
ct
=
_pthread_time_in_ms
();
#define pthread_cleanup_pop( _execute ) \
/* Have we waited long enough? */
} \
if
(
ct
>
t
)
return
ETIMEDOUT
;
__finally \
{ \
if( _execute || AbnormalTermination()) \
{ \
(*(_cleanup.routine))( _cleanup.arg ); \
} \
} \
}
}
}
#else
/* __CLEANUP_SEH */
static
int
pthread_rwlock_timedwrlock
(
pthread_rwlock_t
*
l
,
const
struct
timespec
*
ts
)
{
unsigned
long
long
ct
=
_pthread_time_in_ms
();
unsigned
long
long
t
=
_pthread_time_in_ms_from_timespec
(
ts
);
#ifdef __CLEANUP_C
pthread_testcancel
();
/*
/* Use a busy-loop */
* C implementation of PThreads cancel cleanup
while
(
1
)
*/
{
/* Try to grab lock */
if
(
!
pthread_rwlock_trywrlock
(
l
))
return
0
;
#define pthread_cleanup_push( _rout, _arg ) \
/* Get current time */
{ \
ct
=
_pthread_time_in_ms
();
ptw32_cleanup_t _cleanup; \
\
ptw32_push_cleanup( &_cleanup, (ptw32_cleanup_callback_t) (_rout), (_arg) ); \
#define pthread_cleanup_pop( _execute ) \
/* Have we waited long enough? */
(void) ptw32_pop_cleanup( _execute ); \
if
(
ct
>
t
)
return
ETIMEDOUT
;
}
}
}
#else
/* __CLEANUP_C */
static
int
pthread_get_concurrency
(
int
*
val
)
{
*
val
=
_pthread_concur
;
return
0
;
}
#ifdef __CLEANUP_CXX
static
int
pthread_set_concurrency
(
int
val
)
{
_pthread_concur
=
val
;
return
0
;
}
/*
#define pthread_getschedparam(T, P, S) ENOTSUP
* C++ version of cancel cleanup.
#define pthread_setschedparam(T, P, S) ENOTSUP
* - John E. Bossom.
#define pthread_getcpuclockid(T, C) ENOTSUP
*/
class
PThreadCleanup
{
static
int
pthread_exit
(
void
*
res
)
/*
{
* PThreadCleanup
pthread_t
t
=
pthread_self
();
*
* Purpose
* This class is a C++ helper class that is
* used to implement pthread_cleanup_push/
* pthread_cleanup_pop.
* The destructor of this class automatically
* pops the pushed cleanup routine regardless
* of how the code exits the scope
* (i.e. such as by an exception)
*/
ptw32_cleanup_callback_t
cleanUpRout
;
void
*
obj
;
int
executeIt
;
public:
PThreadCleanup
()
:
cleanUpRout
(
0
),
obj
(
0
),
executeIt
(
0
)
/*
* No cleanup performed
*/
{
}
PThreadCleanup
(
t
->
ret_arg
=
res
;
ptw32_cleanup_callback_t
routine
,
void
*
arg
)
:
_pthread_cleanup_dest
(
t
);
cleanUpRout
(
routine
),
obj
(
arg
),
longjmp
(
t
->
jb
,
1
);
executeIt
(
1
)
}
/*
* Registers a cleanup routine for 'arg'
*/
static
void
_pthread_invoke_cancel
(
void
)
{
_pthread_cleanup
*
pcup
;
_InterlockedDecrement
(
&
_pthread_cancelling
);
/* Call cancel queue */
for
(
pcup
=
pthread_self
()
->
clean
;
pcup
;
pcup
=
pcup
->
next
)
{
{
pcup
->
func
(
pcup
->
arg
);
}
}
~
PThreadCleanup
()
pthread_exit
(
PTHREAD_CANCELED
);
}
static
void
pthread_testcancel
(
void
)
{
if
(
_pthread_cancelling
)
{
{
if
(
executeIt
&&
((
void
*
)
cleanUpRout
!=
(
void
*
)
0
)
)
pthread_t
t
=
pthread_self
();
if
(
t
->
cancelled
&&
(
t
->
p_state
&
PTHREAD_CANCEL_ENABLE
))
{
{
(
void
)
(
*
cleanUpRout
)(
obj
);
_pthread_invoke_cancel
(
);
}
}
}
}
}
void
execute
(
int
exec
)
static
int
pthread_cancel
(
pthread_t
t
)
{
if
(
t
->
p_state
&
PTHREAD_CANCEL_ASYNCHRONOUS
)
{
{
executeIt
=
exec
;
/* Dangerous asynchronous cancelling */
}
CONTEXT
ctxt
;
};
/*
/* Already done? */
* C++ implementation of PThreads cancel cleanup;
if
(
t
->
cancelled
)
return
ESRCH
;
* This implementation takes advantage of a helper
* class who's destructor automatically calls the
* cleanup routine if we exit our scope weirdly
*/
#define pthread_cleanup_push( _rout, _arg ) \
{ \
PThreadCleanup cleanup((ptw32_cleanup_callback_t)(_rout), \
(void *) (_arg) );
#define pthread_cleanup_pop( _execute ) \
ctxt
.
ContextFlags
=
CONTEXT_CONTROL
;
cleanup.execute( _execute ); \
}
SuspendThread
(
t
->
h
);
GetThreadContext
(
t
->
h
,
&
ctxt
);
#ifdef _M_X64
ctxt
.
Rip
=
(
uintptr_t
)
_pthread_invoke_cancel
;
#else
#else
ctxt
.
Eip
=
(
uintptr_t
)
_pthread_invoke_cancel
;
#endif
SetThreadContext
(
t
->
h
,
&
ctxt
);
#error ERROR [__FILE__, line __LINE__]: Cleanup type undefined.
/* Also try deferred Cancelling */
t
->
cancelled
=
1
;
#endif
/* __CLEANUP_CXX */
/* Notify everyone to look */
_InterlockedIncrement
(
&
_pthread_cancelling
);
#endif
/* __CLEANUP_C */
ResumeThread
(
t
->
h
);
}
else
{
/* Safe deferred Cancelling */
t
->
cancelled
=
1
;
#endif
/* __CLEANUP_SEH */
/* Notify everyone to look */
_InterlockedIncrement
(
&
_pthread_cancelling
);
}
/*
return
0
;
* ===============
}
* ===============
* Methods
* ===============
* ===============
*/
/*
static
unsigned
_pthread_get_state
(
pthread_attr_t
*
attr
,
unsigned
flag
)
* PThread Attribute Functions
{
*/
return
attr
->
p_state
&
flag
;
PTW32_DLLPORT
int
PTW32_CDECL
pthread_attr_init
(
pthread_attr_t
*
attr
);
}
PTW32_DLLPORT
int
PTW32_CDECL
pthread_attr_destroy
(
pthread_attr_t
*
attr
);
static
int
_pthread_set_state
(
pthread_attr_t
*
attr
,
unsigned
flag
,
unsigned
val
)
{
if
(
~
flag
&
val
)
return
EINVAL
;
attr
->
p_state
&=
~
flag
;
attr
->
p_state
|=
val
;
PTW32_DLLPORT
int
PTW32_CDECL
pthread_attr_getdetachstate
(
const
pthread_attr_t
*
attr
,
return
0
;
int
*
detachstate
);
}
PTW32_DLLPORT
int
PTW32_CDECL
pthread_attr_getstackaddr
(
const
pthread_attr_t
*
attr
,
static
int
pthread_attr_init
(
pthread_attr_t
*
attr
)
void
**
stackaddr
);
{
attr
->
p_state
=
PTHREAD_DEFAULT_ATTR
;
attr
->
stack
=
NULL
;
attr
->
s_size
=
0
;
return
0
;
}
PTW32_DLLPORT
int
PTW32_CDECL
pthread_attr_getstacksize
(
const
pthread_attr_t
*
attr
,
static
int
pthread_attr_destroy
(
pthread_attr_t
*
attr
)
size_t
*
stacksize
);
{
/* No need to do anything */
return
0
;
}
PTW32_DLLPORT
int
PTW32_CDECL
pthread_attr_setdetachstate
(
pthread_attr_t
*
attr
,
int
detachstate
);
PTW32_DLLPORT
int
PTW32_CDECL
pthread_attr_setstackaddr
(
pthread_attr_t
*
attr
,
static
int
pthread_attr_setdetachstate
(
pthread_attr_t
*
a
,
int
flag
)
void
*
stackaddr
);
{
return
_pthread_set_state
(
a
,
PTHREAD_CREATE_DETACHED
,
flag
);
}
PTW32_DLLPORT
int
PTW32_CDECL
pthread_attr_setstacksize
(
pthread_attr_t
*
attr
,
static
int
pthread_attr_getdetachstate
(
pthread_attr_t
*
a
,
int
*
flag
)
size_t
stacksize
);
{
*
flag
=
_pthread_get_state
(
a
,
PTHREAD_CREATE_DETACHED
);
return
0
;
}
PTW32_DLLPORT
int
PTW32_CDECL
pthread_attr_getschedparam
(
const
pthread_attr_t
*
attr
,
static
int
pthread_attr_setinheritsched
(
pthread_attr_t
*
a
,
int
flag
)
struct
sched_param
*
param
);
{
return
_pthread_set_state
(
a
,
PTHREAD_INHERIT_SCHED
,
flag
);
}
PTW32_DLLPORT
int
PTW32_CDECL
pthread_attr_setschedparam
(
pthread_attr_t
*
attr
,
static
int
pthread_attr_getinheritsched
(
pthread_attr_t
*
a
,
int
*
flag
)
const
struct
sched_param
*
param
);
{
*
flag
=
_pthread_get_state
(
a
,
PTHREAD_INHERIT_SCHED
);
return
0
;
}
PTW32_DLLPORT
int
PTW32_CDECL
pthread_attr_setschedpolicy
(
pthread_attr_t
*
,
static
int
pthread_attr_setscope
(
pthread_attr_t
*
a
,
int
flag
)
int
);
{
return
_pthread_set_state
(
a
,
PTHREAD_SCOPE_SYSTEM
,
flag
);
}
PTW32_DLLPORT
int
PTW32_CDECL
pthread_attr_getschedpolicy
(
pthread_attr_t
*
,
static
int
pthread_attr_getscope
(
pthread_attr_t
*
a
,
int
*
flag
)
int
*
);
{
*
flag
=
_pthread_get_state
(
a
,
PTHREAD_SCOPE_SYSTEM
);
return
0
;
}
PTW32_DLLPORT
int
PTW32_CDECL
pthread_attr_setinheritsched
(
pthread_attr_t
*
attr
,
static
int
pthread_attr_getstackaddr
(
pthread_attr_t
*
attr
,
void
**
stack
)
int
inheritsched
);
{
*
stack
=
attr
->
stack
;
return
0
;
}
PTW32_DLLPORT
int
PTW32_CDECL
pthread_attr_getinheritsched
(
pthread_attr_t
*
attr
,
static
int
pthread_attr_setstackaddr
(
pthread_attr_t
*
attr
,
void
*
stack
)
int
*
inheritsched
);
{
attr
->
stack
=
stack
;
return
0
;
}
PTW32_DLLPORT
int
PTW32_CDECL
pthread_attr_setscope
(
pthread_attr_t
*
,
static
int
pthread_attr_getstacksize
(
pthread_attr_t
*
attr
,
size_t
*
size
)
int
);
{
*
size
=
attr
->
s_size
;
return
0
;
}
PTW32_DLLPORT
int
PTW32_CDECL
pthread_attr_getscope
(
const
pthread_attr_t
*
,
static
int
pthread_attr_setstacksize
(
pthread_attr_t
*
attr
,
size_t
size
)
int
*
);
{
attr
->
s_size
=
size
;
return
0
;
}
/*
#define pthread_attr_getguardsize(A, S) ENOTSUP
* PThread Functions
#define pthread_attr_setgaurdsize(A, S) ENOTSUP
*/
#define pthread_attr_getschedparam(A, S) ENOTSUP
PTW32_DLLPORT
int
PTW32_CDECL
pthread_create
(
pthread_t
*
tid
,
#define pthread_attr_setschedparam(A, S) ENOTSUP
const
pthread_attr_t
*
attr
,
#define pthread_attr_getschedpolicy(A, S) ENOTSUP
void
*
(
*
start
)
(
void
*
),
#define pthread_attr_setschedpolicy(A, S) ENOTSUP
void
*
arg
);
PTW32_DLLPORT
int
PTW32_CDECL
pthread_detach
(
pthread_t
tid
);
PTW32_DLLPORT
int
PTW32_CDECL
pthread_equal
(
pthread_t
t1
,
static
int
pthread_setcancelstate
(
int
state
,
int
*
oldstate
)
pthread_t
t2
);
{
pthread_t
t
=
pthread_self
();
PTW32_DLLPORT
void
PTW32_CDECL
pthread_exit
(
void
*
value_ptr
);
if
((
state
&
PTHREAD_CANCEL_ENABLE
)
!=
state
)
return
EINVAL
;
if
(
oldstate
)
*
oldstate
=
t
->
p_state
&
PTHREAD_CANCEL_ENABLE
;
t
->
p_state
&=
~
PTHREAD_CANCEL_ENABLE
;
t
->
p_state
|=
state
;
PTW32_DLLPORT
int
PTW32_CDECL
pthread_join
(
pthread_t
thread
,
return
0
;
void
**
value_ptr
);
}
PTW32_DLLPORT
pthread_t
PTW32_CDECL
pthread_self
(
void
);
static
int
pthread_setcanceltype
(
int
type
,
int
*
oldtype
)
{
pthread_t
t
=
pthread_self
();
PTW32_DLLPORT
int
PTW32_CDECL
pthread_cancel
(
pthread_t
thread
);
if
((
type
&
PTHREAD_CANCEL_ASYNCHRONOUS
)
!=
type
)
return
EINVAL
;
if
(
oldtype
)
*
oldtype
=
t
->
p_state
&
PTHREAD_CANCEL_ASYNCHRONOUS
;
t
->
p_state
&=
~
PTHREAD_CANCEL_ASYNCHRONOUS
;
t
->
p_state
|=
type
;
PTW32_DLLPORT
int
PTW32_CDECL
pthread_setcancelstate
(
int
state
,
return
0
;
int
*
oldstate
);
}
PTW32_DLLPORT
int
PTW32_CDECL
pthread_setcanceltype
(
int
type
,
static
int
pthread_create_wrapper
(
void
*
args
)
int
*
oldtype
);
{
struct
_pthread_v
*
tv
=
(
_pthread_v
*
)
args
;
int
i
,
j
;
PTW32_DLLPORT
void
PTW32_CDECL
pthread_testcancel
(
void
);
_pthread_once_raw
(
&
_pthread_tls_once
,
pthread_tls_init
);
PTW32_DLLPORT
int
PTW32_CDECL
pthread_once
(
pthread_once_t
*
once_control
,
TlsSetValue
(
_pthread_tls
,
tv
);
void
(
*
init_routine
)
(
void
));
#if PTW32_LEVEL >= PTW32_LEVEL_MAX
if
(
!
setjmp
(
tv
->
jb
))
PTW32_DLLPORT
ptw32_cleanup_t
*
PTW32_CDECL
ptw32_pop_cleanup
(
int
execute
);
{
/* Call function and save return value */
tv
->
ret_arg
=
tv
->
func
(
tv
->
ret_arg
);
PTW32_DLLPORT
void
PTW32_CDECL
ptw32_push_cleanup
(
ptw32_cleanup_t
*
cleanup
,
/* Clean up destructors */
void
(
*
routine
)
(
void
*
),
_pthread_cleanup_dest
(
tv
);
void
*
arg
);
}
#endif
/* PTW32_LEVEL >= PTW32_LEVEL_MAX */
/*
/* If we exit too early, then we can race with create */
* Thread Specific Data Functions
while
(
tv
->
h
==
(
HANDLE
)
-
1
)
*/
{
PTW32_DLLPORT
int
PTW32_CDECL
pthread_key_create
(
pthread_key_t
*
key
,
YieldProcessor
();
void
(
*
destructor
)
(
void
*
));
_ReadWriteBarrier
();
}
PTW32_DLLPORT
int
PTW32_CDECL
pthread_key_delete
(
pthread_key_t
key
);
/* Make sure we free ourselves if we are detached */
if
(
!
tv
->
h
)
free
(
tv
);
PTW32_DLLPORT
int
PTW32_CDECL
pthread_setspecific
(
pthread_key_t
key
,
return
0
;
const
void
*
value
);
}
PTW32_DLLPORT
void
*
PTW32_CDECL
pthread_getspecific
(
pthread_key_t
key
);
static
int
pthread_create
(
pthread_t
*
th
,
pthread_attr_t
*
attr
,
void
*
(
*
func
)(
void
*
),
void
*
arg
)
{
struct
_pthread_v
*
tv
=
(
_pthread_v
*
)
malloc
(
sizeof
(
struct
_pthread_v
));
unsigned
ssize
=
0
;
if
(
!
tv
)
return
1
;
/*
*
th
=
tv
;
* Mutex Attribute Functions
*/
PTW32_DLLPORT
int
PTW32_CDECL
pthread_mutexattr_init
(
pthread_mutexattr_t
*
attr
);
PTW32_DLLPORT
int
PTW32_CDECL
pthread_mutexattr_destroy
(
pthread_mutexattr_t
*
attr
);
/* Save data in pthread_t */
tv
->
ret_arg
=
arg
;
tv
->
func
=
func
;
tv
->
clean
=
NULL
;
tv
->
cancelled
=
0
;
tv
->
p_state
=
PTHREAD_DEFAULT_ATTR
;
tv
->
keymax
=
0
;
tv
->
keyval
=
NULL
;
tv
->
h
=
(
HANDLE
)
-
1
;
PTW32_DLLPORT
int
PTW32_CDECL
pthread_mutexattr_getpshared
(
const
pthread_mutexattr_t
if
(
attr
)
*
attr
,
{
int
*
pshared
);
tv
->
p_state
=
attr
->
p_state
;
ssize
=
attr
->
s_size
;
}
PTW32_DLLPORT
int
PTW32_CDECL
pthread_mutexattr_setpshared
(
pthread_mutexattr_t
*
attr
,
/* Make sure tv->h has value of -1 */
int
pshared
);
_ReadWriteBarrier
(
);
PTW32_DLLPORT
int
PTW32_CDECL
pthread_mutexattr_settype
(
pthread_mutexattr_t
*
attr
,
int
kind
);
#ifdef __cplusplus
PTW32_DLLPORT
int
PTW32_CDECL
pthread_mutexattr_gettype
(
pthread_mutexattr_t
*
attr
,
int
*
kind
);
tv
->
h
=
(
HANDLE
)
_beginthreadex
(
NULL
,
ssize
,
reinterpret_cast
<
unsigned
int
(
__stdcall
*
)(
void
*
)
>
(
pthread_create_wrapper
),
tv
,
0
,
NULL
);
#else
tv
->
h
=
(
HANDLE
)
_beginthreadex
(
NULL
,
ssize
,
pthread_create_wrapper
,
tv
,
0
,
NULL
);
#endif
/*
/* Failed */
* Barrier Attribute Functions
if
(
!
tv
->
h
)
return
1
;
*/
PTW32_DLLPORT
int
PTW32_CDECL
pthread_barrierattr_init
(
pthread_barrierattr_t
*
attr
);
PTW32_DLLPORT
int
PTW32_CDECL
pthread_barrierattr_destroy
(
pthread_barrierattr_t
*
attr
);
if
(
tv
->
p_state
&
PTHREAD_CREATE_DETACHED
)
{
CloseHandle
(
tv
->
h
);
_ReadWriteBarrier
();
tv
->
h
=
0
;
}
PTW32_DLLPORT
int
PTW32_CDECL
pthread_barrierattr_getpshared
(
const
pthread_barrierattr_t
return
0
;
*
attr
,
}
int
*
pshared
);
PTW32_DLLPORT
int
PTW32_CDECL
pthread_barrierattr_setpshared
(
pthread_barrierattr_t
*
attr
,
static
int
pthread_join
(
pthread_t
t
,
void
**
res
)
int
pshared
);
{
struct
_pthread_v
*
tv
=
t
;
/*
pthread_testcancel
();
* Mutex Functions
*/
PTW32_DLLPORT
int
PTW32_CDECL
pthread_mutex_init
(
pthread_mutex_t
*
mutex
,
const
pthread_mutexattr_t
*
attr
);
PTW32_DLLPORT
int
PTW32_CDECL
pthread_mutex_destroy
(
pthread_mutex_t
*
mutex
);
WaitForSingleObject
(
tv
->
h
,
INFINITE
);
CloseHandle
(
tv
->
h
);
PTW32_DLLPORT
int
PTW32_CDECL
pthread_mutex_lock
(
pthread_mutex_t
*
mutex
);
/* Obtain return value */
if
(
res
)
*
res
=
tv
->
ret_arg
;
PTW32_DLLPORT
int
PTW32_CDECL
pthread_mutex_timedlock
(
pthread_mutex_t
*
mutex
,
free
(
tv
);
const
struct
timespec
*
abstime
);
PTW32_DLLPORT
int
PTW32_CDECL
pthread_mutex_trylock
(
pthread_mutex_t
*
mutex
);
return
0
;
}
PTW32_DLLPORT
int
PTW32_CDECL
pthread_mutex_unlock
(
pthread_mutex_t
*
mutex
);
static
int
pthread_detach
(
pthread_t
t
)
{
struct
_pthread_v
*
tv
=
t
;
/*
/*
* Spinlock Functions
* This can't race with thread exit because
* our call would be undefined if called on a dead thread.
*/
*/
PTW32_DLLPORT
int
PTW32_CDECL
pthread_spin_init
(
pthread_spinlock_t
*
lock
,
int
pshared
);
PTW32_DLLPORT
int
PTW32_CDECL
pthread_spin_destroy
(
pthread_spinlock_t
*
lock
);
CloseHandle
(
tv
->
h
);
_ReadWriteBarrier
();
tv
->
h
=
0
;
PTW32_DLLPORT
int
PTW32_CDECL
pthread_spin_lock
(
pthread_spinlock_t
*
lock
);
return
0
;
}
PTW32_DLLPORT
int
PTW32_CDECL
pthread_spin_trylock
(
pthread_spinlock_t
*
lock
);
static
int
pthread_mutexattr_init
(
pthread_mutexattr_t
*
a
)
{
*
a
=
0
;
return
0
;
}
PTW32_DLLPORT
int
PTW32_CDECL
pthread_spin_unlock
(
pthread_spinlock_t
*
lock
);
static
int
pthread_mutexattr_destroy
(
pthread_mutexattr_t
*
a
)
{
(
void
)
a
;
return
0
;
}
/*
static
int
pthread_mutexattr_gettype
(
pthread_mutexattr_t
*
a
,
int
*
type
)
* Barrier Functions
{
*/
*
type
=
*
a
&
3
;
PTW32_DLLPORT
int
PTW32_CDECL
pthread_barrier_init
(
pthread_barrier_t
*
barrier
,
const
pthread_barrierattr_t
*
attr
,
unsigned
int
count
);
PTW32_DLLPORT
int
PTW32_CDECL
pthread_barrier_destroy
(
pthread_barrier_t
*
barrier
);
return
0
;
}
PTW32_DLLPORT
int
PTW32_CDECL
pthread_barrier_wait
(
pthread_barrier_t
*
barrier
);
static
int
pthread_mutexattr_settype
(
pthread_mutexattr_t
*
a
,
int
type
)
{
if
((
unsigned
)
type
>
3
)
return
EINVAL
;
*
a
&=
~
3
;
*
a
|=
type
;
/*
return
0
;
* Condition Variable Attribute Functions
}
*/
PTW32_DLLPORT
int
PTW32_CDECL
pthread_condattr_init
(
pthread_condattr_t
*
attr
);
PTW32_DLLPORT
int
PTW32_CDECL
pthread_condattr_destroy
(
pthread_condattr_t
*
attr
);
static
int
pthread_mutexattr_getpshared
(
pthread_mutexattr_t
*
a
,
int
*
type
)
{
*
type
=
*
a
&
4
;
PTW32_DLLPORT
int
PTW32_CDECL
pthread_condattr_getpshared
(
const
pthread_condattr_t
*
attr
,
return
0
;
int
*
pshared
);
}
PTW32_DLLPORT
int
PTW32_CDECL
pthread_condattr_setpshared
(
pthread_condattr_t
*
attr
,
static
int
pthread_mutexattr_setpshared
(
pthread_mutexattr_t
*
a
,
int
type
)
int
pshared
);
{
if
((
type
&
4
)
!=
type
)
return
EINVAL
;
/*
*
a
&=
~
4
;
* Condition Variable Functions
*
a
|=
type
;
*/
PTW32_DLLPORT
int
PTW32_CDECL
pthread_cond_init
(
pthread_cond_t
*
cond
,
const
pthread_condattr_t
*
attr
);
PTW32_DLLPORT
int
PTW32_CDECL
pthread_cond_destroy
(
pthread_cond_t
*
cond
);
return
0
;
}
PTW32_DLLPORT
int
PTW32_CDECL
pthread_cond_wait
(
pthread_cond_t
*
cond
,
static
int
pthread_mutexattr_getprotocol
(
pthread_mutexattr_t
*
a
,
int
*
type
)
pthread_mutex_t
*
mutex
);
{
*
type
=
*
a
&
(
8
+
16
);
PTW32_DLLPORT
int
PTW32_CDECL
pthread_cond_timedwait
(
pthread_cond_t
*
cond
,
return
0
;
pthread_mutex_t
*
mutex
,
}
const
struct
timespec
*
abstime
);
PTW32_DLLPORT
int
PTW32_CDECL
pthread_cond_signal
(
pthread_cond_t
*
cond
);
static
int
pthread_mutexattr_setprotocol
(
pthread_mutexattr_t
*
a
,
int
type
)
{
if
((
type
&
(
8
+
16
))
!=
8
+
16
)
return
EINVAL
;
PTW32_DLLPORT
int
PTW32_CDECL
pthread_cond_broadcast
(
pthread_cond_t
*
cond
);
*
a
&=
~
(
8
+
16
);
*
a
|=
type
;
/*
return
0
;
* Scheduling
}
*/
PTW32_DLLPORT
int
PTW32_CDECL
pthread_setschedparam
(
pthread_t
thread
,
int
policy
,
const
struct
sched_param
*
param
);
PTW32_DLLPORT
int
PTW32_CDECL
pthread_getschedparam
(
pthread_t
thread
,
static
int
pthread_mutexattr_getprioceiling
(
pthread_mutexattr_t
*
a
,
int
*
prio
)
int
*
policy
,
{
struct
sched_param
*
param
);
*
prio
=
*
a
/
PTHREAD_PRIO_MULT
;
return
0
;
}
PTW32_DLLPORT
int
PTW32_CDECL
pthread_setconcurrency
(
int
);
static
int
pthread_mutexattr_setprioceiling
(
pthread_mutexattr_t
*
a
,
int
prio
)
{
*
a
&=
(
PTHREAD_PRIO_MULT
-
1
);
*
a
+=
prio
*
PTHREAD_PRIO_MULT
;
PTW32_DLLPORT
int
PTW32_CDECL
pthread_getconcurrency
(
void
);
return
0
;
}
/*
static
int
pthread_mutex_timedlock
(
pthread_mutex_t
*
m
,
struct
timespec
*
ts
)
* Read-Write Lock Functions
{
*/
unsigned
long
long
t
,
ct
;
PTW32_DLLPORT
int
PTW32_CDECL
pthread_rwlock_init
(
pthread_rwlock_t
*
lock
,
const
pthread_rwlockattr_t
*
attr
);
PTW32_DLLPORT
int
PTW32_CDECL
pthread_rwlock_destroy
(
pthread_rwlock_t
*
lock
);
struct
_pthread_crit_t
{
void
*
debug
;
LONG
count
;
LONG
r_count
;
HANDLE
owner
;
HANDLE
sem
;
ULONG_PTR
spin
;
};
PTW32_DLLPORT
int
PTW32_CDECL
pthread_rwlock_tryrdlock
(
pthread_rwlock_t
*
);
/* Try to lock it without waiting */
if
(
!
pthread_mutex_trylock
(
m
))
return
0
;
PTW32_DLLPORT
int
PTW32_CDECL
pthread_rwlock_trywrlock
(
pthread_rwlock_t
*
);
ct
=
_pthread_time_in_ms
();
t
=
_pthread_time_in_ms_from_timespec
(
ts
);
PTW32_DLLPORT
int
PTW32_CDECL
pthread_rwlock_rdlock
(
pthread_rwlock_t
*
lock
);
while
(
1
)
{
/* Have we waited long enough? */
if
(
ct
>
t
)
return
ETIMEDOUT
;
PTW32_DLLPORT
int
PTW32_CDECL
pthread_rwlock_timedrdlock
(
pthread_rwlock_t
*
lock
,
/* Wait on semaphore within critical section */
const
struct
timespec
*
abstime
);
WaitForSingleObject
(((
struct
_pthread_crit_t
*
)
m
)
->
sem
,
t
-
ct
);
PTW32_DLLPORT
int
PTW32_CDECL
pthread_rwlock_wrlock
(
pthread_rwlock_t
*
lock
);
/* Try to grab lock */
if
(
!
pthread_mutex_trylock
(
m
))
return
0
;
PTW32_DLLPORT
int
PTW32_CDECL
pthread_rwlock_timedwrlock
(
pthread_rwlock_t
*
lock
,
/* Get current time */
const
struct
timespec
*
abstime
);
ct
=
_pthread_time_in_ms
();
}
}
PTW32_DLLPORT
int
PTW32_CDECL
pthread_rwlock_unlock
(
pthread_rwlock_t
*
lock
);
#define _PTHREAD_BARRIER_FLAG (1<<30)
PTW32_DLLPORT
int
PTW32_CDECL
pthread_rwlockattr_init
(
pthread_rwlockattr_t
*
attr
);
static
int
pthread_barrier_destroy
(
pthread_barrier_t
*
b
)
{
EnterCriticalSection
(
&
b
->
m
);
PTW32_DLLPORT
int
PTW32_CDECL
pthread_rwlockattr_destroy
(
pthread_rwlockattr_t
*
attr
);
while
(
b
->
total
>
_PTHREAD_BARRIER_FLAG
)
{
/* Wait until everyone exits the barrier */
SleepConditionVariableCS
(
&
b
->
cv
,
&
b
->
m
,
INFINITE
);
}
PTW32_DLLPORT
int
PTW32_CDECL
pthread_rwlockattr_getpshared
(
const
pthread_rwlockattr_t
*
attr
,
LeaveCriticalSection
(
&
b
->
m
);
int
*
pshared
);
PTW32_DLLPORT
int
PTW32_CDECL
pthread_rwlockattr_setpshared
(
pthread_rwlockattr_t
*
attr
,
DeleteCriticalSection
(
&
b
->
m
);
int
pshared
);
#if PTW32_LEVEL >= PTW32_LEVEL_MAX - 1
return
0
;
}
/*
static
int
pthread_barrier_init
(
pthread_barrier_t
*
b
,
void
*
attr
,
int
count
)
* Signal Functions. Should be defined in <signal.h> but MSVC and MinGW32
{
* already have signal.h that don't define these.
/* Ignore attr */
*/
(
void
)
attr
;
PTW32_DLLPORT
int
PTW32_CDECL
pthread_kill
(
pthread_t
thread
,
int
sig
);
/*
b
->
count
=
count
;
* Non-portable functions
b
->
total
=
0
;
*/
/*
InitializeCriticalSection
(
&
b
->
m
);
* Compatibility with Linux.
InitializeConditionVariable
(
&
b
->
cv
);
*/
PTW32_DLLPORT
int
PTW32_CDECL
pthread_mutexattr_setkind_np
(
pthread_mutexattr_t
*
attr
,
int
kind
);
PTW32_DLLPORT
int
PTW32_CDECL
pthread_mutexattr_getkind_np
(
pthread_mutexattr_t
*
attr
,
int
*
kind
);
/*
return
0
;
* Possibly supported by other POSIX threads implementations
}
*/
PTW32_DLLPORT
int
PTW32_CDECL
pthread_delay_np
(
struct
timespec
*
interval
);
PTW32_DLLPORT
int
PTW32_CDECL
pthread_num_processors_np
(
void
);
/*
static
int
pthread_barrier_wait
(
pthread_barrier_t
*
b
)
* Useful if an application wants to statically link
{
* the lib rather than load the DLL at run-time.
EnterCriticalSection
(
&
b
->
m
);
*/
PTW32_DLLPORT
int
PTW32_CDECL
pthread_win32_process_attach_np
(
void
);
PTW32_DLLPORT
int
PTW32_CDECL
pthread_win32_process_detach_np
(
void
);
PTW32_DLLPORT
int
PTW32_CDECL
pthread_win32_thread_attach_np
(
void
);
PTW32_DLLPORT
int
PTW32_CDECL
pthread_win32_thread_detach_np
(
void
);
/*
while
(
b
->
total
>
_PTHREAD_BARRIER_FLAG
)
* Features that are auto-detected at load/run time.
{
*/
/* Wait until everyone exits the barrier */
PTW32_DLLPORT
int
PTW32_CDECL
pthread_win32_test_features_np
(
int
);
SleepConditionVariableCS
(
&
b
->
cv
,
&
b
->
m
,
INFINITE
);
enum
ptw32_features
{
}
PTW32_SYSTEM_INTERLOCKED_COMPARE_EXCHANGE
=
0x0001
,
/* System provides it. */
PTW32_ALERTABLE_ASYNC_CANCEL
=
0x0002
/* Can cancel blocked threads. */
};
/*
/* Are we the first to enter? */
* Register a system time change with the library.
if
(
b
->
total
==
_PTHREAD_BARRIER_FLAG
)
b
->
total
=
0
;
* Causes the library to perform various functions
* in response to the change. Should be called whenever
* the application's top level window receives a
* WM_TIMECHANGE message. It can be passed directly to
* pthread_create() as a new thread if desired.
*/
PTW32_DLLPORT
void
*
PTW32_CDECL
pthread_timechange_handler_np
(
void
*
);
#endif
/*PTW32_LEVEL >= PTW32_LEVEL_MAX - 1 */
b
->
total
++
;
#if PTW32_LEVEL >= PTW32_LEVEL_MAX
if
(
b
->
total
==
b
->
count
)
{
b
->
total
+=
_PTHREAD_BARRIER_FLAG
-
1
;
WakeAllConditionVariable
(
&
b
->
cv
);
/*
LeaveCriticalSection
(
&
b
->
m
);
* Returns the Win32 HANDLE for the POSIX thread.
*/
PTW32_DLLPORT
HANDLE
PTW32_CDECL
pthread_getw32threadhandle_np
(
pthread_t
thread
);
return
1
;
}
else
{
while
(
b
->
total
<
_PTHREAD_BARRIER_FLAG
)
{
/* Wait until enough threads enter the barrier */
SleepConditionVariableCS
(
&
b
->
cv
,
&
b
->
m
,
INFINITE
);
}
/*
b
->
total
--
;
* Protected Methods
*
* This function blocks until the given WIN32 handle
* is signaled or pthread_cancel had been called.
* This function allows the caller to hook into the
* PThreads cancel mechanism. It is implemented using
*
* WaitForMultipleObjects
*
* on 'waitHandle' and a manually reset WIN32 Event
* used to implement pthread_cancel. The 'timeout'
* argument to TimedWait is simply passed to
* WaitForMultipleObjects.
*/
PTW32_DLLPORT
int
PTW32_CDECL
pthreadCancelableWait
(
HANDLE
waitHandle
);
PTW32_DLLPORT
int
PTW32_CDECL
pthreadCancelableTimedWait
(
HANDLE
waitHandle
,
DWORD
timeout
);
#endif
/* PTW32_LEVEL >= PTW32_LEVEL_MAX */
/* Get entering threads to wake up */
if
(
b
->
total
==
_PTHREAD_BARRIER_FLAG
)
WakeAllConditionVariable
(
&
b
->
cv
);
/*
LeaveCriticalSection
(
&
b
->
m
);
* Thread-Safe C Runtime Library Mappings.
*/
#ifndef _UWIN
# if defined(NEED_ERRNO)
PTW32_DLLPORT
int
*
PTW32_CDECL
_errno
(
void
);
# else
# ifndef errno
# if (defined(_MT) || defined(_DLL))
__declspec
(
dllimport
)
extern
int
*
__cdecl
_errno
(
void
);
# define errno (*_errno())
# endif
# endif
# endif
#endif
/*
return
0
;
* WIN32 C runtime library had been made thread-safe
}
* without affecting the user interface. Provide
}
* mappings from the UNIX thread-safe versions to
* the standard C runtime library calls.
* Only provide function mappings for functions that
* actually exist on WIN32.
*/
#if !defined(__MINGW32__)
static
int
pthread_barrierattr_init
(
void
**
attr
)
#define strtok_r( _s, _sep, _lasts ) \
{
( *(_lasts) = strtok( (_s), (_sep) ) )
*
attr
=
NULL
;
#endif
/* !__MINGW32__ */
return
0
;
}
#define asctime_r( _tm, _buf ) \
static
int
pthread_barrierattr_destroy
(
void
**
attr
)
( strcpy( (_buf), asctime( (_tm) ) ), \
{
(_buf) )
/* Ignore attr */
(
void
)
attr
;
#define ctime_r( _clock, _buf ) \
return
0
;
( strcpy( (_buf), ctime( (_clock) ) ), \
}
(_buf) )
#define gmtime_r( _clock, _result ) \
static
int
pthread_barrierattr_setpshared
(
void
**
attr
,
int
s
)
( *(_result) = *gmtime( (_clock) ), \
{
(_result) )
*
attr
=
(
void
*
)
s
;
return
0
;
}
#define localtime_r( _clock, _result ) \
static
int
pthread_barrierattr_getpshared
(
void
**
attr
,
int
*
s
)
( *(_result) = *localtime( (_clock) ), \
{
(_result) )
*
s
=
(
int
)
(
size_t
)
*
attr
;
#define rand_r( _seed ) \
return
0
;
( _seed == _seed? rand() : rand() )
}
static
int
pthread_key_create
(
pthread_key_t
*
key
,
void
(
*
dest
)(
void
*
))
{
int
i
;
long
nmax
;
void
(
**
d
)(
void
*
);
/*
if
(
!
key
)
return
EINVAL
;
* Some compiler environments don't define some things.
*/
#if defined(__BORLANDC__)
# define _ftime ftime
# define _timeb timeb
#endif
#ifdef __cplusplus
pthread_rwlock_wrlock
(
&
_pthread_key_lock
);
/*
for
(
i
=
_pthread_key_sch
;
i
<
_pthread_key_max
;
i
++
)
* Internal exceptions
{
*/
if
(
!
_pthread_key_dest
[
i
])
class
ptw32_exception
{};
{
class
ptw32_exception_cancel
:
public
ptw32_exception
{};
*
key
=
i
;
class
ptw32_exception_exit
:
public
ptw32_exception
{};
if
(
dest
)
{
_pthread_key_dest
[
i
]
=
dest
;
}
else
{
_pthread_key_dest
[
i
]
=
(
void
(
*
)(
void
*
))
1
;
}
pthread_rwlock_unlock
(
&
_pthread_key_lock
);
return
0
;
}
}
for
(
i
=
0
;
i
<
_pthread_key_sch
;
i
++
)
{
if
(
!
_pthread_key_dest
[
i
])
{
*
key
=
i
;
if
(
dest
)
{
_pthread_key_dest
[
i
]
=
dest
;
}
else
{
_pthread_key_dest
[
i
]
=
(
void
(
*
)(
void
*
))
1
;
}
pthread_rwlock_unlock
(
&
_pthread_key_lock
);
return
0
;
}
}
if
(
!
_pthread_key_max
)
_pthread_key_max
=
1
;
if
(
_pthread_key_max
==
PTHREAD_KEYS_MAX
)
{
pthread_rwlock_unlock
(
&
_pthread_key_lock
);
return
ENOMEM
;
}
nmax
=
_pthread_key_max
*
2
;
if
(
nmax
>
PTHREAD_KEYS_MAX
)
nmax
=
PTHREAD_KEYS_MAX
;
/* No spare room anywhere */
#ifdef __cplusplus
d
=
reinterpret_cast
<
void
(
__cdecl
**
)(
void
*
)
>
(
realloc
(
_pthread_key_dest
,
nmax
*
sizeof
(
*
d
)));
#else
d
=
realloc
(
_pthread_key_dest
,
nmax
*
sizeof
(
*
d
));
#endif
#endif
if
(
!
d
)
{
pthread_rwlock_unlock
(
&
_pthread_key_lock
);
#if PTW32_LEVEL >= PTW32_LEVEL_MAX
return
ENOMEM
;
}
/* FIXME: This is only required if the library was built using SEH */
/* Clear new region */
/*
memset
((
void
*
)
&
d
[
_pthread_key_max
],
0
,
(
nmax
-
_pthread_key_max
)
*
sizeof
(
void
*
));
* Get internal SEH tag
*/
PTW32_DLLPORT
DWORD
PTW32_CDECL
ptw32_get_exception_services_code
(
void
);
#endif
/* PTW32_LEVEL >= PTW32_LEVEL_MAX */
/* Use new region */
_pthread_key_dest
=
d
;
_pthread_key_sch
=
_pthread_key_max
+
1
;
*
key
=
_pthread_key_max
;
_pthread_key_max
=
nmax
;
#ifndef PTW32_BUILD
if
(
dest
)
{
_pthread_key_dest
[
*
key
]
=
dest
;
}
else
{
_pthread_key_dest
[
*
key
]
=
(
void
(
*
)(
void
*
))
1
;
}
#ifdef __CLEANUP_SEH
pthread_rwlock_unlock
(
&
_pthread_key_lock
);
/*
return
0
;
* Redefine the SEH __except keyword to ensure that applications
}
* propagate our internal exceptions up to the library's internal handlers.
*/
#define __except( E ) \
__except( ( GetExceptionCode() == ptw32_get_exception_services_code() ) \
? EXCEPTION_CONTINUE_SEARCH : ( E ) )
#endif
/* __CLEANUP_SEH */
static
int
pthread_key_delete
(
pthread_key_t
key
)
{
if
(
key
>
_pthread_key_max
)
return
EINVAL
;
if
(
!
_pthread_key_dest
)
return
EINVAL
;
#ifdef __CLEANUP_CXX
pthread_rwlock_wrlock
(
&
_pthread_key_lock
);
_pthread_key_dest
[
key
]
=
NULL
;
/*
/* Start next search from our location */
* Redefine the C++ catch keyword to ensure that applications
if
(
_pthread_key_sch
>
key
)
_pthread_key_sch
=
key
;
* propagate our internal exceptions up to the library's internal handlers.
*/
#ifdef _MSC_VER
/*
* WARNING: Replace any 'catch( ... )' with 'PtW32CatchAll'
* if you want Pthread-Win32 cancelation and pthread_exit to work.
*/
#ifndef PtW32NoCatchWarn
pthread_rwlock_unlock
(
&
_pthread_key_lock
);
#pragma message("Specify \"/DPtW32NoCatchWarn\" compiler flag to skip this message.")
#pragma message("------------------------------------------------------------------")
#pragma message("When compiling applications with MSVC++ and C++ exception handling:")
#pragma message(" Replace any 'catch( ... )' in routines called from POSIX threads")
#pragma message(" with 'PtW32CatchAll' or 'CATCHALL' if you want POSIX thread")
#pragma message(" cancelation and pthread_exit to work. For example:")
#pragma message("")
#pragma message(" #ifdef PtW32CatchAll")
#pragma message(" PtW32CatchAll")
#pragma message(" #else")
#pragma message(" catch(...)")
#pragma message(" #endif")
#pragma message(" {")
#pragma message("
/* Catchall block processing */
")
#pragma message(" }")
#pragma message("------------------------------------------------------------------")
#endif
return
0
;
}
#define PtW32CatchAll \
static
void
*
pthread_getspecific
(
pthread_key_t
key
)
catch( ptw32_exception & ) { throw; } \
{
catch( ... )
pthread_t
t
=
pthread_self
();
#else
/* _MSC_VER */
if
(
key
>=
t
->
keymax
)
return
NULL
;
#define catch( E ) \
return
t
->
keyval
[
key
];
catch( ptw32_exception & ) { throw; } \
catch( E )
#endif
/* _MSC_VER */
}
#endif
/* __CLEANUP_CXX */
static
int
pthread_setspecific
(
pthread_key_t
key
,
const
void
*
value
)
{
pthread_t
t
=
pthread_self
();
#endif
/* ! PTW32_BUILD */
if
(
key
>
t
->
keymax
)
{
int
keymax
=
(
key
+
1
)
*
2
;
void
**
kv
=
(
void
**
)
realloc
(
t
->
keyval
,
keymax
*
sizeof
(
void
*
));
#ifdef __cplusplus
if
(
!
kv
)
return
ENOMEM
;
}
/* End of extern "C" */
#endif
/* __cplusplus */
#ifdef PTW32__HANDLE_DEF
/* Clear new region */
# undef HANDLE
memset
(
&
kv
[
t
->
keymax
],
0
,
(
keymax
-
t
->
keymax
)
*
sizeof
(
void
*
));
#endif
#ifdef PTW32__DWORD_DEF
t
->
keyval
=
kv
;
# undef DWORD
t
->
keymax
=
keymax
;
#endif
}
t
->
keyval
[
key
]
=
(
void
*
)
value
;
return
0
;
}
static
int
pthread_spin_init
(
pthread_spinlock_t
*
l
,
int
pshared
)
{
(
void
)
pshared
;
*
l
=
0
;
return
0
;
}
static
int
pthread_spin_destroy
(
pthread_spinlock_t
*
l
)
{
(
void
)
l
;
return
0
;
}
/* No-fair spinlock due to lack of knowledge of thread number */
static
int
pthread_spin_lock
(
pthread_spinlock_t
*
l
)
{
while
(
_InterlockedExchange
(
l
,
EBUSY
))
{
/* Don't lock the bus whilst waiting */
while
(
*
l
)
{
YieldProcessor
();
/* Compiler barrier. Prevent caching of *l */
_ReadWriteBarrier
();
}
}
return
0
;
}
static
int
pthread_spin_trylock
(
pthread_spinlock_t
*
l
)
{
return
_InterlockedExchange
(
l
,
EBUSY
);
}
static
int
pthread_spin_unlock
(
pthread_spinlock_t
*
l
)
{
/* Compiler barrier. The store below acts with release symmantics */
_ReadWriteBarrier
();
*
l
=
0
;
return
0
;
}
static
int
pthread_cond_init
(
pthread_cond_t
*
c
,
pthread_condattr_t
*
a
)
{
(
void
)
a
;
InitializeConditionVariable
(
c
);
return
0
;
}
static
int
pthread_cond_signal
(
pthread_cond_t
*
c
)
{
WakeConditionVariable
(
c
);
return
0
;
}
static
int
pthread_cond_broadcast
(
pthread_cond_t
*
c
)
{
WakeAllConditionVariable
(
c
);
return
0
;
}
static
int
pthread_cond_wait
(
pthread_cond_t
*
c
,
pthread_mutex_t
*
m
)
{
pthread_testcancel
();
SleepConditionVariableCS
(
c
,
m
,
INFINITE
);
return
0
;
}
static
int
pthread_cond_destroy
(
pthread_cond_t
*
c
)
{
(
void
)
c
;
return
0
;
}
static
int
pthread_cond_timedwait
(
pthread_cond_t
*
c
,
pthread_mutex_t
*
m
,
struct
timespec
*
t
)
{
unsigned
long
long
tm
=
_pthread_rel_time_in_ms
(
t
);
pthread_testcancel
();
#undef PTW32_LEVEL
if
(
!
SleepConditionVariableCS
(
c
,
m
,
tm
))
return
ETIMEDOUT
;
#undef PTW32_LEVEL_MAX
#endif
/* ! RC_INVOKED */
/* We can have a spurious wakeup after the timeout */
if
(
!
_pthread_rel_time_in_ms
(
t
))
return
ETIMEDOUT
;
return
0
;
}
static
int
pthread_condattr_destroy
(
pthread_condattr_t
*
a
)
{
(
void
)
a
;
return
0
;
}
#define pthread_condattr_getclock(A, C) ENOTSUP
#define pthread_condattr_setclock(A, C) ENOTSUP
static
int
pthread_condattr_init
(
pthread_condattr_t
*
a
)
{
*
a
=
0
;
return
0
;
}
static
int
pthread_condattr_getpshared
(
pthread_condattr_t
*
a
,
int
*
s
)
{
*
s
=
*
a
;
return
0
;
}
#endif
/* PTHREAD_H */
static
int
pthread_condattr_setpshared
(
pthread_condattr_t
*
a
,
int
s
)
{
*
a
=
s
;
return
0
;
}
static
int
pthread_rwlockattr_destroy
(
pthread_rwlockattr_t
*
a
)
{
(
void
)
a
;
return
0
;
}
static
int
pthread_rwlockattr_init
(
pthread_rwlockattr_t
*
a
)
{
*
a
=
0
;
}
static
int
pthread_rwlockattr_getpshared
(
pthread_rwlockattr_t
*
a
,
int
*
s
)
{
*
s
=
*
a
;
return
0
;
}
static
int
pthread_rwlockattr_setpshared
(
pthread_rwlockattr_t
*
a
,
int
s
)
{
*
a
=
s
;
return
0
;
}
/* No fork() in windows - so ignore this */
#define pthread_atfork(F1,F2,F3) 0
/* Windows has rudimentary signals support */
#define pthread_kill(T, S) 0
#define pthread_sigmask(H, S1, S2) 0
/* Wrap cancellation points */
/*
#define accept(...) (pthread_testcancel(), accept(__VA_ARGS__))
#define aio_suspend(...) (pthread_testcancel(), aio_suspend(__VA_ARGS__))
#define clock_nanosleep(...) (pthread_testcancel(), clock_nanosleep(__VA_ARGS__))
#define close(...) (pthread_testcancel(), close(__VA_ARGS__))
#define connect(...) (pthread_testcancel(), connect(__VA_ARGS__))
#define creat(...) (pthread_testcancel(), creat(__VA_ARGS__))
#define fcntl(...) (pthread_testcancel(), fcntl(__VA_ARGS__))
#define fdatasync(...) (pthread_testcancel(), fdatasync(__VA_ARGS__))
#define fsync(...) (pthread_testcancel(), fsync(__VA_ARGS__))
#define getmsg(...) (pthread_testcancel(), getmsg(__VA_ARGS__))
#define getpmsg(...) (pthread_testcancel(), getpmsg(__VA_ARGS__))
#define lockf(...) (pthread_testcancel(), lockf(__VA_ARGS__))
#define mg_receive(...) (pthread_testcancel(), mg_receive(__VA_ARGS__))
#define mg_send(...) (pthread_testcancel(), mg_send(__VA_ARGS__))
#define mg_timedreceive(...) (pthread_testcancel(), mg_timedreceive(__VA_ARGS__))
#define mg_timessend(...) (pthread_testcancel(), mg_timedsend(__VA_ARGS__))
#define msgrcv(...) (pthread_testcancel(), msgrecv(__VA_ARGS__))
#define msgsnd(...) (pthread_testcancel(), msgsnd(__VA_ARGS__))
#define msync(...) (pthread_testcancel(), msync(__VA_ARGS__))
#define nanosleep(...) (pthread_testcancel(), nanosleep(__VA_ARGS__))
#define open(...) (pthread_testcancel(), open(__VA_ARGS__))
#define pause(...) (pthread_testcancel(), pause(__VA_ARGS__))
#define poll(...) (pthread_testcancel(), poll(__VA_ARGS__))
#define pread(...) (pthread_testcancel(), pread(__VA_ARGS__))
#define pselect(...) (pthread_testcancel(), pselect(__VA_ARGS__))
#define putmsg(...) (pthread_testcancel(), putmsg(__VA_ARGS__))
#define putpmsg(...) (pthread_testcancel(), putpmsg(__VA_ARGS__))
#define pwrite(...) (pthread_testcancel(), pwrite(__VA_ARGS__))
#define read(...) (pthread_testcancel(), read(__VA_ARGS__))
#define readv(...) (pthread_testcancel(), readv(__VA_ARGS__))
#define recv(...) (pthread_testcancel(), recv(__VA_ARGS__))
#define recvfrom(...) (pthread_testcancel(), recvfrom(__VA_ARGS__))
#define recvmsg(...) (pthread_testcancel(), recvmsg(__VA_ARGS__))
#define select(...) (pthread_testcancel(), select(__VA_ARGS__))
#define sem_timedwait(...) (pthread_testcancel(), sem_timedwait(__VA_ARGS__))
#define sem_wait(...) (pthread_testcancel(), sem_wait(__VA_ARGS__))
#define send(...) (pthread_testcancel(), send(__VA_ARGS__))
#define sendmsg(...) (pthread_testcancel(), sendmsg(__VA_ARGS__))
#define sendto(...) (pthread_testcancel(), sendto(__VA_ARGS__))
#define sigpause(...) (pthread_testcancel(), sigpause(__VA_ARGS__))
#define sigsuspend(...) (pthread_testcancel(), sigsuspend(__VA_ARGS__))
#define sigwait(...) (pthread_testcancel(), sigwait(__VA_ARGS__))
#define sigwaitinfo(...) (pthread_testcancel(), sigwaitinfo(__VA_ARGS__))
#define sleep(...) (pthread_testcancel(), sleep(__VA_ARGS__))
//#define Sleep(...) (pthread_testcancel(), Sleep(__VA_ARGS__))
#define system(...) (pthread_testcancel(), system(__VA_ARGS__))
#define access(...) (pthread_testcancel(), access(__VA_ARGS__))
#define asctime(...) (pthread_testcancel(), asctime(__VA_ARGS__))
#define asctime_r(...) (pthread_testcancel(), asctime_r(__VA_ARGS__))
#define catclose(...) (pthread_testcancel(), catclose(__VA_ARGS__))
#define catgets(...) (pthread_testcancel(), catgets(__VA_ARGS__))
#define catopen(...) (pthread_testcancel(), catopen(__VA_ARGS__))
#define closedir(...) (pthread_testcancel(), closedir(__VA_ARGS__))
#define closelog(...) (pthread_testcancel(), closelog(__VA_ARGS__))
#define ctermid(...) (pthread_testcancel(), ctermid(__VA_ARGS__))
#define ctime(...) (pthread_testcancel(), ctime(__VA_ARGS__))
#define ctime_r(...) (pthread_testcancel(), ctime_r(__VA_ARGS__))
#define dbm_close(...) (pthread_testcancel(), dbm_close(__VA_ARGS__))
#define dbm_delete(...) (pthread_testcancel(), dbm_delete(__VA_ARGS__))
#define dbm_fetch(...) (pthread_testcancel(), dbm_fetch(__VA_ARGS__))
#define dbm_nextkey(...) (pthread_testcancel(), dbm_nextkey(__VA_ARGS__))
#define dbm_open(...) (pthread_testcancel(), dbm_open(__VA_ARGS__))
#define dbm_store(...) (pthread_testcancel(), dbm_store(__VA_ARGS__))
#define dlclose(...) (pthread_testcancel(), dlclose(__VA_ARGS__))
#define dlopen(...) (pthread_testcancel(), dlopen(__VA_ARGS__))
#define endgrent(...) (pthread_testcancel(), endgrent(__VA_ARGS__))
#define endhostent(...) (pthread_testcancel(), endhostent(__VA_ARGS__))
#define endnetent(...) (pthread_testcancel(), endnetent(__VA_ARGS__))
#define endprotoent(...) (pthread_testcancel(), endprotoend(__VA_ARGS__))
#define endpwent(...) (pthread_testcancel(), endpwent(__VA_ARGS__))
#define endservent(...) (pthread_testcancel(), endservent(__VA_ARGS__))
#define endutxent(...) (pthread_testcancel(), endutxent(__VA_ARGS__))
#define fclose(...) (pthread_testcancel(), fclose(__VA_ARGS__))
#define fflush(...) (pthread_testcancel(), fflush(__VA_ARGS__))
#define fgetc(...) (pthread_testcancel(), fgetc(__VA_ARGS__))
#define fgetpos(...) (pthread_testcancel(), fgetpos(__VA_ARGS__))
#define fgets(...) (pthread_testcancel(), fgets(__VA_ARGS__))
#define fgetwc(...) (pthread_testcancel(), fgetwc(__VA_ARGS__))
#define fgetws(...) (pthread_testcancel(), fgetws(__VA_ARGS__))
#define fmtmsg(...) (pthread_testcancel(), fmtmsg(__VA_ARGS__))
#define fopen(...) (pthread_testcancel(), fopen(__VA_ARGS__))
#define fpathconf(...) (pthread_testcancel(), fpathconf(__VA_ARGS__))
#define fprintf(...) (pthread_testcancel(), fprintf(__VA_ARGS__))
#define fputc(...) (pthread_testcancel(), fputc(__VA_ARGS__))
#define fputs(...) (pthread_testcancel(), fputs(__VA_ARGS__))
#define fputwc(...) (pthread_testcancel(), fputwc(__VA_ARGS__))
#define fputws(...) (pthread_testcancel(), fputws(__VA_ARGS__))
#define fread(...) (pthread_testcancel(), fread(__VA_ARGS__))
#define freopen(...) (pthread_testcancel(), freopen(__VA_ARGS__))
#define fscanf(...) (pthread_testcancel(), fscanf(__VA_ARGS__))
#define fseek(...) (pthread_testcancel(), fseek(__VA_ARGS__))
#define fseeko(...) (pthread_testcancel(), fseeko(__VA_ARGS__))
#define fsetpos(...) (pthread_testcancel(), fsetpos(__VA_ARGS__))
#define fstat(...) (pthread_testcancel(), fstat(__VA_ARGS__))
#define ftell(...) (pthread_testcancel(), ftell(__VA_ARGS__))
#define ftello(...) (pthread_testcancel(), ftello(__VA_ARGS__))
#define ftw(...) (pthread_testcancel(), ftw(__VA_ARGS__))
#define fwprintf(...) (pthread_testcancel(), fwprintf(__VA_ARGS__))
#define fwrite(...) (pthread_testcancel(), fwrite(__VA_ARGS__))
#define fwscanf(...) (pthread_testcancel(), fwscanf(__VA_ARGS__))
#define getaddrinfo(...) (pthread_testcancel(), getaddrinfo(__VA_ARGS__))
#define getc(...) (pthread_testcancel(), getc(__VA_ARGS__))
#define getc_unlocked(...) (pthread_testcancel(), getc_unlocked(__VA_ARGS__))
#define getchar(...) (pthread_testcancel(), getchar(__VA_ARGS__))
#define getchar_unlocked(...) (pthread_testcancel(), getchar_unlocked(__VA_ARGS__))
#define getcwd(...) (pthread_testcancel(), getcwd(__VA_ARGS__))
#define getdate(...) (pthread_testcancel(), getdate(__VA_ARGS__))
#define getgrent(...) (pthread_testcancel(), getgrent(__VA_ARGS__))
#define getgrgid(...) (pthread_testcancel(), getgrgid(__VA_ARGS__))
#define getgrgid_r(...) (pthread_testcancel(), getgrgid_r(__VA_ARGS__))
#define gergrnam(...) (pthread_testcancel(), getgrnam(__VA_ARGS__))
#define getgrnam_r(...) (pthread_testcancel(), getgrnam_r(__VA_ARGS__))
#define gethostbyaddr(...) (pthread_testcancel(), gethostbyaddr(__VA_ARGS__))
#define gethostbyname(...) (pthread_testcancel(), gethostbyname(__VA_ARGS__))
#define gethostent(...) (pthread_testcancel(), gethostent(__VA_ARGS__))
#define gethostid(...) (pthread_testcancel(), gethostid(__VA_ARGS__))
#define gethostname(...) (pthread_testcancel(), gethostname(__VA_ARGS__))
#define getlogin(...) (pthread_testcancel(), getlogin(__VA_ARGS__))
#define getlogin_r(...) (pthread_testcancel(), getlogin_r(__VA_ARGS__))
#define getnameinfo(...) (pthread_testcancel(), getnameinfo(__VA_ARGS__))
#define getnetbyaddr(...) (pthread_testcancel(), getnetbyaddr(__VA_ARGS__))
#define getnetbyname(...) (pthread_testcancel(), getnetbyname(__VA_ARGS__))
#define getnetent(...) (pthread_testcancel(), getnetent(__VA_ARGS__))
#define getopt(...) (pthread_testcancel(), getopt(__VA_ARGS__))
#define getprotobyname(...) (pthread_testcancel(), getprotobyname(__VA_ARGS__))
#define getprotobynumber(...) (pthread_testcancel(), getprotobynumber(__VA_ARGS__))
#define getprotoent(...) (pthread_testcancel(), getprotoent(__VA_ARGS__))
#define getpwent(...) (pthread_testcancel(), getpwent(__VA_ARGS__))
#define getpwnam(...) (pthread_testcancel(), getpwnam(__VA_ARGS__))
#define getpwnam_r(...) (pthread_testcancel(), getpwnam_r(__VA_ARGS__))
#define getpwuid(...) (pthread_testcancel(), getpwuid(__VA_ARGS__))
#define getpwuid_r(...) (pthread_testcancel(), getpwuid_r(__VA_ARGS__))
#define gets(...) (pthread_testcancel(), gets(__VA_ARGS__))
#define getservbyname(...) (pthread_testcancel(), getservbyname(__VA_ARGS__))
#define getservbyport(...) (pthread_testcancel(), getservbyport(__VA_ARGS__))
#define getservent(...) (pthread_testcancel(), getservent(__VA_ARGS__))
#define getutxent(...) (pthread_testcancel(), getutxent(__VA_ARGS__))
#define getutxid(...) (pthread_testcancel(), getutxid(__VA_ARGS__))
#define getutxline(...) (pthread_testcancel(), getutxline(__VA_ARGS__))
#undef getwc
#define getwc(...) (pthread_testcancel(), getwc(__VA_ARGS__))
#undef getwchar
#define getwchar(...) (pthread_testcancel(), getwchar(__VA_ARGS__))
#define getwd(...) (pthread_testcancel(), getwd(__VA_ARGS__))
#define glob(...) (pthread_testcancel(), glob(__VA_ARGS__))
#define iconv_close(...) (pthread_testcancel(), iconv_close(__VA_ARGS__))
#define iconv_open(...) (pthread_testcancel(), iconv_open(__VA_ARGS__))
#define ioctl(...) (pthread_testcancel(), ioctl(__VA_ARGS__))
#define link(...) (pthread_testcancel(), link(__VA_ARGS__))
#define localtime(...) (pthread_testcancel(), localtime(__VA_ARGS__))
#define localtime_r(...) (pthread_testcancel(), localtime_r(__VA_ARGS__))
#define lseek(...) (pthread_testcancel(), lseek(__VA_ARGS__))
#define lstat(...) (pthread_testcancel(), lstat(__VA_ARGS__))
#define mkstemp(...) (pthread_testcancel(), mkstemp(__VA_ARGS__))
#define nftw(...) (pthread_testcancel(), nftw(__VA_ARGS__))
#define opendir(...) (pthread_testcancel(), opendir(__VA_ARGS__))
#define openlog(...) (pthread_testcancel(), openlog(__VA_ARGS__))
#define pathconf(...) (pthread_testcancel(), pathconf(__VA_ARGS__))
#define pclose(...) (pthread_testcancel(), pclose(__VA_ARGS__))
#define perror(...) (pthread_testcancel(), perror(__VA_ARGS__))
#define popen(...) (pthread_testcancel(), popen(__VA_ARGS__))
#define posix_fadvise(...) (pthread_testcancel(), posix_fadvise(__VA_ARGS__))
#define posix_fallocate(...) (pthread_testcancel(), posix_fallocate(__VA_ARGS__))
#define posix_madvise(...) (pthread_testcancel(), posix_madvise(__VA_ARGS__))
#define posix_openpt(...) (pthread_testcancel(), posix_openpt(__VA_ARGS__))
#define posix_spawn(...) (pthread_testcancel(), posix_spawn(__VA_ARGS__))
#define posix_spawnp(...) (pthread_testcancel(), posix_spawnp(__VA_ARGS__))
#define posix_trace_clear(...) (pthread_testcancel(), posix_trace_clear(__VA_ARGS__))
#define posix_trace_close(...) (pthread_testcancel(), posix_trace_close(__VA_ARGS__))
#define posix_trace_create(...) (pthread_testcancel(), posix_trace_create(__VA_ARGS__))
#define posix_trace_create_withlog(...) (pthread_testcancel(), posix_trace_create_withlog(__VA_ARGS__))
#define posix_trace_eventtypelist_getne(...) (pthread_testcancel(), posix_trace_eventtypelist_getne(__VA_ARGS__))
#define posix_trace_eventtypelist_rewin(...) (pthread_testcancel(), posix_trace_eventtypelist_rewin(__VA_ARGS__))
#define posix_trace_flush(...) (pthread_testcancel(), posix_trace_flush(__VA_ARGS__))
#define posix_trace_get_attr(...) (pthread_testcancel(), posix_trace_get_attr(__VA_ARGS__))
#define posix_trace_get_filter(...) (pthread_testcancel(), posix_trace_get_filter(__VA_ARGS__))
#define posix_trace_get_status(...) (pthread_testcancel(), posix_trace_get_status(__VA_ARGS__))
#define posix_trace_getnext_event(...) (pthread_testcancel(), posix_trace_getnext_event(__VA_ARGS__))
#define posix_trace_open(...) (pthread_testcancel(), posix_trace_open(__VA_ARGS__))
#define posix_trace_rewind(...) (pthread_testcancel(), posix_trace_rewind(__VA_ARGS__))
#define posix_trace_setfilter(...) (pthread_testcancel(), posix_trace_setfilter(__VA_ARGS__))
#define posix_trace_shutdown(...) (pthread_testcancel(), posix_trace_shutdown(__VA_ARGS__))
#define posix_trace_timedgetnext_event(...) (pthread_testcancel(), posix_trace_timedgetnext_event(__VA_ARGS__))
#define posix_typed_mem_open(...) (pthread_testcancel(), posix_typed_mem_open(__VA_ARGS__))
#define printf(...) (pthread_testcancel(), printf(__VA_ARGS__))
#define putc(...) (pthread_testcancel(), putc(__VA_ARGS__))
#define putc_unlocked(...) (pthread_testcancel(), putc_unlocked(__VA_ARGS__))
#define putchar(...) (pthread_testcancel(), putchar(__VA_ARGS__))
#define putchar_unlocked(...) (pthread_testcancel(), putchar_unlocked(__VA_ARGS__))
#define puts(...) (pthread_testcancel(), puts(__VA_ARGS__))
#define pututxline(...) (pthread_testcancel(), pututxline(__VA_ARGS__))
#undef putwc
#define putwc(...) (pthread_testcancel(), putwc(__VA_ARGS__))
#undef putwchar
#define putwchar(...) (pthread_testcancel(), putwchar(__VA_ARGS__))
#define readdir(...) (pthread_testcancel(), readdir(__VA_ARSG__))
#define readdir_r(...) (pthread_testcancel(), readdir_r(__VA_ARGS__))
#define remove(...) (pthread_testcancel(), remove(__VA_ARGS__))
#define rename(...) (pthread_testcancel(), rename(__VA_ARGS__))
#define rewind(...) (pthread_testcancel(), rewind(__VA_ARGS__))
#define rewinddir(...) (pthread_testcancel(), rewinddir(__VA_ARGS__))
#define scanf(...) (pthread_testcancel(), scanf(__VA_ARGS__))
#define seekdir(...) (pthread_testcancel(), seekdir(__VA_ARGS__))
#define semop(...) (pthread_testcancel(), semop(__VA_ARGS__))
#define setgrent(...) (pthread_testcancel(), setgrent(__VA_ARGS__))
#define sethostent(...) (pthread_testcancel(), sethostemt(__VA_ARGS__))
#define setnetent(...) (pthread_testcancel(), setnetent(__VA_ARGS__))
#define setprotoent(...) (pthread_testcancel(), setprotoent(__VA_ARGS__))
#define setpwent(...) (pthread_testcancel(), setpwent(__VA_ARGS__))
#define setservent(...) (pthread_testcancel(), setservent(__VA_ARGS__))
#define setutxent(...) (pthread_testcancel(), setutxent(__VA_ARGS__))
#define stat(...) (pthread_testcancel(), stat(__VA_ARGS__))
#define strerror(...) (pthread_testcancel(), strerror(__VA_ARGS__))
#define strerror_r(...) (pthread_testcancel(), strerror_r(__VA_ARGS__))
#define strftime(...) (pthread_testcancel(), strftime(__VA_ARGS__))
#define symlink(...) (pthread_testcancel(), symlink(__VA_ARGS__))
#define sync(...) (pthread_testcancel(), sync(__VA_ARGS__))
#define syslog(...) (pthread_testcancel(), syslog(__VA_ARGS__))
#define tmpfile(...) (pthread_testcancel(), tmpfile(__VA_ARGS__))
#define tmpnam(...) (pthread_testcancel(), tmpnam(__VA_ARGS__))
#define ttyname(...) (pthread_testcancel(), ttyname(__VA_ARGS__))
#define ttyname_r(...) (pthread_testcancel(), ttyname_r(__VA_ARGS__))
#define tzset(...) (pthread_testcancel(), tzset(__VA_ARGS__))
#define ungetc(...) (pthread_testcancel(), ungetc(__VA_ARGS__))
#define ungetwc(...) (pthread_testcancel(), ungetwc(__VA_ARGS__))
#define unlink(...) (pthread_testcancel(), unlink(__VA_ARGS__))
#define vfprintf(...) (pthread_testcancel(), vfprintf(__VA_ARGS__))
#define vfwprintf(...) (pthread_testcancel(), vfwprintf(__VA_ARGS__))
#define vprintf(...) (pthread_testcancel(), vprintf(__VA_ARGS__))
#define vwprintf(...) (pthread_testcancel(), vwprintf(__VA_ARGS__))
#define wcsftime(...) (pthread_testcancel(), wcsftime(__VA_ARGS__))
#define wordexp(...) (pthread_testcancel(), wordexp(__VA_ARGS__))
#define wprintf(...) (pthread_testcancel(), wprintf(__VA_ARGS__))
#define wscanf(...) (pthread_testcancel(), wscanf(__VA_ARGS__))
*/
#endif
/* WIN_PTHREADS */
libraries/pthreads/include/sched.h
deleted
100644 → 0
View file @
08945326
/*
* Module: sched.h
*
* Purpose:
* Provides an implementation of POSIX realtime extensions
* as defined in
*
* POSIX 1003.1b-1993 (POSIX.1b)
*
* --------------------------------------------------------------------------
*
* Pthreads-win32 - POSIX Threads Library for Win32
* Copyright(C) 1998 John E. Bossom
* Copyright(C) 1999,2005 Pthreads-win32 contributors
*
* Contact Email: rpj@callisto.canberra.edu.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.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifndef _SCHED_H
#define _SCHED_H
#undef PTW32_LEVEL
#if defined(_POSIX_SOURCE)
#define PTW32_LEVEL 0
/* Early POSIX */
#endif
#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309
#undef PTW32_LEVEL
#define PTW32_LEVEL 1
/* Include 1b, 1c and 1d */
#endif
#if defined(INCLUDE_NP)
#undef PTW32_LEVEL
#define PTW32_LEVEL 2
/* Include Non-Portable extensions */
#endif
#define PTW32_LEVEL_MAX 3
#if !defined(PTW32_LEVEL)
#define PTW32_LEVEL PTW32_LEVEL_MAX
/* Include everything */
#endif
#if __GNUC__ && ! defined (__declspec)
# error Please upgrade your GNU compiler to one that supports __declspec.
#endif
/*
* When building the DLL code, you should define PTW32_BUILD so that
* the variables/functions are exported correctly. When using the DLL,
* do NOT define PTW32_BUILD, and then the variables/functions will
* be imported correctly.
*/
#ifndef PTW32_STATIC_LIB
# ifdef PTW32_BUILD
# define PTW32_DLLPORT __declspec (dllexport)
# else
# define PTW32_DLLPORT __declspec (dllimport)
# endif
#else
# define PTW32_DLLPORT
#endif
/*
* This is a duplicate of what is in the autoconf config.h,
* which is only used when building the pthread-win32 libraries.
*/
#ifndef PTW32_CONFIG_H
# if defined(WINCE)
# define NEED_ERRNO
# define NEED_SEM
# endif
# if defined(_UWIN) || defined(__MINGW32__)
# define HAVE_MODE_T
# endif
#endif
/*
*
*/
#if PTW32_LEVEL >= PTW32_LEVEL_MAX
#ifdef NEED_ERRNO
#include "need_errno.h"
#else
#include <errno.h>
#endif
#endif
/* PTW32_LEVEL >= PTW32_LEVEL_MAX */
#if defined(__MINGW32__) || defined(_UWIN)
#if PTW32_LEVEL >= PTW32_LEVEL_MAX
/* For pid_t */
# include <sys/types.h>
/* Required by Unix 98 */
# include <time.h>
#endif
/* PTW32_LEVEL >= PTW32_LEVEL_MAX */
#else
typedef
int
pid_t
;
#endif
/* Thread scheduling policies */
enum
{
SCHED_OTHER
=
0
,
SCHED_FIFO
,
SCHED_RR
,
SCHED_MIN
=
SCHED_OTHER
,
SCHED_MAX
=
SCHED_RR
};
struct
sched_param
{
int
sched_priority
;
};
#ifdef __cplusplus
extern
"C"
{
#endif
/* __cplusplus */
PTW32_DLLPORT
int
__cdecl
sched_yield
(
void
);
PTW32_DLLPORT
int
__cdecl
sched_get_priority_min
(
int
policy
);
PTW32_DLLPORT
int
__cdecl
sched_get_priority_max
(
int
policy
);
PTW32_DLLPORT
int
__cdecl
sched_setscheduler
(
pid_t
pid
,
int
policy
);
PTW32_DLLPORT
int
__cdecl
sched_getscheduler
(
pid_t
pid
);
/*
* Note that this macro returns ENOTSUP rather than
* ENOSYS as might be expected. However, returning ENOSYS
* should mean that sched_get_priority_{min,max} are
* not implemented as well as sched_rr_get_interval.
* This is not the case, since we just don't support
* round-robin scheduling. Therefore I have chosen to
* return the same value as sched_setscheduler when
* SCHED_RR is passed to it.
*/
#define sched_rr_get_interval(_pid, _interval) \
( errno = ENOTSUP, (int) -1 )
#ifdef __cplusplus
}
/* End of extern "C" */
#endif
/* __cplusplus */
#undef PTW32_LEVEL
#undef PTW32_LEVEL_MAX
#endif
/* !_SCHED_H */
libraries/pthreads/include/semaphore.h
deleted
100644 → 0
View file @
08945326
/*
* Module: semaphore.h
*
* Purpose:
* Semaphores aren't actually part of the PThreads standard.
* They are defined by the POSIX Standard:
*
* POSIX 1003.1b-1993 (POSIX.1b)
*
* --------------------------------------------------------------------------
*
* Pthreads-win32 - POSIX Threads Library for Win32
* Copyright(C) 1998 John E. Bossom
* Copyright(C) 1999,2005 Pthreads-win32 contributors
*
* Contact Email: rpj@callisto.canberra.edu.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.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined( SEMAPHORE_H )
#define SEMAPHORE_H
#undef PTW32_LEVEL
#if defined(_POSIX_SOURCE)
#define PTW32_LEVEL 0
/* Early POSIX */
#endif
#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309
#undef PTW32_LEVEL
#define PTW32_LEVEL 1
/* Include 1b, 1c and 1d */
#endif
#if defined(INCLUDE_NP)
#undef PTW32_LEVEL
#define PTW32_LEVEL 2
/* Include Non-Portable extensions */
#endif
#define PTW32_LEVEL_MAX 3
#if !defined(PTW32_LEVEL)
#define PTW32_LEVEL PTW32_LEVEL_MAX
/* Include everything */
#endif
#if __GNUC__ && ! defined (__declspec)
# error Please upgrade your GNU compiler to one that supports __declspec.
#endif
/*
* When building the DLL code, you should define PTW32_BUILD so that
* the variables/functions are exported correctly. When using the DLL,
* do NOT define PTW32_BUILD, and then the variables/functions will
* be imported correctly.
*/
#ifndef PTW32_STATIC_LIB
# ifdef PTW32_BUILD
# define PTW32_DLLPORT __declspec (dllexport)
# else
# define PTW32_DLLPORT __declspec (dllimport)
# endif
#else
# define PTW32_DLLPORT
#endif
/*
* This is a duplicate of what is in the autoconf config.h,
* which is only used when building the pthread-win32 libraries.
*/
#ifndef PTW32_CONFIG_H
# if defined(WINCE)
# define NEED_ERRNO
# define NEED_SEM
# endif
# if defined(_UWIN) || defined(__MINGW32__)
# define HAVE_MODE_T
# endif
#endif
/*
*
*/
#if PTW32_LEVEL >= PTW32_LEVEL_MAX
#ifdef NEED_ERRNO
#include "need_errno.h"
#else
#include <errno.h>
#endif
#endif
/* PTW32_LEVEL >= PTW32_LEVEL_MAX */
#define _POSIX_SEMAPHORES
#ifdef __cplusplus
extern
"C"
{
#endif
/* __cplusplus */
#ifndef HAVE_MODE_T
typedef
unsigned
int
mode_t
;
#endif
typedef
struct
sem_t_
*
sem_t
;
PTW32_DLLPORT
int
__cdecl
sem_init
(
sem_t
*
sem
,
int
pshared
,
unsigned
int
value
);
PTW32_DLLPORT
int
__cdecl
sem_destroy
(
sem_t
*
sem
);
PTW32_DLLPORT
int
__cdecl
sem_trywait
(
sem_t
*
sem
);
PTW32_DLLPORT
int
__cdecl
sem_wait
(
sem_t
*
sem
);
PTW32_DLLPORT
int
__cdecl
sem_timedwait
(
sem_t
*
sem
,
const
struct
timespec
*
abstime
);
PTW32_DLLPORT
int
__cdecl
sem_post
(
sem_t
*
sem
);
PTW32_DLLPORT
int
__cdecl
sem_post_multiple
(
sem_t
*
sem
,
int
count
);
PTW32_DLLPORT
int
__cdecl
sem_open
(
const
char
*
name
,
int
oflag
,
mode_t
mode
,
unsigned
int
value
);
PTW32_DLLPORT
int
__cdecl
sem_close
(
sem_t
*
sem
);
PTW32_DLLPORT
int
__cdecl
sem_unlink
(
const
char
*
name
);
PTW32_DLLPORT
int
__cdecl
sem_getvalue
(
sem_t
*
sem
,
int
*
sval
);
#ifdef __cplusplus
}
/* End of extern "C" */
#endif
/* __cplusplus */
#undef PTW32_LEVEL
#undef PTW32_LEVEL_MAX
#endif
/* !SEMAPHORE_H */
libraries/pthreads/lib/pthreadVC2.dll
deleted
100644 → 0
View file @
08945326
File deleted
libraries/pthreads/lib/pthreadVC2.lib
deleted
100644 → 0
View file @
08945326
File deleted
libraries/pthreads/lib/pthreadVC2_static_mt.lib
deleted
100644 → 0
View file @
08945326
File deleted
libraries/pthreads/lib/pthreadVC2_x64.dll
deleted
100644 → 0
View file @
08945326
File deleted
libraries/pthreads/lib/pthreadVC2_x64.lib
deleted
100644 → 0
View file @
08945326
File deleted
libraries/pthreads/src/pthread.cpp
0 → 100644
View file @
6cf75568
#include "pthread.h"
PTHREAD_EXPORT
volatile
long
_pthread_cancelling
;
PTHREAD_EXPORT
int
_pthread_concur
;
/* Will default to zero as needed */
PTHREAD_EXPORT
pthread_once_t
_pthread_tls_once
;
PTHREAD_EXPORT
DWORD
_pthread_tls
;
/* Note initializer is zero, so this works */
PTHREAD_EXPORT
pthread_rwlock_t
_pthread_key_lock
;
PTHREAD_EXPORT
long
_pthread_key_max
;
PTHREAD_EXPORT
long
_pthread_key_sch
;
PTHREAD_EXPORT
void
(
**
_pthread_key_dest
)(
void
*
);
platforms/cpu/src/gmx_atomic.h
View file @
6cf75568
...
@@ -64,6 +64,7 @@
...
@@ -64,6 +64,7 @@
#include <stdio.h>
#include <stdio.h>
#define NOMINMAX
#include <pthread.h>
#include <pthread.h>
#ifdef __cplusplus
#ifdef __cplusplus
...
...
platforms/cuda/include/CudaContext.h
View file @
6cf75568
...
@@ -30,12 +30,12 @@
...
@@ -30,12 +30,12 @@
#include <map>
#include <map>
#include <queue>
#include <queue>
#include <string>
#include <string>
#include <pthread.h>
#define __CL_ENABLE_EXCEPTIONS
#define __CL_ENABLE_EXCEPTIONS
#ifdef _MSC_VER
#ifdef _MSC_VER
// Prevent Windows from defining macros that interfere with other code.
// Prevent Windows from defining macros that interfere with other code.
#define NOMINMAX
#define NOMINMAX
#endif
#endif
#include <pthread.h>
#include <cuda.h>
#include <cuda.h>
#include <builtin_types.h>
#include <builtin_types.h>
#include <vector_functions.h>
#include <vector_functions.h>
...
...
platforms/opencl/include/OpenCLContext.h
View file @
6cf75568
...
@@ -30,13 +30,13 @@
...
@@ -30,13 +30,13 @@
#include <map>
#include <map>
#include <queue>
#include <queue>
#include <string>
#include <string>
#include <pthread.h>
#define __CL_ENABLE_EXCEPTIONS
#define __CL_ENABLE_EXCEPTIONS
#define CL_USE_DEPRECATED_OPENCL_1_1_APIS
#define CL_USE_DEPRECATED_OPENCL_1_1_APIS
#ifdef _MSC_VER
#ifdef _MSC_VER
// Prevent Windows from defining macros that interfere with other code.
// Prevent Windows from defining macros that interfere with other code.
#define NOMINMAX
#define NOMINMAX
#endif
#endif
#include <pthread.h>
#include <cl.hpp>
#include <cl.hpp>
#include "windowsExportOpenCL.h"
#include "windowsExportOpenCL.h"
#include "OpenCLPlatform.h"
#include "OpenCLPlatform.h"
...
...
plugins/cpupme/src/CpuPmeKernels.h
View file @
6cf75568
...
@@ -32,6 +32,7 @@
...
@@ -32,6 +32,7 @@
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* -------------------------------------------------------------------------- */
* -------------------------------------------------------------------------- */
#define NOMINMAX
#include "internal/windowsExportPme.h"
#include "internal/windowsExportPme.h"
#include "openmm/kernels.h"
#include "openmm/kernels.h"
#include "openmm/Vec3.h"
#include "openmm/Vec3.h"
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment