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
08945326
"platforms/cuda/vscode:/vscode.git/clone" did not exist on "870fff2acca1cf78626a202a4de929e243b9c17c"
Commit
08945326
authored
May 15, 2015
by
peastman
Browse files
Attempting to get an alternate pthreads implementation to work
parent
0f76088d
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
1640 additions
and
0 deletions
+1640
-0
libraries/pthreads-2/include/pthread.h
libraries/pthreads-2/include/pthread.h
+1625
-0
libraries/pthreads-2/src/pthread.c
libraries/pthreads-2/src/pthread.c
+15
-0
No files found.
libraries/pthreads-2/include/pthread.h
0 → 100644
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
0 → 100644
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
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