mirror of https://github.com/lukechilds/node.git
202 changed files with 35350 additions and 49 deletions
Binary file not shown.
Binary file not shown.
@ -0,0 +1,13 @@ |
|||||
|
{ |
||||
|
'conditions': [ |
||||
|
['OS=="win"', { |
||||
|
'target_defaults': { |
||||
|
'msvs_settings': { |
||||
|
'VCLinkerTool': { |
||||
|
'GenerateDebugInformation': 'true', |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
}], # OS=="win" |
||||
|
], |
||||
|
} |
@ -0,0 +1,5 @@ |
|||||
|
CVS |
||||
|
*.obj |
||||
|
*.dll |
||||
|
*.lib |
||||
|
*.res |
@ -0,0 +1,482 @@ |
|||||
|
PTHREADS-WIN32 RELEASE 2.9.0 (2007-??-??) |
||||
|
----------------------------------------- |
||||
|
Web Site: http://sources.redhat.com/pthreads-win32/ |
||||
|
FTP Site: ftp://sources.redhat.com/pub/pthreads-win32 |
||||
|
Maintainer: Ross Johnson <rpj@callisto.canberra.edu.au> |
||||
|
|
||||
|
|
||||
|
We are pleased to announce the availability of a new release of |
||||
|
Pthreads-win32, an Open Source Software implementation of the |
||||
|
Threads component of the POSIX 1003.1 2001 Standard for Microsoft's |
||||
|
Win32 environment. Some functions from other sections of POSIX |
||||
|
1003.1 2001 are also supported including semaphores and scheduling |
||||
|
functions. |
||||
|
|
||||
|
Some common non-portable functions are also implemented for |
||||
|
additional compatibility, as are a few functions specific |
||||
|
to pthreads-win32 for easier integration with Win32 applications. |
||||
|
|
||||
|
Pthreads-win32 is free software, distributed under the GNU Lesser |
||||
|
General Public License (LGPL). |
||||
|
|
||||
|
|
||||
|
Acknowledgements |
||||
|
---------------- |
||||
|
This library is based originally on a Win32 pthreads |
||||
|
implementation contributed by John Bossom <John.Bossom@cognos.com>. |
||||
|
|
||||
|
The implementation of Condition Variables uses algorithms developed |
||||
|
by Alexander Terekhov and Louis Thomas. |
||||
|
|
||||
|
The implementation of POSIX mutexes has been improved by Thomas Pfaff |
||||
|
and later by Alexander Terekhov. |
||||
|
|
||||
|
The implementation of Spinlocks and Barriers was contributed |
||||
|
by Ross Johnson. |
||||
|
|
||||
|
The implementation of read/write locks was contributed by |
||||
|
Aurelio Medina and improved by Alexander Terekhov. |
||||
|
|
||||
|
Many others have contributed significant time and effort to solve crutial |
||||
|
problems in order to make the library workable, robust and reliable. |
||||
|
|
||||
|
Thanks to Xavier Leroy for granting permission to use and modify his |
||||
|
LinuxThreads manual pages. |
||||
|
|
||||
|
Thanks to The Open Group for making the Single Unix Specification |
||||
|
publicly available - many of the manual pages included in the package |
||||
|
were extracted from it. |
||||
|
|
||||
|
There is also a separate CONTRIBUTORS file. This file and others are |
||||
|
on the web site: |
||||
|
|
||||
|
http://sources.redhat.com/pthreads-win32 |
||||
|
|
||||
|
As much as possible, the ChangeLog file acknowledges contributions to the |
||||
|
code base in more detail. |
||||
|
|
||||
|
|
||||
|
Changes since the last release |
||||
|
------------------------------ |
||||
|
These are now documented in the NEWS file. |
||||
|
See the ChangeLog file also. |
||||
|
|
||||
|
|
||||
|
Known Bugs |
||||
|
---------- |
||||
|
These are now documented in the BUGS file. |
||||
|
|
||||
|
|
||||
|
Level of standards conformance |
||||
|
------------------------------ |
||||
|
|
||||
|
The following POSIX 1003.1 2001 options are defined and set to 200112L: |
||||
|
|
||||
|
_POSIX_THREADS |
||||
|
_POSIX_THREAD_SAFE_FUNCTIONS |
||||
|
_POSIX_THREAD_ATTR_STACKSIZE |
||||
|
_POSIX_THREAD_PRIORITY_SCHEDULING |
||||
|
_POSIX_SEMAPHORES |
||||
|
_POSIX_READER_WRITER_LOCKS |
||||
|
_POSIX_SPIN_LOCKS |
||||
|
_POSIX_BARRIERS |
||||
|
|
||||
|
|
||||
|
The following POSIX 1003.1 2001 options are defined and set to -1: |
||||
|
|
||||
|
_POSIX_THREAD_ATTR_STACKADDR |
||||
|
_POSIX_THREAD_PRIO_INHERIT |
||||
|
_POSIX_THREAD_PRIO_PROTECT |
||||
|
_POSIX_THREAD_PROCESS_SHARED |
||||
|
|
||||
|
|
||||
|
The following POSIX 1003.1 2001 limits are defined and set: |
||||
|
|
||||
|
_POSIX_THREAD_THREADS_MAX |
||||
|
_POSIX_SEM_VALUE_MAX |
||||
|
_POSIX_SEM_NSEMS_MAX |
||||
|
_POSIX_THREAD_KEYS_MAX |
||||
|
_POSIX_THREAD_DESTRUCTOR_ITERATIONS |
||||
|
PTHREAD_STACK_MIN |
||||
|
PTHREAD_THREADS_MAX |
||||
|
SEM_VALUE_MAX |
||||
|
SEM_NSEMS_MAX |
||||
|
PTHREAD_KEYS_MAX |
||||
|
PTHREAD_DESTRUCTOR_ITERATIONS |
||||
|
|
||||
|
|
||||
|
The following functions are implemented: |
||||
|
|
||||
|
--------------------------- |
||||
|
PThreads |
||||
|
--------------------------- |
||||
|
pthread_attr_init |
||||
|
pthread_attr_destroy |
||||
|
pthread_attr_getdetachstate |
||||
|
pthread_attr_getstackaddr |
||||
|
pthread_attr_getstacksize |
||||
|
pthread_attr_setdetachstate |
||||
|
pthread_attr_setstackaddr |
||||
|
pthread_attr_setstacksize |
||||
|
|
||||
|
pthread_create |
||||
|
pthread_detach |
||||
|
pthread_equal |
||||
|
pthread_exit |
||||
|
pthread_join |
||||
|
pthread_once |
||||
|
pthread_self |
||||
|
|
||||
|
pthread_cancel |
||||
|
pthread_cleanup_pop |
||||
|
pthread_cleanup_push |
||||
|
pthread_setcancelstate |
||||
|
pthread_setcanceltype |
||||
|
pthread_testcancel |
||||
|
|
||||
|
--------------------------- |
||||
|
Thread Specific Data |
||||
|
--------------------------- |
||||
|
pthread_key_create |
||||
|
pthread_key_delete |
||||
|
pthread_setspecific |
||||
|
pthread_getspecific |
||||
|
|
||||
|
--------------------------- |
||||
|
Mutexes |
||||
|
--------------------------- |
||||
|
pthread_mutexattr_init |
||||
|
pthread_mutexattr_destroy |
||||
|
pthread_mutexattr_getpshared |
||||
|
pthread_mutexattr_setpshared |
||||
|
pthread_mutexattr_gettype |
||||
|
pthread_mutexattr_settype (types: PTHREAD_MUTEX_DEFAULT |
||||
|
PTHREAD_MUTEX_NORMAL |
||||
|
PTHREAD_MUTEX_ERRORCHECK |
||||
|
PTHREAD_MUTEX_RECURSIVE ) |
||||
|
pthread_mutexattr_getrobust |
||||
|
pthread_mutexattr_setrobust (values: PTHREAD_MUTEX_STALLED |
||||
|
PTHREAD_MUTEX_ROBUST) |
||||
|
pthread_mutex_init |
||||
|
pthread_mutex_destroy |
||||
|
pthread_mutex_lock |
||||
|
pthread_mutex_trylock |
||||
|
pthread_mutex_timedlock |
||||
|
pthread_mutex_unlock |
||||
|
pthread_mutex_consistent |
||||
|
|
||||
|
--------------------------- |
||||
|
Condition Variables |
||||
|
--------------------------- |
||||
|
pthread_condattr_init |
||||
|
pthread_condattr_destroy |
||||
|
pthread_condattr_getpshared |
||||
|
pthread_condattr_setpshared |
||||
|
|
||||
|
pthread_cond_init |
||||
|
pthread_cond_destroy |
||||
|
pthread_cond_wait |
||||
|
pthread_cond_timedwait |
||||
|
pthread_cond_signal |
||||
|
pthread_cond_broadcast |
||||
|
|
||||
|
--------------------------- |
||||
|
Read/Write Locks |
||||
|
--------------------------- |
||||
|
pthread_rwlock_init |
||||
|
pthread_rwlock_destroy |
||||
|
pthread_rwlock_tryrdlock |
||||
|
pthread_rwlock_trywrlock |
||||
|
pthread_rwlock_rdlock |
||||
|
pthread_rwlock_timedrdlock |
||||
|
pthread_rwlock_rwlock |
||||
|
pthread_rwlock_timedwrlock |
||||
|
pthread_rwlock_unlock |
||||
|
pthread_rwlockattr_init |
||||
|
pthread_rwlockattr_destroy |
||||
|
pthread_rwlockattr_getpshared |
||||
|
pthread_rwlockattr_setpshared |
||||
|
|
||||
|
--------------------------- |
||||
|
Spin Locks |
||||
|
--------------------------- |
||||
|
pthread_spin_init |
||||
|
pthread_spin_destroy |
||||
|
pthread_spin_lock |
||||
|
pthread_spin_unlock |
||||
|
pthread_spin_trylock |
||||
|
|
||||
|
--------------------------- |
||||
|
Barriers |
||||
|
--------------------------- |
||||
|
pthread_barrier_init |
||||
|
pthread_barrier_destroy |
||||
|
pthread_barrier_wait |
||||
|
pthread_barrierattr_init |
||||
|
pthread_barrierattr_destroy |
||||
|
pthread_barrierattr_getpshared |
||||
|
pthread_barrierattr_setpshared |
||||
|
|
||||
|
--------------------------- |
||||
|
Semaphores |
||||
|
--------------------------- |
||||
|
sem_init |
||||
|
sem_destroy |
||||
|
sem_post |
||||
|
sem_wait |
||||
|
sem_trywait |
||||
|
sem_timedwait |
||||
|
sem_getvalue (# free if +ve, # of waiters if -ve) |
||||
|
sem_open (returns an error ENOSYS) |
||||
|
sem_close (returns an error ENOSYS) |
||||
|
sem_unlink (returns an error ENOSYS) |
||||
|
|
||||
|
--------------------------- |
||||
|
RealTime Scheduling |
||||
|
--------------------------- |
||||
|
pthread_attr_getschedparam |
||||
|
pthread_attr_setschedparam |
||||
|
pthread_attr_getinheritsched |
||||
|
pthread_attr_setinheritsched |
||||
|
pthread_attr_getschedpolicy (only supports SCHED_OTHER) |
||||
|
pthread_attr_setschedpolicy (only supports SCHED_OTHER) |
||||
|
pthread_getschedparam |
||||
|
pthread_setschedparam |
||||
|
pthread_getconcurrency |
||||
|
pthread_setconcurrency |
||||
|
pthread_attr_getscope |
||||
|
pthread_attr_setscope (only supports PTHREAD_SCOPE_SYSTEM) |
||||
|
sched_get_priority_max |
||||
|
sched_get_priority_min |
||||
|
sched_rr_get_interval (returns an error ENOTSUP) |
||||
|
sched_setscheduler (only supports SCHED_OTHER) |
||||
|
sched_getscheduler (only supports SCHED_OTHER) |
||||
|
sched_yield |
||||
|
|
||||
|
--------------------------- |
||||
|
Signals |
||||
|
--------------------------- |
||||
|
pthread_sigmask |
||||
|
pthread_kill (only supports zero sig value, |
||||
|
for thread validity checking) |
||||
|
|
||||
|
--------------------------- |
||||
|
Non-portable routines (see the README.NONPORTABLE file for usage) |
||||
|
--------------------------- |
||||
|
pthread_getw32threadhandle_np |
||||
|
pthread_timechange_handler_np |
||||
|
pthread_delay_np |
||||
|
pthread_getunique_np |
||||
|
pthread_mutexattr_getkind_np |
||||
|
pthread_mutexattr_setkind_np (types: PTHREAD_MUTEX_FAST_NP, |
||||
|
PTHREAD_MUTEX_ERRORCHECK_NP, |
||||
|
PTHREAD_MUTEX_RECURSIVE_NP, |
||||
|
PTHREAD_MUTEX_ADAPTIVE_NP, |
||||
|
PTHREAD_MUTEX_TIMED_NP) |
||||
|
pthread_num_processors_np |
||||
|
pthread_win32_process_attach_np (Required when statically linking |
||||
|
the library) |
||||
|
pthread_win32_process_detach_np (Required when statically linking |
||||
|
the library) |
||||
|
pthread_win32_thread_attach_np (Required when statically linking |
||||
|
the library) |
||||
|
pthread_win32_thread_detach_np (Required when statically linking |
||||
|
the library) |
||||
|
|
||||
|
--------------------------- |
||||
|
Static Initializers |
||||
|
--------------------------- |
||||
|
PTHREAD_ONCE_INIT |
||||
|
PTHREAD_MUTEX_INITIALIZER |
||||
|
PTHREAD_RECURSIVE_MUTEX_INITIALIZER |
||||
|
PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP |
||||
|
PTHREAD_ERRORCHECK_MUTEX_INITIALIZER |
||||
|
PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP |
||||
|
PTHREAD_COND_INITIALIZER |
||||
|
PTHREAD_RWLOCK_INITIALIZER |
||||
|
PTHREAD_SPINLOCK_INITIALIZER |
||||
|
|
||||
|
|
||||
|
The library includes two non-API functions for creating cancellation |
||||
|
points in applications and libraries: |
||||
|
|
||||
|
pthreadCancelableWait |
||||
|
pthreadCancelableTimedWait |
||||
|
|
||||
|
|
||||
|
The following functions are not implemented: |
||||
|
|
||||
|
--------------------------- |
||||
|
RealTime Scheduling |
||||
|
--------------------------- |
||||
|
pthread_mutex_getprioceiling |
||||
|
pthread_mutex_setprioceiling |
||||
|
pthread_mutex_attr_getprioceiling |
||||
|
pthread_mutex_attr_getprotocol |
||||
|
pthread_mutex_attr_setprioceiling |
||||
|
pthread_mutex_attr_setprotocol |
||||
|
|
||||
|
--------------------------- |
||||
|
Fork Handlers |
||||
|
--------------------------- |
||||
|
pthread_atfork |
||||
|
|
||||
|
--------------------------- |
||||
|
Stdio |
||||
|
--------------------------- |
||||
|
flockfile |
||||
|
ftrylockfile |
||||
|
funlockfile |
||||
|
getc_unlocked |
||||
|
getchar_unlocked |
||||
|
putc_unlocked |
||||
|
putchar_unlocked |
||||
|
|
||||
|
--------------------------- |
||||
|
Thread-Safe C Runtime Library |
||||
|
--------------------------- |
||||
|
readdir_r |
||||
|
getgrgid_r |
||||
|
getgrnam_r |
||||
|
getpwuid_r |
||||
|
getpwnam_r |
||||
|
|
||||
|
--------------------------- |
||||
|
Signals |
||||
|
--------------------------- |
||||
|
sigtimedwait |
||||
|
sigwait |
||||
|
sigwaitinfo |
||||
|
|
||||
|
--------------------------- |
||||
|
General |
||||
|
--------------------------- |
||||
|
sysconf |
||||
|
|
||||
|
--------------------------- |
||||
|
Thread-Safe C Runtime Library (macros) |
||||
|
--------------------------- |
||||
|
strtok_r |
||||
|
asctime_r |
||||
|
ctime_r |
||||
|
gmtime_r |
||||
|
localtime_r |
||||
|
rand_r |
||||
|
|
||||
|
|
||||
|
Availability |
||||
|
------------ |
||||
|
|
||||
|
The prebuilt DLL, export libs (for both MSVC and Mingw32), and the header |
||||
|
files (pthread.h, semaphore.h, sched.h) are available along with the |
||||
|
complete source code. |
||||
|
|
||||
|
The source code can be found at: |
||||
|
|
||||
|
ftp://sources.redhat.com/pub/pthreads-win32 |
||||
|
|
||||
|
and as individual source code files at |
||||
|
|
||||
|
ftp://sources.redhat.com/pub/pthreads-win32/source |
||||
|
|
||||
|
The pre-built DLL, export libraries and include files can be found at: |
||||
|
|
||||
|
ftp://sources.redhat.com/pub/pthreads-win32/dll-latest |
||||
|
|
||||
|
|
||||
|
|
||||
|
Mailing List |
||||
|
------------ |
||||
|
|
||||
|
There is a mailing list for discussing pthreads on Win32. To join, |
||||
|
send email to: |
||||
|
|
||||
|
pthreads-win32-subscribe@sourceware.cygnus.com |
||||
|
|
||||
|
|
||||
|
Application Development Environments |
||||
|
------------------------------------ |
||||
|
|
||||
|
See the README file for more information. |
||||
|
|
||||
|
MSVC: |
||||
|
MSVC using SEH works. Distribute pthreadVSE.dll with your application. |
||||
|
MSVC using C++ EH works. Distribute pthreadVCE.dll with your application. |
||||
|
MSVC using C setjmp/longjmp works. Distribute pthreadVC.dll with your application. |
||||
|
|
||||
|
|
||||
|
Mingw32: |
||||
|
See the FAQ, Questions 6 and 10. |
||||
|
|
||||
|
Mingw using C++ EH works. Distribute pthreadGCE.dll with your application. |
||||
|
Mingw using C setjmp/longjmp works. Distribute pthreadGC.dll with your application. |
||||
|
|
||||
|
|
||||
|
Cygwin: (http://sourceware.cygnus.com/cygwin/) |
||||
|
Developers using Cygwin do not need pthreads-win32 since it has POSIX threads |
||||
|
support. Refer to its documentation for details and extent. |
||||
|
|
||||
|
|
||||
|
UWIN: |
||||
|
UWIN is a complete Unix-like environment for Windows from AT&T. Pthreads-win32 |
||||
|
doesn't currently support UWIN (and vice versa), but that may change in the |
||||
|
future. |
||||
|
|
||||
|
Generally: |
||||
|
For convenience, the following pre-built files are available on the FTP site |
||||
|
(see Availability above): |
||||
|
|
||||
|
pthread.h - for POSIX threads |
||||
|
semaphore.h - for POSIX semaphores |
||||
|
sched.h - for POSIX scheduling |
||||
|
pthreadVCE.dll - built with MSVC++ compiler using C++ EH |
||||
|
pthreadVCE.lib |
||||
|
pthreadVC.dll - built with MSVC compiler using C setjmp/longjmp |
||||
|
pthreadVC.lib |
||||
|
pthreadVSE.dll - built with MSVC compiler using SEH |
||||
|
pthreadVSE.lib |
||||
|
pthreadGCE.dll - built with Mingw32 G++ 2.95.2-1 |
||||
|
pthreadGC.dll - built with Mingw32 GCC 2.95.2-1 using setjmp/longjmp |
||||
|
libpthreadGCE.a - derived from pthreadGCE.dll |
||||
|
libpthreadGC.a - derived from pthreadGC.dll |
||||
|
gcc.dll - needed if distributing applications that use |
||||
|
pthreadGCE.dll (but see the FAQ Q 10 for the latest |
||||
|
related information) |
||||
|
|
||||
|
These are the only files you need in order to build POSIX threads |
||||
|
applications for Win32 using either MSVC or Mingw32. |
||||
|
|
||||
|
See the FAQ file in the source tree for additional information. |
||||
|
|
||||
|
|
||||
|
Documentation |
||||
|
------------- |
||||
|
|
||||
|
For the authoritative reference, see the online POSIX |
||||
|
standard reference at: |
||||
|
|
||||
|
http://www.OpenGroup.org |
||||
|
|
||||
|
For POSIX Thread API programming, several reference books are |
||||
|
available: |
||||
|
|
||||
|
Programming with POSIX Threads |
||||
|
David R. Butenhof |
||||
|
Addison-Wesley (pub) |
||||
|
|
||||
|
Pthreads Programming |
||||
|
By Bradford Nichols, Dick Buttlar & Jacqueline Proulx Farrell |
||||
|
O'Reilly (pub) |
||||
|
|
||||
|
On the web: see the links at the bottom of the pthreads-win32 site: |
||||
|
|
||||
|
http://sources.redhat.com/pthreads-win32/ |
||||
|
|
||||
|
Currently, there is no documentation included in the package apart |
||||
|
from the copious comments in the source code. |
||||
|
|
||||
|
|
||||
|
|
||||
|
Enjoy! |
||||
|
|
||||
|
Ross Johnson |
@ -0,0 +1,141 @@ |
|||||
|
---------- |
||||
|
Known bugs |
||||
|
---------- |
||||
|
|
||||
|
1. Not strictly a bug, more of a gotcha. |
||||
|
|
||||
|
Under MS VC++ (only tested with version 6.0), a term_func |
||||
|
set via the standard C++ set_terminate() function causes the |
||||
|
application to abort. |
||||
|
|
||||
|
Notes from the MSVC++ manual: |
||||
|
1) A term_func() should call exit(), otherwise |
||||
|
abort() will be called on return to the caller. |
||||
|
A call to abort() raises SIGABRT and the default signal handler |
||||
|
for all signals terminates the calling program with |
||||
|
exit code 3. |
||||
|
2) A term_func() must not throw an exception. Therefore |
||||
|
term_func() should not call pthread_exit(), which |
||||
|
works by throwing an exception (pthreadVCE or pthreadVSE) |
||||
|
or by calling longjmp (pthreadVC). |
||||
|
|
||||
|
Workaround: avoid using pthread_exit() in C++ applications. Exit |
||||
|
threads by dropping through the end of the thread routine. |
||||
|
|
||||
|
2. Cancellation problems in C++ builds |
||||
|
- Milan Gardian |
||||
|
|
||||
|
[Note: It's not clear if this problem isn't simply due to the context |
||||
|
switch in pthread_cancel() which occurs unless the QueueUserAPCEx |
||||
|
library and driver are installed and used. Just like setjmp/longjmp, |
||||
|
this is probably not going to work well in C++. In any case, unless for |
||||
|
some very unusual reason you really must use the C++ build then please |
||||
|
use the C build pthreadVC2.dll or pthreadGC2.dll, i.e. for C++ |
||||
|
applications.] |
||||
|
|
||||
|
This is suspected to be a compiler bug in VC6.0, and also seen in |
||||
|
VC7.0 and VS .NET 2003. The GNU C++ compiler does not have a problem |
||||
|
with this, and it has been reported that the Intel C++ 8.1 compiler |
||||
|
and Visual C++ 2005 Express Edition Beta2 pass tests\semaphore4.c |
||||
|
(which exposes the bug). |
||||
|
|
||||
|
Workaround [rpj - 2 Feb 2002] |
||||
|
----------------------------- |
||||
|
[Please note: this workaround did not solve a similar problem in |
||||
|
snapshot-2004-11-03 or later, even though similar symptoms were seen. |
||||
|
tests\semaphore4.c fails in that snapshot for the VCE version of the |
||||
|
DLL.] |
||||
|
|
||||
|
The problem disappears when /Ob0 is used, i.e. /O2 /Ob0 works OK, |
||||
|
but if you want to use inlining optimisation you can be much more |
||||
|
specific about where it's switched off and on by using a pragma. |
||||
|
|
||||
|
So the inlining optimisation is interfering with the way that cleanup |
||||
|
handlers are run. It appears to relate to auto-inlining of class methods |
||||
|
since this is the only auto inlining that is performed at /O1 optimisation |
||||
|
(functions with the "inline" qualifier are also inlined, but the problem |
||||
|
doesn't appear to involve any such functions in the library or testsuite). |
||||
|
|
||||
|
In order to confirm the inlining culprit, the following use of pragmas |
||||
|
eliminate the problem but I don't know how to make it transparent, putting |
||||
|
it in, say, pthread.h where pthread_cleanup_push defined as a macro. |
||||
|
|
||||
|
#pragma inline_depth(0) |
||||
|
pthread_cleanup_push(handlerFunc, (void *) &arg); |
||||
|
|
||||
|
/* ... */ |
||||
|
|
||||
|
pthread_cleanup_pop(0); |
||||
|
#pragma inline_depth() |
||||
|
|
||||
|
Note the empty () pragma value after the pop macro. This resets depth to the |
||||
|
default. Or you can specify a non-zero depth here. |
||||
|
|
||||
|
The pragma is also needed (and now used) within the library itself wherever |
||||
|
cleanup handlers are used (condvar.c and rwlock.c). |
||||
|
|
||||
|
Use of these pragmas allows compiler optimisations /O1 and /O2 to be |
||||
|
used for either or both the library and applications. |
||||
|
|
||||
|
Experimenting further, I found that wrapping the actual cleanup handler |
||||
|
function with #pragma auto_inline(off|on) does NOT work. |
||||
|
|
||||
|
MSVC6.0 doesn't appear to support the C99 standard's _Pragma directive, |
||||
|
however, later versions may. This form is embeddable inside #define |
||||
|
macros, which would be ideal because it would mean that it could be added |
||||
|
to the push/pop macro definitions in pthread.h and hidden from the |
||||
|
application programmer. |
||||
|
|
||||
|
[/rpj] |
||||
|
|
||||
|
Original problem description |
||||
|
---------------------------- |
||||
|
|
||||
|
The cancellation (actually, cleanup-after-cancel) tests fail when using VC |
||||
|
(professional) optimisation switches (/O1 or /O2) in pthreads library. I |
||||
|
have not investigated which concrete optimisation technique causes this |
||||
|
problem (/Og, /Oi, /Ot, /Oy, /Ob1, /Gs, /Gf, /Gy, etc.), but here is a |
||||
|
summary of builds and corresponding failures: |
||||
|
|
||||
|
* pthreads VSE (optimised tests): OK |
||||
|
* pthreads VCE (optimised tests): Failed "cleanup1" test (runtime) |
||||
|
|
||||
|
* pthreads VSE (DLL in CRT, optimised tests): OK |
||||
|
* pthreads VCE (DLL in CRT, optimised tests): Failed "cleanup1" test |
||||
|
(runtime) |
||||
|
|
||||
|
Please note that while in VSE version of the pthreads library the |
||||
|
optimisation does not really have any impact on the tests (they pass OK), in |
||||
|
VCE version addition of optimisation (/O2 in this case) causes the tests to |
||||
|
fail uniformly - either in "cleanup0" or "cleanup1" test cases. |
||||
|
|
||||
|
Please note that all the tests above use default pthreads DLL (no |
||||
|
optimisations, linked with either static or DLL CRT, based on test type). |
||||
|
Therefore the problem lies not within the pthreads DLL but within the |
||||
|
compiled client code (the application using pthreads -> involvement of |
||||
|
"pthread.h"). |
||||
|
|
||||
|
I think the message of this section is that usage of VCE version of pthreads |
||||
|
in applications relying on cancellation/cleanup AND using optimisations for |
||||
|
creation of production code is highly unreliable for the current version of |
||||
|
the pthreads library. |
||||
|
|
||||
|
3. The Borland Builder 5.5 version of the library produces memory read exceptions |
||||
|
in some tests. |
||||
|
|
||||
|
4. pthread_barrier_wait() can deadlock if the number of potential calling |
||||
|
threads for a particular barrier is greater than the barrier count parameter |
||||
|
given to pthread_barrier_init() for that barrier. |
||||
|
|
||||
|
This is due to the very lightweight implementation of pthread-win32 barriers. |
||||
|
To cope with more than "count" possible waiters, barriers must effectively |
||||
|
implement all the same safeguards as condition variables, making them much |
||||
|
"heavier" than at present. |
||||
|
|
||||
|
The workaround is to ensure that no more than "count" threads attempt to wait |
||||
|
at the barrier. |
||||
|
|
||||
|
5. Canceling a thread blocked on pthread_once appears not to work in the MSVC++ |
||||
|
version of the library "pthreadVCE.dll". The test case "once3.c" hangs. I have no |
||||
|
clues on this at present. All other versions pass this test ok - pthreadsVC.dll, |
||||
|
pthreadsVSE.dll, pthreadsGC.dll and pthreadsGCE.dll. |
@ -0,0 +1,268 @@ |
|||||
|
# This makefile is compatible with BCB make. Use "make -fBMakefile" to compile. |
||||
|
# |
||||
|
# The variables $DLLDEST and $LIBDEST hold the destination directories for the |
||||
|
# dll and the lib, respectively. Probably all that needs to change is $DEVROOT. |
||||
|
# |
||||
|
# Currently only the recommended pthreadBC.dll is built by this makefile. |
||||
|
# |
||||
|
|
||||
|
|
||||
|
DLL_VER = 2 |
||||
|
|
||||
|
DEVROOT = . |
||||
|
|
||||
|
DLLDEST = $(DEVROOT)\DLL |
||||
|
LIBDEST = $(DEVROOT)\DLL |
||||
|
|
||||
|
DLLS = pthreadBC$(DLL_VER).dll |
||||
|
|
||||
|
OPTIM = /O2 |
||||
|
|
||||
|
RC = brcc32 |
||||
|
RCFLAGS = -i. |
||||
|
|
||||
|
CFLAGS = /q /I. /D_WIN32_WINNT=0x400 /DHAVE_PTW32_CONFIG_H=1 /4 /tWD /tWM \ |
||||
|
/w-aus /w-asc /w-par |
||||
|
|
||||
|
#C cleanup code |
||||
|
BCFLAGS = $(PTW32_FLAGS) $(CFLAGS) |
||||
|
|
||||
|
# Agregate modules for inlinability |
||||
|
DLL_OBJS = \ |
||||
|
attr.obj \ |
||||
|
barrier.obj \ |
||||
|
cancel.obj \ |
||||
|
cleanup.obj \ |
||||
|
condvar.obj \ |
||||
|
create.obj \ |
||||
|
dll.obj \ |
||||
|
errno.obj \ |
||||
|
exit.obj \ |
||||
|
fork.obj \ |
||||
|
global.obj \ |
||||
|
misc.obj \ |
||||
|
mutex.obj \ |
||||
|
nonportable.obj \ |
||||
|
private.obj \ |
||||
|
rwlock.obj \ |
||||
|
sched.obj \ |
||||
|
semaphore.obj \ |
||||
|
signal.obj \ |
||||
|
spin.obj \ |
||||
|
sync.obj \ |
||||
|
tsd.obj |
||||
|
|
||||
|
INCL = config.h implement.h semaphore.h pthread.h need_errno.h |
||||
|
|
||||
|
ATTR_SRCS = \ |
||||
|
pthread_attr_init.c \ |
||||
|
pthread_attr_destroy.c \ |
||||
|
pthread_attr_getdetachstate.c \ |
||||
|
pthread_attr_setdetachstate.c \ |
||||
|
pthread_attr_getstackaddr.c \ |
||||
|
pthread_attr_setstackaddr.c \ |
||||
|
pthread_attr_getstacksize.c \ |
||||
|
pthread_attr_setstacksize.c \ |
||||
|
pthread_attr_getscope.c \ |
||||
|
pthread_attr_setscope.c |
||||
|
|
||||
|
BARRIER_SRCS = \ |
||||
|
pthread_barrier_init.c \ |
||||
|
pthread_barrier_destroy.c \ |
||||
|
pthread_barrier_wait.c \ |
||||
|
pthread_barrierattr_init.c \ |
||||
|
pthread_barrierattr_destroy.c \ |
||||
|
pthread_barrierattr_setpshared.c \ |
||||
|
pthread_barrierattr_getpshared.c |
||||
|
|
||||
|
CANCEL_SRCS = \ |
||||
|
pthread_setcancelstate.c \ |
||||
|
pthread_setcanceltype.c \ |
||||
|
pthread_testcancel.c \ |
||||
|
pthread_cancel.c |
||||
|
|
||||
|
CONDVAR_SRCS = \ |
||||
|
ptw32_cond_check_need_init.c \ |
||||
|
pthread_condattr_destroy.c \ |
||||
|
pthread_condattr_getpshared.c \ |
||||
|
pthread_condattr_init.c \ |
||||
|
pthread_condattr_setpshared.c \ |
||||
|
pthread_cond_destroy.c \ |
||||
|
pthread_cond_init.c \ |
||||
|
pthread_cond_signal.c \ |
||||
|
pthread_cond_wait.c |
||||
|
|
||||
|
EXIT_SRCS = \ |
||||
|
pthread_exit.c |
||||
|
|
||||
|
MISC_SRCS = \ |
||||
|
pthread_equal.c \ |
||||
|
pthread_getconcurrency.c \ |
||||
|
pthread_once.c \ |
||||
|
pthread_self.c \ |
||||
|
pthread_setconcurrency.c \ |
||||
|
ptw32_calloc.c \ |
||||
|
ptw32_MCS_lock.c \ |
||||
|
ptw32_new.c \ |
||||
|
w32_CancelableWait.c |
||||
|
|
||||
|
MUTEX_SRCS = \ |
||||
|
ptw32_mutex_check_need_init.c \ |
||||
|
pthread_mutex_init.c \ |
||||
|
pthread_mutex_destroy.c \ |
||||
|
pthread_mutexattr_init.c \ |
||||
|
pthread_mutexattr_destroy.c \ |
||||
|
pthread_mutexattr_getpshared.c \ |
||||
|
pthread_mutexattr_setpshared.c \ |
||||
|
pthread_mutexattr_settype.c \ |
||||
|
pthread_mutexattr_gettype.c \ |
||||
|
pthread_mutexattr_setrobust.c \ |
||||
|
pthread_mutexattr_getrobust.c \ |
||||
|
pthread_mutex_lock.c \ |
||||
|
pthread_mutex_timedlock.c \ |
||||
|
pthread_mutex_unlock.c \ |
||||
|
pthread_mutex_trylock.c \ |
||||
|
pthread_mutex_consistent.c |
||||
|
|
||||
|
NONPORTABLE_SRCS = \ |
||||
|
pthread_mutexattr_setkind_np.c \ |
||||
|
pthread_mutexattr_getkind_np.c \ |
||||
|
pthread_getw32threadhandle_np.c \ |
||||
|
pthread_delay_np.c \ |
||||
|
pthread_num_processors_np.c \ |
||||
|
pthread_win32_attach_detach_np.c \ |
||||
|
pthread_timechange_handler_np.c |
||||
|
|
||||
|
PRIVATE_SRCS = \ |
||||
|
ptw32_is_attr.c \ |
||||
|
ptw32_processInitialize.c \ |
||||
|
ptw32_processTerminate.c \ |
||||
|
ptw32_threadStart.c \ |
||||
|
ptw32_threadDestroy.c \ |
||||
|
ptw32_tkAssocCreate.c \ |
||||
|
ptw32_tkAssocDestroy.c \ |
||||
|
ptw32_callUserDestroyRoutines.c \ |
||||
|
ptw32_timespec.c \ |
||||
|
ptw32_relmillisecs.c \ |
||||
|
ptw32_throw.c \ |
||||
|
ptw32_getprocessors.c |
||||
|
|
||||
|
RWLOCK_SRCS = \ |
||||
|
ptw32_rwlock_check_need_init.c \ |
||||
|
ptw32_rwlock_cancelwrwait.c \ |
||||
|
pthread_rwlock_init.c \ |
||||
|
pthread_rwlock_destroy.c \ |
||||
|
pthread_rwlockattr_init.c \ |
||||
|
pthread_rwlockattr_destroy.c \ |
||||
|
pthread_rwlockattr_getpshared.c \ |
||||
|
pthread_rwlockattr_setpshared.c \ |
||||
|
pthread_rwlock_rdlock.c \ |
||||
|
pthread_rwlock_timedrdlock.c \ |
||||
|
pthread_rwlock_wrlock.c \ |
||||
|
pthread_rwlock_timedwrlock.c \ |
||||
|
pthread_rwlock_unlock.c \ |
||||
|
pthread_rwlock_tryrdlock.c \ |
||||
|
pthread_rwlock_trywrlock.c |
||||
|
|
||||
|
SCHED_SRCS = \ |
||||
|
pthread_attr_setschedpolicy.c \ |
||||
|
pthread_attr_getschedpolicy.c \ |
||||
|
pthread_attr_setschedparam.c \ |
||||
|
pthread_attr_getschedparam.c \ |
||||
|
pthread_attr_setinheritsched.c \ |
||||
|
pthread_attr_getinheritsched.c \ |
||||
|
pthread_setschedparam.c \ |
||||
|
pthread_getschedparam.c \ |
||||
|
sched_get_priority_max.c \ |
||||
|
sched_get_priority_min.c \ |
||||
|
sched_setscheduler.c \ |
||||
|
sched_getscheduler.c \ |
||||
|
sched_yield.c |
||||
|
|
||||
|
SEMAPHORE_SRCS = \ |
||||
|
sem_init.c \ |
||||
|
sem_destroy.c \ |
||||
|
sem_trywait.c \ |
||||
|
sem_timedwait.c \ |
||||
|
sem_wait.c \ |
||||
|
sem_post.c \ |
||||
|
sem_post_multiple.c \ |
||||
|
sem_getvalue.c \ |
||||
|
sem_open.c \ |
||||
|
sem_close.c \ |
||||
|
sem_unlink.c |
||||
|
|
||||
|
SPIN_SRCS = \ |
||||
|
ptw32_spinlock_check_need_init.c \ |
||||
|
pthread_spin_init.c \ |
||||
|
pthread_spin_destroy.c \ |
||||
|
pthread_spin_lock.c \ |
||||
|
pthread_spin_unlock.c \ |
||||
|
pthread_spin_trylock.c |
||||
|
|
||||
|
SYNC_SRCS = \ |
||||
|
pthread_detach.c \ |
||||
|
pthread_join.c |
||||
|
|
||||
|
TSD_SRCS = \ |
||||
|
pthread_key_create.c \ |
||||
|
pthread_key_delete.c \ |
||||
|
pthread_setspecific.c \ |
||||
|
pthread_getspecific.c |
||||
|
|
||||
|
|
||||
|
all: clean $(DLLS) |
||||
|
|
||||
|
realclean: clean |
||||
|
if exist pthread*.dll del pthread*.dll |
||||
|
if exist pthread*.lib del pthread*.lib |
||||
|
if exist *.stamp del *.stamp |
||||
|
|
||||
|
clean: |
||||
|
if exist *.obj del *.obj |
||||
|
if exist *.ilk del *.ilk |
||||
|
if exist *.ilc del *.ilc |
||||
|
if exist *.ild del *.ild |
||||
|
if exist *.ilf del *.ilf |
||||
|
if exist *.ils del *.ils |
||||
|
if exist *.tds del *.tds |
||||
|
if exist *.pdb del *.pdb |
||||
|
if exist *.exp del *.exp |
||||
|
if exist *.map del *.map |
||||
|
if exist *.o del *.o |
||||
|
if exist *.i del *.i |
||||
|
if exist *.res del *.res |
||||
|
|
||||
|
|
||||
|
install: $(DLLS) |
||||
|
copy pthread*.dll $(DLLDEST) |
||||
|
copy pthread*.lib $(LIBDEST) |
||||
|
|
||||
|
$(DLLS): $(DLL_OBJS) version.res |
||||
|
ilink32 /Tpd /Gi c0d32x.obj $(DLL_OBJS), \ |
||||
|
$@, ,\ |
||||
|
cw32mti.lib import32.lib, ,\ |
||||
|
version.res |
||||
|
|
||||
|
.c.obj: |
||||
|
$(CC) $(OPTIM) $(BCFLAGS) -c $< |
||||
|
|
||||
|
.rc.res: |
||||
|
$(RC) $(RCFLAGS) $< |
||||
|
|
||||
|
attr.obj: attr.c $(ATTR_SRCS) $(INCL) |
||||
|
barrier.obj: barrier.c $(BARRIER_SRCS) $(INCL) |
||||
|
cancel.obj: cancel.c $(CANCEL_SRCS) $(INCL) |
||||
|
condvar.obj: condvar.c $(CONDVAR_SRCS) $(INCL) |
||||
|
exit.obj: exit.c $(EXIT_SRCS) $(INCL) |
||||
|
misc.obj: misc.c $(MISC_SRCS) $(INCL) |
||||
|
mutex.obj: mutex.c $(MUTEX_SRCS) $(INCL) |
||||
|
nonportable.obj: nonportable.c $(NONPORTABLE_SRCS) $(INCL) |
||||
|
private.obj: private.c $(PRIVATE_SRCS) $(INCL) |
||||
|
rwlock.obj: rwlock.c $(RWLOCK_SRCS) $(INCL) |
||||
|
sched.obj: sched.c $(SCHED_SRCS) $(INCL) |
||||
|
semaphore.obj: semaphore.c $(SEMAPHORE_SRCS) $(INCL) |
||||
|
spin.obj: spin.c $(SPIN_SRCS) $(INCL) |
||||
|
sync.obj: sync.c $(SYNC_SRCS) $(INCL) |
||||
|
tsd.obj: tsd.c $(TSD_SRCS) $(INCL) |
||||
|
version.res: version.rc $(INCL) |
@ -0,0 +1,140 @@ |
|||||
|
Contributors (in approximate order of appearance) |
||||
|
|
||||
|
[See also the ChangeLog file where individuals are |
||||
|
attributed in log entries. Likewise in the FAQ file.] |
||||
|
|
||||
|
Ben Elliston bje at cygnus dot com |
||||
|
Initiated the project; |
||||
|
setup the project infrastructure (CVS, web page, etc.); |
||||
|
early prototype routines. |
||||
|
Ross Johnson Ross dot Johnson at dot homemail dot com dot au |
||||
|
early prototype routines; |
||||
|
ongoing project coordination/maintenance; |
||||
|
implementation of spin locks and barriers; |
||||
|
various enhancements; |
||||
|
bug fixes; |
||||
|
documentation; |
||||
|
testsuite. |
||||
|
Robert Colquhoun rjc at trump dot net dot au |
||||
|
Early bug fixes. |
||||
|
John E. Bossom John dot Bossom at cognos dot com |
||||
|
Contributed substantial original working implementation; |
||||
|
bug fixes; |
||||
|
ongoing guidance and standards interpretation. |
||||
|
Anders Norlander anorland at hem2 dot passagen dot se |
||||
|
Early enhancements and runtime checking for supported |
||||
|
Win32 routines. |
||||
|
Tor Lillqvist tml at iki dot fi |
||||
|
General enhancements; |
||||
|
early bug fixes to condition variables. |
||||
|
Scott Lightner scott at curriculum dot com |
||||
|
Bug fix. |
||||
|
Kevin Ruland Kevin dot Ruland at anheuser-busch dot com |
||||
|
Various bug fixes. |
||||
|
Mike Russo miker at eai dot com |
||||
|
Bug fix. |
||||
|
Mark E. Armstrong avail at pacbell dot net |
||||
|
Bug fixes. |
||||
|
Lorin Hochstein lmh at xiphos dot ca |
||||
|
general bug fixes; bug fixes to condition variables. |
||||
|
Peter Slacik Peter dot Slacik at tatramed dot sk |
||||
|
Bug fixes. |
||||
|
Mumit Khan khan at xraylith dot wisc dot edu |
||||
|
Fixes to work with Mingw32. |
||||
|
Milan Gardian mg at tatramed dot sk |
||||
|
Bug fixes and reports/analyses of obscure problems. |
||||
|
Aurelio Medina aureliom at crt dot com |
||||
|
First implementation of read-write locks. |
||||
|
Graham Dumpleton Graham dot Dumpleton at ra dot pad dot otc dot telstra dot com dot au |
||||
|
Bug fix in condition variables. |
||||
|
Tristan Savatier tristan at mpegtv dot com |
||||
|
WinCE port. |
||||
|
Erik Hensema erik at hensema dot xs4all dot nl |
||||
|
Bug fixes. |
||||
|
Rich Peters rpeters at micro-magic dot com |
||||
|
Todd Owen towen at lucidcalm dot dropbear dot id dot au |
||||
|
Bug fixes to dll loading. |
||||
|
Jason Nye jnye at nbnet dot nb dot ca |
||||
|
Implementation of async cancelation. |
||||
|
Fred Forester fforest at eticomm dot net |
||||
|
Kevin D. Clark kclark at cabletron dot com |
||||
|
David Baggett dmb at itasoftware dot com |
||||
|
Bug fixes. |
||||
|
Paul Redondo paul at matchvision dot com |
||||
|
Scott McCaskill scott at 3dfx dot com |
||||
|
Bug fixes. |
||||
|
Jef Gearhart jgearhart at tpssys dot com |
||||
|
Bug fix. |
||||
|
Arthur Kantor akantor at bexusa dot com |
||||
|
Mutex enhancements. |
||||
|
Steven Reddie smr at essemer dot com dot au |
||||
|
Bug fix. |
||||
|
Alexander Terekhov TEREKHOV at de dot ibm dot com |
||||
|
Re-implemented and improved read-write locks; |
||||
|
(with Louis Thomas) re-implemented and improved |
||||
|
condition variables; |
||||
|
enhancements to semaphores; |
||||
|
enhancements to mutexes; |
||||
|
new mutex implementation in 'futex' style; |
||||
|
suggested a robust implementation of pthread_once |
||||
|
similar to that implemented by V.Kliathcko; |
||||
|
system clock change handling re CV timeouts; |
||||
|
bug fixes. |
||||
|
Thomas Pfaff tpfaff at gmx dot net |
||||
|
Changes to make C version usable with C++ applications; |
||||
|
re-implemented mutex routines to avoid Win32 mutexes |
||||
|
and TryEnterCriticalSection; |
||||
|
procedure to fix Mingw32 thread-safety issues. |
||||
|
Franco Bez franco dot bez at gmx dot de |
||||
|
procedure to fix Mingw32 thread-safety issues. |
||||
|
Louis Thomas lthomas at arbitrade dot com |
||||
|
(with Alexander Terekhov) re-implemented and improved |
||||
|
condition variables. |
||||
|
David Korn dgk at research dot att dot com |
||||
|
Ported to UWIN. |
||||
|
Phil Frisbie, Jr. phil at hawksoft dot com |
||||
|
Bug fix. |
||||
|
Ralf Brese Ralf dot Brese at pdb4 dot siemens dot de |
||||
|
Bug fix. |
||||
|
prionx at juno dot com prionx at juno dot com |
||||
|
Bug fixes. |
||||
|
Max Woodbury mtew at cds dot duke dot edu |
||||
|
POSIX versioning conditionals; |
||||
|
reduced namespace pollution; |
||||
|
idea to separate routines to reduce statically |
||||
|
linked image sizes. |
||||
|
Rob Fanner rfanner at stonethree dot com |
||||
|
Bug fix. |
||||
|
Michael Johnson michaelj at maine dot rr dot com |
||||
|
Bug fix. |
||||
|
Nicolas Barry boozai at yahoo dot com |
||||
|
Bug fixes. |
||||
|
Piet van Bruggen pietvb at newbridges dot nl |
||||
|
Bug fix. |
||||
|
Makoto Kato raven at oldskool dot jp |
||||
|
AMD64 port. |
||||
|
Panagiotis E. Hadjidoukas peh at hpclab dot ceid dot upatras dot gr |
||||
|
phadjido at cs dot uoi dot gr |
||||
|
Contributed the QueueUserAPCEx package which |
||||
|
makes preemptive async cancelation possible. |
||||
|
Will Bryant will dot bryant at ecosm dot com |
||||
|
Borland compiler patch and makefile. |
||||
|
Anuj Goyal anuj dot goyal at gmail dot com |
||||
|
Port to Digital Mars compiler. |
||||
|
Gottlob Frege gottlobfrege at gmail dot com |
||||
|
re-implemented pthread_once (version 2) |
||||
|
(pthread_once cancellation added by rpj). |
||||
|
Vladimir Kliatchko vladimir at kliatchko dot com |
||||
|
reimplemented pthread_once with the same form |
||||
|
as described by A.Terekhov (later version 2); |
||||
|
implementation of MCS (Mellor-Crummey/Scott) locks. |
||||
|
Ramiro Polla ramiro.polla at gmail dot com |
||||
|
static library auto init/cleanup on application |
||||
|
start/exit via RT hooks (MSC and GCC compilers only). |
||||
|
Daniel Richard G. skunk at iSKUNK dot org |
||||
|
Patches and cleanups for x86 and x64, particularly |
||||
|
across a range of MS build environments. |
||||
|
John Kamp john dot kamp at globalgraphics dot com |
||||
|
Patches to fix various problems on x64; brutal testing |
||||
|
particularly using high memory run environments. |
||||
|
|
@ -0,0 +1,150 @@ |
|||||
|
pthreads-win32 - a POSIX threads library for Microsoft Windows |
||||
|
|
||||
|
|
||||
|
This file is Copyrighted |
||||
|
------------------------ |
||||
|
|
||||
|
This file is covered under the following Copyright: |
||||
|
|
||||
|
Copyright (C) 2001,2006 Ross P. Johnson |
||||
|
All rights reserved. |
||||
|
|
||||
|
Everyone is permitted to copy and distribute verbatim copies |
||||
|
of this license document, but changing it is not allowed. |
||||
|
|
||||
|
Pthreads-win32 is covered by the GNU Lesser General Public License |
||||
|
------------------------------------------------------------------ |
||||
|
|
||||
|
Pthreads-win32 is open 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 version 2.1 of the |
||||
|
License. |
||||
|
|
||||
|
Pthreads-win32 is several binary link libraries, several modules, |
||||
|
associated interface definition files and scripts used to control |
||||
|
its compilation and installation. |
||||
|
|
||||
|
Pthreads-win32 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. |
||||
|
|
||||
|
A copy of the GNU Lesser General Public License is distributed with |
||||
|
pthreads-win32 under the filename: |
||||
|
|
||||
|
COPYING.LIB |
||||
|
|
||||
|
You should have received a copy of the version 2.1 GNU Lesser General |
||||
|
Public License with pthreads-win32; if not, write to: |
||||
|
|
||||
|
Free Software Foundation, Inc. |
||||
|
59 Temple Place |
||||
|
Suite 330 |
||||
|
Boston, MA 02111-1307 |
||||
|
USA |
||||
|
|
||||
|
The contact addresses for pthreads-win32 is as follows: |
||||
|
|
||||
|
Web: http://sources.redhat.com/pthreads-win32 |
||||
|
Email: Ross Johnson |
||||
|
Please use: Firstname.Lastname@homemail.com.au |
||||
|
|
||||
|
|
||||
|
|
||||
|
Pthreads-win32 copyrights and exception files |
||||
|
--------------------------------------------- |
||||
|
|
||||
|
With the exception of the files listed below, Pthreads-win32 |
||||
|
is covered under the following GNU Lesser General Public License |
||||
|
Copyrights: |
||||
|
|
||||
|
Pthreads-win32 - POSIX Threads Library for Win32 |
||||
|
Copyright(C) 1998 John E. Bossom |
||||
|
Copyright(C) 1999,2006 Pthreads-win32 contributors |
||||
|
|
||||
|
The current list of contributors is contained |
||||
|
in the file CONTRIBUTORS included with the source |
||||
|
code distribution. The current list of CONTRIBUTORS |
||||
|
can also be seen at the following WWW location: |
||||
|
http://sources.redhat.com/pthreads-win32/contributors.html |
||||
|
|
||||
|
Contact Email: Ross Johnson |
||||
|
Please use: Firstname.Lastname@homemail.com.au |
||||
|
|
||||
|
These files are not covered under one of the Copyrights listed above: |
||||
|
|
||||
|
COPYING |
||||
|
COPYING.LIB |
||||
|
tests/rwlock7.c |
||||
|
|
||||
|
This file, COPYING, is distributed under the Copyright found at the |
||||
|
top of this file. It is important to note that you may distribute |
||||
|
verbatim copies of this file but you may not modify this file. |
||||
|
|
||||
|
The file COPYING.LIB, which contains a copy of the version 2.1 |
||||
|
GNU Lesser General Public License, is itself copyrighted by the |
||||
|
Free Software Foundation, Inc. Please note that the Free Software |
||||
|
Foundation, Inc. does NOT have a copyright over Pthreads-win32, |
||||
|
only the COPYING.LIB that is supplied with pthreads-win32. |
||||
|
|
||||
|
The file tests/rwlock7.c is derived from code written by |
||||
|
Dave Butenhof for his book 'Programming With POSIX(R) Threads'. |
||||
|
The original code was obtained by free download from his website |
||||
|
http://home.earthlink.net/~anneart/family/Threads/source.html |
||||
|
and did not contain a copyright or author notice. It is assumed to |
||||
|
be freely distributable. |
||||
|
|
||||
|
In all cases one may use and distribute these exception files freely. |
||||
|
And because one may freely distribute the LGPL covered files, the |
||||
|
entire pthreads-win32 source may be freely used and distributed. |
||||
|
|
||||
|
|
||||
|
|
||||
|
General Copyleft and License info |
||||
|
--------------------------------- |
||||
|
|
||||
|
For general information on Copylefts, see: |
||||
|
|
||||
|
http://www.gnu.org/copyleft/ |
||||
|
|
||||
|
For information on GNU Lesser General Public Licenses, see: |
||||
|
|
||||
|
http://www.gnu.org/copyleft/lesser.html |
||||
|
http://www.gnu.org/copyleft/lesser.txt |
||||
|
|
||||
|
|
||||
|
Why pthreads-win32 did not use the GNU General Public License |
||||
|
------------------------------------------------------------- |
||||
|
|
||||
|
The goal of the pthreads-win32 project has been to |
||||
|
provide a quality and complete implementation of the POSIX |
||||
|
threads API for Microsoft Windows within the limits imposed |
||||
|
by virtue of it being a stand-alone library and not |
||||
|
linked directly to other POSIX compliant libraries. For |
||||
|
example, some functions and features, such as those based |
||||
|
on POSIX signals, are missing. |
||||
|
|
||||
|
Pthreads-win32 is a library, available in several different |
||||
|
versions depending on supported compilers, and may be used |
||||
|
as a dynamically linked module or a statically linked set of |
||||
|
binary modules. It is not an application on it's own. |
||||
|
|
||||
|
It was fully intended that pthreads-win32 be usable with |
||||
|
commercial software not covered by either the GPL or the LGPL |
||||
|
licenses. Pthreads-win32 has many contributors to it's |
||||
|
code base, many of whom have done so because they have |
||||
|
used the library in commercial or proprietry software |
||||
|
projects. |
||||
|
|
||||
|
Releasing pthreads-win32 under the LGPL ensures that the |
||||
|
library can be used widely, while at the same time ensures |
||||
|
that bug fixes and improvements to the pthreads-win32 code |
||||
|
itself is returned to benefit all current and future users |
||||
|
of the library. |
||||
|
|
||||
|
Although pthreads-win32 makes it possible for applications |
||||
|
that use POSIX threads to be ported to Win32 platforms, the |
||||
|
broader goal of the project is to encourage the use of open |
||||
|
standards, and in particular, to make it just a little easier |
||||
|
for developers writing Win32 applications to consider |
||||
|
widening the potential market for their products. |
File diff suppressed because it is too large
@ -0,0 +1,451 @@ |
|||||
|
========================================= |
||||
|
PTHREADS-WIN32 Frequently Asked Questions |
||||
|
========================================= |
||||
|
|
||||
|
INDEX |
||||
|
----- |
||||
|
|
||||
|
Q 1 What is it? |
||||
|
|
||||
|
Q 2 Which of the several dll versions do I use? |
||||
|
or, |
||||
|
What are all these pthread*.dll and pthread*.lib files? |
||||
|
|
||||
|
Q 3 What is the library naming convention? |
||||
|
|
||||
|
Q 4 Cleanup code default style or: it used to work when I built |
||||
|
the library myself, but now it doesn't - why? |
||||
|
|
||||
|
Q 5 Why is the default library version now less exception-friendly? |
||||
|
|
||||
|
Q 6 Should I use Cygwin or Mingw32 as a development environment? |
||||
|
|
||||
|
Q 7 Now that pthreads-win32 builds under Mingw32, why do I get |
||||
|
memory access violations (segfaults)? |
||||
|
|
||||
|
Q 8 How do I use pthread.dll for Win32 (Visual C++ 5.0) |
||||
|
|
||||
|
Q 9 Cancelation doesn't work for me, why? |
||||
|
|
||||
|
Q 10 How do I generate pthreadGCE.dll and libpthreadw32.a for use |
||||
|
with Mingw32? |
||||
|
|
||||
|
Q 11 Why isn't pthread_t defined as a scalar (e.g. pointer or int) |
||||
|
like it is for other POSIX threads implementations? |
||||
|
|
||||
|
============================================================================= |
||||
|
|
||||
|
Q 1 What is it? |
||||
|
--- |
||||
|
|
||||
|
Pthreads-win32 is an Open Source Software implementation of the |
||||
|
Threads component of the POSIX 1003.1c 1995 Standard for Microsoft's |
||||
|
Win32 environment. Some functions from POSIX 1003.1b are also |
||||
|
supported including semaphores. Other related functions include |
||||
|
the set of read-write lock functions. The library also supports |
||||
|
some of the functionality of the Open Group's Single Unix |
||||
|
specification, version 2, namely mutex types. |
||||
|
|
||||
|
See the file "ANNOUNCE" for more information including standards |
||||
|
conformance details and list of supported routines. |
||||
|
|
||||
|
|
||||
|
------------------------------------------------------------------------------ |
||||
|
|
||||
|
Q 2 Which of the several dll versions do I use? |
||||
|
--- or, |
||||
|
What are all these pthread*.dll and pthread*.lib files? |
||||
|
|
||||
|
Simply, you only use one of them, but you need to choose carefully. |
||||
|
|
||||
|
The most important choice you need to make is whether to use a |
||||
|
version that uses exceptions internally, or not (there are versions |
||||
|
of the library that use exceptions as part of the thread |
||||
|
cancelation and cleanup implementation, and one that uses |
||||
|
setjmp/longjmp instead). |
||||
|
|
||||
|
There is some contension amongst POSIX threads experts as |
||||
|
to how POSIX threads cancelation and exit should work |
||||
|
with languages that include exceptions and handlers, e.g. |
||||
|
C++ and even C (Microsoft's Structured Exceptions). |
||||
|
|
||||
|
The issue is: should cancelation of a thread in, say, |
||||
|
a C++ application cause object destructors and C++ exception |
||||
|
handlers to be invoked as the stack unwinds during thread |
||||
|
exit, or not? |
||||
|
|
||||
|
There seems to be more opinion in favour of using the |
||||
|
standard C version of the library (no EH) with C++ applications |
||||
|
since this appears to be the assumption commercial pthreads |
||||
|
implementations make. Therefore, if you use an EH version |
||||
|
of pthreads-win32 then you may be under the illusion that |
||||
|
your application will be portable, when in fact it is likely to |
||||
|
behave very differently linked with other pthreads libraries. |
||||
|
|
||||
|
Now you may be asking: why have you kept the EH versions of |
||||
|
the library? |
||||
|
|
||||
|
There are a couple of reasons: |
||||
|
- there is division amongst the experts and so the code may |
||||
|
be needed in the future. (Yes, it's in the repository and we |
||||
|
can get it out anytime in the future, but ...) |
||||
|
- pthreads-win32 is one of the few implementations, and possibly |
||||
|
the only freely available one, that has EH versions. It may be |
||||
|
useful to people who want to play with or study application |
||||
|
behaviour under these conditions. |
||||
|
|
||||
|
|
||||
|
------------------------------------------------------------------------------ |
||||
|
|
||||
|
Q 3 What is the library naming convention? |
||||
|
--- |
||||
|
|
||||
|
Because the library is being built using various exception |
||||
|
handling schemes and compilers - and because the library |
||||
|
may not work reliably if these are mixed in an application, |
||||
|
each different version of the library has it's own name. |
||||
|
|
||||
|
Note 1: the incompatibility is really between EH implementations |
||||
|
of the different compilers. It should be possible to use the |
||||
|
standard C version from either compiler with C++ applications |
||||
|
built with a different compiler. If you use an EH version of |
||||
|
the library, then you must use the same compiler for the |
||||
|
application. This is another complication and dependency that |
||||
|
can be avoided by using only the standard C library version. |
||||
|
|
||||
|
Note 2: if you use a standard C pthread*.dll with a C++ |
||||
|
application, then any functions that you define that are |
||||
|
intended to be called via pthread_cleanup_push() must be |
||||
|
__cdecl. |
||||
|
|
||||
|
Note 3: the intention is to also name either the VC or GC |
||||
|
version (it should be arbitrary) as pthread.dll, including |
||||
|
pthread.lib and libpthread.a as appropriate. |
||||
|
|
||||
|
In general: |
||||
|
pthread[VG]{SE,CE,C}.dll |
||||
|
pthread[VG]{SE,CE,C}.lib |
||||
|
|
||||
|
where: |
||||
|
[VG] indicates the compiler |
||||
|
V - MS VC |
||||
|
G - GNU C |
||||
|
|
||||
|
{SE,CE,C} indicates the exception handling scheme |
||||
|
SE - Structured EH |
||||
|
CE - C++ EH |
||||
|
C - no exceptions - uses setjmp/longjmp |
||||
|
|
||||
|
For example: |
||||
|
pthreadVSE.dll (MSVC/SEH) |
||||
|
pthreadGCE.dll (GNUC/C++ EH) |
||||
|
pthreadGC.dll (GNUC/not dependent on exceptions) |
||||
|
|
||||
|
The GNU library archive file names have changed to: |
||||
|
|
||||
|
libpthreadGCE.a |
||||
|
libpthreadGC.a |
||||
|
|
||||
|
|
||||
|
------------------------------------------------------------------------------ |
||||
|
|
||||
|
Q 4 Cleanup code default style or: it used to work when I built |
||||
|
--- the library myself, but now it doesn't - why? |
||||
|
|
||||
|
Up to and including snapshot 2001-07-12, if not defined, the cleanup |
||||
|
style was determined automatically from the compiler used, and one |
||||
|
of the following was defined accordingly: |
||||
|
|
||||
|
__CLEANUP_SEH MSVC only |
||||
|
__CLEANUP_CXX C++, including MSVC++, GNU G++ |
||||
|
__CLEANUP_C C, including GNU GCC, not MSVC |
||||
|
|
||||
|
These defines determine the style of cleanup (see pthread.h) and, |
||||
|
most importantly, the way that cancelation and thread exit (via |
||||
|
pthread_exit) is performed (see the routine ptw32_throw() in private.c). |
||||
|
|
||||
|
In short, the exceptions versions of the library throw an exception |
||||
|
when a thread is canceled or exits (via pthread_exit()), which is |
||||
|
caught by a handler in the thread startup routine, so that the |
||||
|
the correct stack unwinding occurs regardless of where the thread |
||||
|
is when it's canceled or exits via pthread_exit(). |
||||
|
|
||||
|
After snapshot 2001-07-12, unless your build explicitly defines (e.g. |
||||
|
via a compiler option) __CLEANUP_SEH, __CLEANUP_CXX, or __CLEANUP_C, then |
||||
|
the build now ALWAYS defaults to __CLEANUP_C style cleanup. This style |
||||
|
uses setjmp/longjmp in the cancelation and pthread_exit implementations, |
||||
|
and therefore won't do stack unwinding even when linked to applications |
||||
|
that have it (e.g. C++ apps). This is for consistency with most/all |
||||
|
commercial Unix POSIX threads implementations. |
||||
|
|
||||
|
Although it was not clearly documented before, it is still necessary to |
||||
|
build your application using the same __CLEANUP_* define as was |
||||
|
used for the version of the library that you link with, so that the |
||||
|
correct parts of pthread.h are included. That is, the possible |
||||
|
defines require the following library versions: |
||||
|
|
||||
|
__CLEANUP_SEH pthreadVSE.dll |
||||
|
__CLEANUP_CXX pthreadVCE.dll or pthreadGCE.dll |
||||
|
__CLEANUP_C pthreadVC.dll or pthreadGC.dll |
||||
|
|
||||
|
THE POINT OF ALL THIS IS: if you have not been defining one of these |
||||
|
explicitly, then the defaults have been set according to the compiler |
||||
|
and language you are using, as described at the top of this |
||||
|
section. |
||||
|
|
||||
|
THIS NOW CHANGES, as has been explained above. For example: |
||||
|
|
||||
|
If you were building your application with MSVC++ i.e. using C++ |
||||
|
exceptions (rather than SEH) and not explicitly defining one of |
||||
|
__CLEANUP_*, then __CLEANUP_C++ was defined for you in pthread.h. |
||||
|
You should have been linking with pthreadVCE.dll, which does |
||||
|
stack unwinding. |
||||
|
|
||||
|
If you now build your application as you had before, pthread.h will now |
||||
|
set __CLEANUP_C as the default style, and you will need to link |
||||
|
with pthreadVC.dll. Stack unwinding will now NOT occur when a |
||||
|
thread is canceled, nor when the thread calls pthread_exit(). |
||||
|
|
||||
|
Your application will now most likely behave differently to previous |
||||
|
versions, and in non-obvious ways. Most likely is that local |
||||
|
objects may not be destroyed or cleaned up after a thread |
||||
|
is canceled. |
||||
|
|
||||
|
If you want the same behaviour as before, then you must now define |
||||
|
__CLEANUP_C++ explicitly using a compiler option and link with |
||||
|
pthreadVCE.dll as you did before. |
||||
|
|
||||
|
|
||||
|
------------------------------------------------------------------------------ |
||||
|
|
||||
|
Q 5 Why is the default library version now less exception-friendly? |
||||
|
--- |
||||
|
|
||||
|
Because most commercial Unix POSIX threads implementations don't allow you to |
||||
|
choose to have stack unwinding. (Compaq's TRU64 Unix is possibly an exception.) |
||||
|
|
||||
|
Therefore, providing it in pthread-win32 as a default could be dangerous |
||||
|
and non-portable. We still provide the choice but you must now consciously |
||||
|
make it. |
||||
|
|
||||
|
WHY NOT REMOVE THE EXCEPTIONS VERSIONS OF THE LIBRARY ALTOGETHER? |
||||
|
There are a few reasons: |
||||
|
- because there are well respected POSIX threads people who believe |
||||
|
that POSIX threads implementations should be exceptions-aware and |
||||
|
do the expected thing in that context. (There are equally respected |
||||
|
people who believe it should not be easily accessible, if it's there |
||||
|
at all.) |
||||
|
- because pthreads-win32 is one of the few implementations that has |
||||
|
the choice, perhaps the only freely available one, and so offers |
||||
|
a laboratory to people who may want to explore the effects; |
||||
|
- although the code will always be around somewhere for anyone who |
||||
|
wants it, once it's removed from the current version it will not be |
||||
|
nearly as visible to people who may have a use for it. |
||||
|
|
||||
|
|
||||
|
------------------------------------------------------------------------------ |
||||
|
|
||||
|
Q 6 Should I use Cygwin or Mingw32 as a development environment? |
||||
|
--- |
||||
|
|
||||
|
Important: see Q7 also. |
||||
|
|
||||
|
Use Mingw32 with the MSVCRT library to build applications that use |
||||
|
the pthreads DLL. |
||||
|
|
||||
|
Cygwin's own internal support for POSIX threads is growing. |
||||
|
Consult that project's documentation for more information. |
||||
|
|
||||
|
------------------------------------------------------------------------------ |
||||
|
|
||||
|
Q 7 Now that pthreads-win32 builds under Mingw32, why do I get |
||||
|
--- memory access violations (segfaults)? |
||||
|
|
||||
|
The latest Mingw32 package has thread-safe exception handling (see Q10). |
||||
|
Also, see Q6 above. |
||||
|
|
||||
|
------------------------------------------------------------------------------ |
||||
|
|
||||
|
Q 8 How do I use pthread.dll for Win32 (Visual C++ 5.0) |
||||
|
--- |
||||
|
|
||||
|
> |
||||
|
> I'm a "rookie" when it comes to your pthread implementation. I'm currently |
||||
|
> desperately trying to install the prebuilt .dll file into my MSVC compiler. |
||||
|
> Could you please provide me with explicit instructions on how to do this (or |
||||
|
> direct me to a resource(s) where I can acquire such information)? |
||||
|
> |
||||
|
> Thank you, |
||||
|
> |
||||
|
|
||||
|
You should have a .dll, .lib, .def, and three .h files. It is recommended |
||||
|
that you use pthreadVC.dll, rather than pthreadVCE.dll or pthreadVSE.dll |
||||
|
(see Q2 above). |
||||
|
|
||||
|
The .dll can go in any directory listed in your PATH environment |
||||
|
variable, so putting it into C:\WINDOWS should work. |
||||
|
|
||||
|
The .lib file can go in any directory listed in your LIB environment |
||||
|
variable. |
||||
|
|
||||
|
The .h files can go in any directory listed in your INCLUDE |
||||
|
environment variable. |
||||
|
|
||||
|
Or you might prefer to put the .lib and .h files into a new directory |
||||
|
and add its path to LIB and INCLUDE. You can probably do this easiest |
||||
|
by editing the file:- |
||||
|
|
||||
|
C:\Program Files\DevStudio\vc\bin\vcvars32.bat |
||||
|
|
||||
|
The .def file isn't used by anything in the pre-compiled version but |
||||
|
is included for information. |
||||
|
|
||||
|
Cheers. |
||||
|
Ross |
||||
|
|
||||
|
------------------------------------------------------------------------------ |
||||
|
|
||||
|
Q 9 Cancelation doesn't work for me, why? |
||||
|
--- |
||||
|
|
||||
|
> I'm investigating a problem regarding thread cancelation. The thread I want |
||||
|
> to cancel has PTHREAD_CANCEL_ASYNCHRONOUS, however, this piece of code |
||||
|
> blocks on the join(): |
||||
|
> |
||||
|
> if ((retv = Pthread_cancel( recvThread )) == 0) |
||||
|
> { |
||||
|
> retv = Pthread_join( recvThread, 0 ); |
||||
|
> } |
||||
|
> |
||||
|
> Pthread_* are just macro's; they call pthread_*. |
||||
|
> |
||||
|
> The thread recvThread seems to block on a select() call. It doesn't get |
||||
|
> cancelled. |
||||
|
> |
||||
|
> Two questions: |
||||
|
> |
||||
|
> 1) is this normal behaviour? |
||||
|
> |
||||
|
> 2) if not, how does the cancel mechanism work? I'm not very familliar to |
||||
|
> win32 programming, so I don't really understand how the *Event() family of |
||||
|
> calls work. |
||||
|
|
||||
|
The answer to your first question is, normal POSIX behaviour would |
||||
|
be to asynchronously cancel the thread. However, even that doesn't |
||||
|
guarantee cancelation as the standard only says it should be |
||||
|
cancelled as soon as possible. |
||||
|
|
||||
|
Snapshot 99-11-02 or earlier only partially supports asynchronous cancellation. |
||||
|
Snapshots since then simulate async cancelation by poking the address of |
||||
|
a cancelation routine into the PC of the threads context. This requires |
||||
|
the thread to be resumed in some way for the cancelation to actually |
||||
|
proceed. This is not true async cancelation, but it is as close as we've |
||||
|
been able to get to it. |
||||
|
|
||||
|
If the thread you're trying to cancel is blocked (for instance, it could be |
||||
|
waiting for data from the network), it will only get cancelled when it unblocks |
||||
|
(when the data arrives). For true pre-emptive cancelation in these cases, |
||||
|
pthreads-win32 from snapshot 2004-05-16 can automatically recognise and use the |
||||
|
QueueUserAPCEx package by Panagiotis E. Hadjidoukas. This package is available |
||||
|
from the pthreads-win32 ftp site and is included in the pthreads-win32 |
||||
|
self-unpacking zip from 2004-05-16 onwards. |
||||
|
|
||||
|
Using deferred cancelation would normally be the way to go, however, |
||||
|
even though the POSIX threads standard lists a number of C library |
||||
|
functions that are defined as deferred cancelation points, there is |
||||
|
no hookup between those which are provided by Windows and the |
||||
|
pthreads-win32 library. |
||||
|
|
||||
|
Incidently, it's worth noting for code portability that the older POSIX |
||||
|
threads standards cancelation point lists didn't include "select" because |
||||
|
(as I read in Butenhof) it wasn't part of POSIX. However, it does appear in |
||||
|
the SUSV3. |
||||
|
|
||||
|
Effectively, the only mandatory cancelation points that pthreads-win32 |
||||
|
recognises are those the library implements itself, ie. |
||||
|
|
||||
|
pthread_testcancel |
||||
|
pthread_cond_wait |
||||
|
pthread_cond_timedwait |
||||
|
pthread_join |
||||
|
sem_wait |
||||
|
sem_timedwait |
||||
|
pthread_delay_np |
||||
|
|
||||
|
The following routines from the non-mandatory list in SUSV3 are |
||||
|
cancelation points in pthreads-win32: |
||||
|
|
||||
|
pthread_rwlock_wrlock |
||||
|
pthread_rwlock_timedwrlock |
||||
|
|
||||
|
The following routines from the non-mandatory list in SUSV3 are not |
||||
|
cancelation points in pthreads-win32: |
||||
|
|
||||
|
pthread_rwlock_rdlock |
||||
|
pthread_rwlock_timedrdlock |
||||
|
|
||||
|
Pthreads-win32 also provides two functions that allow you to create |
||||
|
cancelation points within your application, but only for cases where |
||||
|
a thread is going to block on a Win32 handle. These are: |
||||
|
|
||||
|
pthreadCancelableWait(HANDLE waitHandle) /* Infinite wait */ |
||||
|
|
||||
|
pthreadCancelableTimedWait(HANDLE waitHandle, DWORD timeout) |
||||
|
|
||||
|
------------------------------------------------------------------------------ |
||||
|
|
||||
|
|
||||
|
Q 10 How do I create thread-safe applications using |
||||
|
---- pthreadGCE.dll, libpthreadw32.a and Mingw32? |
||||
|
|
||||
|
This should not be a problem with recent versions of MinGW32. |
||||
|
|
||||
|
For early versions, see Thomas Pfaff's email at: |
||||
|
http://sources.redhat.com/ml/pthreads-win32/2002/msg00000.html |
||||
|
------------------------------------------------------------------------------ |
||||
|
|
||||
|
Q 11 Why isn't pthread_t defined as a scalar (e.g. pointer or int) |
||||
|
like it is for other POSIX threads implementations? |
||||
|
---- |
||||
|
|
||||
|
Originally pthread_t was defined as a pointer (to the opaque pthread_t_ |
||||
|
struct) and later it was changed to a struct containing the original |
||||
|
pointer plus a sequence counter. This is allowed under both the original |
||||
|
POSIX Threads Standard and the current Single Unix Specification. |
||||
|
|
||||
|
When pthread_t is a simple pointer to a struct some very difficult to |
||||
|
debug problems arise from the process of freeing and later allocing |
||||
|
thread structs because new pthread_t handles can acquire the identity of |
||||
|
previously detached threads. The change to a struct was made, along with |
||||
|
some changes to their internal managment, in order to guarantee (for |
||||
|
practical applications) that the pthread_t handle will be unique over the |
||||
|
life of the running process. |
||||
|
|
||||
|
Where application code attempts to compare one pthread_t against another |
||||
|
directly, a compiler error will be emitted because structs can't be |
||||
|
compared at that level. This should signal a potentially serious problem |
||||
|
in the code design, which would go undetected if pthread_t was a scalar. |
||||
|
|
||||
|
The POSIX Threading API provides a function named pthread_equal() to |
||||
|
compare pthread_t thread handles. |
||||
|
|
||||
|
Other pthreads implementations, such as Sun's, use an int as the handle |
||||
|
but do guarantee uniqueness within the process scope. Win32 scalar typed |
||||
|
thread handles also guarantee uniqueness in system scope. It wasn't clear |
||||
|
how well the internal management of these handles would scale as the |
||||
|
number of threads and the fragmentation of the sequence numbering |
||||
|
increased for applications where thousands or millions of threads are |
||||
|
created and detached over time. The current management of threads within |
||||
|
pthreads-win32 using structs for pthread_t, and reusing without ever |
||||
|
freeing them, reduces the management time overheads to a constant, which |
||||
|
could be important given that pthreads-win32 threads are built on top of |
||||
|
Win32 threads and will therefore include that management overhead on top |
||||
|
of their own. The cost is that the memory resources used for thread |
||||
|
handles will remain at the peak level until the process exits. |
||||
|
|
||||
|
While it may be inconvenient for developers to be forced away from making |
||||
|
assumptions about the internals of pthread_t, the advantage for the |
||||
|
future development of pthread-win32, as well as those applications that |
||||
|
use it and other pthread implementations, is that the library is free to |
||||
|
change pthread_t internals and management as better methods arise. |
||||
|
|
@ -0,0 +1,593 @@ |
|||||
|
#
|
||||
|
# --------------------------------------------------------------------------
|
||||
|
#
|
||||
|
# 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
|
||||
|
#
|
||||
|
|
||||
|
DLL_VER = 2 |
||||
|
DLL_VERD= $(DLL_VER)d |
||||
|
|
||||
|
DEVROOT = C:\PTHREADS |
||||
|
|
||||
|
DLLDEST = $(DEVROOT)\DLL |
||||
|
LIBDEST = $(DEVROOT)\DLL |
||||
|
|
||||
|
# If Running MsysDTK
|
||||
|
RM = rm -f |
||||
|
MV = mv -f |
||||
|
CP = cp -f |
||||
|
|
||||
|
# If not.
|
||||
|
#RM = erase
|
||||
|
#MV = rename
|
||||
|
#CP = copy
|
||||
|
|
||||
|
# For cross compiling use e.g.
|
||||
|
# make CROSS=x86_64-w64-mingw32- clean GC-inlined
|
||||
|
CROSS = |
||||
|
|
||||
|
AR = $(CROSS)ar |
||||
|
DLLTOOL = $(CROSS)dlltool |
||||
|
CC = $(CROSS)gcc |
||||
|
CXX = $(CROSS)g++ |
||||
|
RANLIB = $(CROSS)ranlib |
||||
|
RC = $(CROSS)windres |
||||
|
|
||||
|
OPT = $(CLEANUP) -O3 # -finline-functions -findirect-inlining |
||||
|
XOPT = |
||||
|
|
||||
|
RCFLAGS = --include-dir=. |
||||
|
# Uncomment this if config.h defines RETAIN_WSALASTERROR
|
||||
|
#LFLAGS = -lws2_32
|
||||
|
|
||||
|
# ----------------------------------------------------------------------
|
||||
|
# The library can be built with some alternative behaviour to
|
||||
|
# facilitate development of applications on Win32 that will be ported
|
||||
|
# to other POSIX systems. Nothing definable here will make the library
|
||||
|
# non-compliant, but applications that make assumptions that POSIX
|
||||
|
# does not garrantee may fail or misbehave under some settings.
|
||||
|
#
|
||||
|
# PTW32_THREAD_ID_REUSE_INCREMENT
|
||||
|
# Purpose:
|
||||
|
# POSIX says that applications should assume that thread IDs can be
|
||||
|
# recycled. However, Solaris and some other systems use a [very large]
|
||||
|
# sequence number as the thread ID, which provides virtual uniqueness.
|
||||
|
# Pthreads-win32 provides pseudo-unique IDs when the default increment
|
||||
|
# (1) is used, but pthread_t is not a scalar type like Solaris's.
|
||||
|
#
|
||||
|
# Usage:
|
||||
|
# Set to any value in the range: 0 <= value <= 2^wordsize
|
||||
|
#
|
||||
|
# Examples:
|
||||
|
# Set to 0 to emulate non recycle-unique behaviour like Linux or *BSD.
|
||||
|
# Set to 1 for recycle-unique thread IDs (this is the default).
|
||||
|
# Set to some other +ve value to emulate smaller word size types
|
||||
|
# (i.e. will wrap sooner).
|
||||
|
#
|
||||
|
#PTW32_FLAGS = "-DPTW32_THREAD_ID_REUSE_INCREMENT=0"
|
||||
|
#
|
||||
|
# ----------------------------------------------------------------------
|
||||
|
|
||||
|
GC_CFLAGS = $(PTW32_FLAGS) |
||||
|
GCE_CFLAGS = $(PTW32_FLAGS) -mthreads |
||||
|
|
||||
|
## Mingw32
|
||||
|
MAKE ?= make |
||||
|
CFLAGS = $(OPT) $(XOPT) -I. -DHAVE_PTW32_CONFIG_H -Wall |
||||
|
|
||||
|
DLL_INLINED_OBJS = \
|
||||
|
pthread.o \
|
||||
|
version.o |
||||
|
|
||||
|
# Agregate modules for inlinability
|
||||
|
DLL_OBJS = \
|
||||
|
attr.o \
|
||||
|
barrier.o \
|
||||
|
cancel.o \
|
||||
|
cleanup.o \
|
||||
|
condvar.o \
|
||||
|
create.o \
|
||||
|
dll.o \
|
||||
|
errno.o \
|
||||
|
exit.o \
|
||||
|
fork.o \
|
||||
|
global.o \
|
||||
|
misc.o \
|
||||
|
mutex.o \
|
||||
|
nonportable.o \
|
||||
|
private.o \
|
||||
|
rwlock.o \
|
||||
|
sched.o \
|
||||
|
semaphore.o \
|
||||
|
signal.o \
|
||||
|
spin.o \
|
||||
|
sync.o \
|
||||
|
tsd.o \
|
||||
|
version.o |
||||
|
|
||||
|
# Separate modules for minimum size statically linked images
|
||||
|
SMALL_STATIC_OBJS = \
|
||||
|
pthread_attr_init.o \
|
||||
|
pthread_attr_destroy.o \
|
||||
|
pthread_attr_getdetachstate.o \
|
||||
|
pthread_attr_setdetachstate.o \
|
||||
|
pthread_attr_getstackaddr.o \
|
||||
|
pthread_attr_setstackaddr.o \
|
||||
|
pthread_attr_getstacksize.o \
|
||||
|
pthread_attr_setstacksize.o \
|
||||
|
pthread_attr_getscope.o \
|
||||
|
pthread_attr_setscope.o \
|
||||
|
pthread_attr_setschedpolicy.o \
|
||||
|
pthread_attr_getschedpolicy.o \
|
||||
|
pthread_attr_setschedparam.o \
|
||||
|
pthread_attr_getschedparam.o \
|
||||
|
pthread_attr_setinheritsched.o \
|
||||
|
pthread_attr_getinheritsched.o \
|
||||
|
pthread_barrier_init.o \
|
||||
|
pthread_barrier_destroy.o \
|
||||
|
pthread_barrier_wait.o \
|
||||
|
pthread_barrierattr_init.o \
|
||||
|
pthread_barrierattr_destroy.o \
|
||||
|
pthread_barrierattr_setpshared.o \
|
||||
|
pthread_barrierattr_getpshared.o \
|
||||
|
pthread_setcancelstate.o \
|
||||
|
pthread_setcanceltype.o \
|
||||
|
pthread_testcancel.o \
|
||||
|
pthread_cancel.o \
|
||||
|
cleanup.o \
|
||||
|
pthread_condattr_destroy.o \
|
||||
|
pthread_condattr_getpshared.o \
|
||||
|
pthread_condattr_init.o \
|
||||
|
pthread_condattr_setpshared.o \
|
||||
|
pthread_cond_destroy.o \
|
||||
|
pthread_cond_init.o \
|
||||
|
pthread_cond_signal.o \
|
||||
|
pthread_cond_wait.o \
|
||||
|
create.o \
|
||||
|
dll.o \
|
||||
|
autostatic.o \
|
||||
|
errno.o \
|
||||
|
pthread_exit.o \
|
||||
|
fork.o \
|
||||
|
global.o \
|
||||
|
pthread_mutex_init.o \
|
||||
|
pthread_mutex_destroy.o \
|
||||
|
pthread_mutexattr_init.o \
|
||||
|
pthread_mutexattr_destroy.o \
|
||||
|
pthread_mutexattr_getpshared.o \
|
||||
|
pthread_mutexattr_setpshared.o \
|
||||
|
pthread_mutexattr_settype.o \
|
||||
|
pthread_mutexattr_gettype.o \
|
||||
|
pthread_mutexattr_setrobust.o \
|
||||
|
pthread_mutexattr_getrobust.o \
|
||||
|
pthread_mutex_lock.o \
|
||||
|
pthread_mutex_timedlock.o \
|
||||
|
pthread_mutex_unlock.o \
|
||||
|
pthread_mutex_trylock.o \
|
||||
|
pthread_mutex_consistent.o \
|
||||
|
pthread_mutexattr_setkind_np.o \
|
||||
|
pthread_mutexattr_getkind_np.o \
|
||||
|
pthread_getw32threadhandle_np.o \
|
||||
|
pthread_getunique_np.o \
|
||||
|
pthread_delay_np.o \
|
||||
|
pthread_num_processors_np.o \
|
||||
|
pthread_win32_attach_detach_np.o \
|
||||
|
pthread_equal.o \
|
||||
|
pthread_getconcurrency.o \
|
||||
|
pthread_once.o \
|
||||
|
pthread_self.o \
|
||||
|
pthread_setconcurrency.o \
|
||||
|
pthread_rwlock_init.o \
|
||||
|
pthread_rwlock_destroy.o \
|
||||
|
pthread_rwlockattr_init.o \
|
||||
|
pthread_rwlockattr_destroy.o \
|
||||
|
pthread_rwlockattr_getpshared.o \
|
||||
|
pthread_rwlockattr_setpshared.o \
|
||||
|
pthread_rwlock_rdlock.o \
|
||||
|
pthread_rwlock_wrlock.o \
|
||||
|
pthread_rwlock_unlock.o \
|
||||
|
pthread_rwlock_tryrdlock.o \
|
||||
|
pthread_rwlock_trywrlock.o \
|
||||
|
pthread_setschedparam.o \
|
||||
|
pthread_getschedparam.o \
|
||||
|
pthread_timechange_handler_np.o \
|
||||
|
ptw32_is_attr.o \
|
||||
|
ptw32_cond_check_need_init.o \
|
||||
|
ptw32_MCS_lock.o \
|
||||
|
ptw32_mutex_check_need_init.o \
|
||||
|
ptw32_processInitialize.o \
|
||||
|
ptw32_processTerminate.o \
|
||||
|
ptw32_threadStart.o \
|
||||
|
ptw32_threadDestroy.o \
|
||||
|
ptw32_tkAssocCreate.o \
|
||||
|
ptw32_tkAssocDestroy.o \
|
||||
|
ptw32_callUserDestroyRoutines.o \
|
||||
|
ptw32_timespec.o \
|
||||
|
ptw32_throw.o \
|
||||
|
ptw32_getprocessors.o \
|
||||
|
ptw32_calloc.o \
|
||||
|
ptw32_new.o \
|
||||
|
ptw32_reuse.o \
|
||||
|
ptw32_semwait.o \
|
||||
|
ptw32_relmillisecs.o \
|
||||
|
ptw32_rwlock_check_need_init.o \
|
||||
|
sched_get_priority_max.o \
|
||||
|
sched_get_priority_min.o \
|
||||
|
sched_setscheduler.o \
|
||||
|
sched_getscheduler.o \
|
||||
|
sched_yield.o \
|
||||
|
sem_init.o \
|
||||
|
sem_destroy.o \
|
||||
|
sem_trywait.o \
|
||||
|
sem_timedwait.o \
|
||||
|
sem_wait.o \
|
||||
|
sem_post.o \
|
||||
|
sem_post_multiple.o \
|
||||
|
sem_getvalue.o \
|
||||
|
sem_open.o \
|
||||
|
sem_close.o \
|
||||
|
sem_unlink.o \
|
||||
|
signal.o \
|
||||
|
pthread_kill.o \
|
||||
|
ptw32_spinlock_check_need_init.o \
|
||||
|
pthread_spin_init.o \
|
||||
|
pthread_spin_destroy.o \
|
||||
|
pthread_spin_lock.o \
|
||||
|
pthread_spin_unlock.o \
|
||||
|
pthread_spin_trylock.o \
|
||||
|
pthread_detach.o \
|
||||
|
pthread_join.o \
|
||||
|
pthread_key_create.o \
|
||||
|
pthread_key_delete.o \
|
||||
|
pthread_setspecific.o \
|
||||
|
pthread_getspecific.o \
|
||||
|
w32_CancelableWait.o \
|
||||
|
version.o |
||||
|
|
||||
|
INCL = \
|
||||
|
config.h \
|
||||
|
implement.h \
|
||||
|
semaphore.h \
|
||||
|
pthread.h \
|
||||
|
need_errno.h |
||||
|
|
||||
|
ATTR_SRCS = \
|
||||
|
pthread_attr_init.c \
|
||||
|
pthread_attr_destroy.c \
|
||||
|
pthread_attr_getdetachstate.c \
|
||||
|
pthread_attr_setdetachstate.c \
|
||||
|
pthread_attr_getstackaddr.c \
|
||||
|
pthread_attr_setstackaddr.c \
|
||||
|
pthread_attr_getstacksize.c \
|
||||
|
pthread_attr_setstacksize.c \
|
||||
|
pthread_attr_getscope.c \
|
||||
|
pthread_attr_setscope.c |
||||
|
|
||||
|
BARRIER_SRCS = \
|
||||
|
pthread_barrier_init.c \
|
||||
|
pthread_barrier_destroy.c \
|
||||
|
pthread_barrier_wait.c \
|
||||
|
pthread_barrierattr_init.c \
|
||||
|
pthread_barrierattr_destroy.c \
|
||||
|
pthread_barrierattr_setpshared.c \
|
||||
|
pthread_barrierattr_getpshared.c |
||||
|
|
||||
|
CANCEL_SRCS = \
|
||||
|
pthread_setcancelstate.c \
|
||||
|
pthread_setcanceltype.c \
|
||||
|
pthread_testcancel.c \
|
||||
|
pthread_cancel.c |
||||
|
|
||||
|
CONDVAR_SRCS = \
|
||||
|
ptw32_cond_check_need_init.c \
|
||||
|
pthread_condattr_destroy.c \
|
||||
|
pthread_condattr_getpshared.c \
|
||||
|
pthread_condattr_init.c \
|
||||
|
pthread_condattr_setpshared.c \
|
||||
|
pthread_cond_destroy.c \
|
||||
|
pthread_cond_init.c \
|
||||
|
pthread_cond_signal.c \
|
||||
|
pthread_cond_wait.c |
||||
|
|
||||
|
EXIT_SRCS = \
|
||||
|
pthread_exit.c |
||||
|
|
||||
|
MISC_SRCS = \
|
||||
|
pthread_equal.c \
|
||||
|
pthread_getconcurrency.c \
|
||||
|
pthread_kill.c \
|
||||
|
pthread_once.c \
|
||||
|
pthread_self.c \
|
||||
|
pthread_setconcurrency.c \
|
||||
|
ptw32_calloc.c \
|
||||
|
ptw32_MCS_lock.c \
|
||||
|
ptw32_new.c \
|
||||
|
ptw32_reuse.c \
|
||||
|
w32_CancelableWait.c |
||||
|
|
||||
|
MUTEX_SRCS = \
|
||||
|
ptw32_mutex_check_need_init.c \
|
||||
|
pthread_mutex_init.c \
|
||||
|
pthread_mutex_destroy.c \
|
||||
|
pthread_mutexattr_init.c \
|
||||
|
pthread_mutexattr_destroy.c \
|
||||
|
pthread_mutexattr_getpshared.c \
|
||||
|
pthread_mutexattr_setpshared.c \
|
||||
|
pthread_mutexattr_settype.c \
|
||||
|
pthread_mutexattr_gettype.c \
|
||||
|
pthread_mutexattr_setrobust.c \
|
||||
|
pthread_mutexattr_getrobust.c \
|
||||
|
pthread_mutex_lock.c \
|
||||
|
pthread_mutex_timedlock.c \
|
||||
|
pthread_mutex_unlock.c \
|
||||
|
pthread_mutex_trylock.c \
|
||||
|
pthread_mutex_consistent.c |
||||
|
|
||||
|
NONPORTABLE_SRCS = \
|
||||
|
pthread_mutexattr_setkind_np.c \
|
||||
|
pthread_mutexattr_getkind_np.c \
|
||||
|
pthread_getw32threadhandle_np.c \
|
||||
|
pthread_getunique_np.c \
|
||||
|
pthread_delay_np.c \
|
||||
|
pthread_num_processors_np.c \
|
||||
|
pthread_win32_attach_detach_np.c \
|
||||
|
pthread_timechange_handler_np.c |
||||
|
|
||||
|
PRIVATE_SRCS = \
|
||||
|
ptw32_is_attr.c \
|
||||
|
ptw32_processInitialize.c \
|
||||
|
ptw32_processTerminate.c \
|
||||
|
ptw32_threadStart.c \
|
||||
|
ptw32_threadDestroy.c \
|
||||
|
ptw32_tkAssocCreate.c \
|
||||
|
ptw32_tkAssocDestroy.c \
|
||||
|
ptw32_callUserDestroyRoutines.c \
|
||||
|
ptw32_semwait.c \
|
||||
|
ptw32_relmillisecs.c \
|
||||
|
ptw32_timespec.c \
|
||||
|
ptw32_throw.c \
|
||||
|
ptw32_getprocessors.c |
||||
|
|
||||
|
RWLOCK_SRCS = \
|
||||
|
ptw32_rwlock_check_need_init.c \
|
||||
|
ptw32_rwlock_cancelwrwait.c \
|
||||
|
pthread_rwlock_init.c \
|
||||
|
pthread_rwlock_destroy.c \
|
||||
|
pthread_rwlockattr_init.c \
|
||||
|
pthread_rwlockattr_destroy.c \
|
||||
|
pthread_rwlockattr_getpshared.c \
|
||||
|
pthread_rwlockattr_setpshared.c \
|
||||
|
pthread_rwlock_rdlock.c \
|
||||
|
pthread_rwlock_timedrdlock.c \
|
||||
|
pthread_rwlock_wrlock.c \
|
||||
|
pthread_rwlock_timedwrlock.c \
|
||||
|
pthread_rwlock_unlock.c \
|
||||
|
pthread_rwlock_tryrdlock.c \
|
||||
|
pthread_rwlock_trywrlock.c |
||||
|
|
||||
|
SCHED_SRCS = \
|
||||
|
pthread_attr_setschedpolicy.c \
|
||||
|
pthread_attr_getschedpolicy.c \
|
||||
|
pthread_attr_setschedparam.c \
|
||||
|
pthread_attr_getschedparam.c \
|
||||
|
pthread_attr_setinheritsched.c \
|
||||
|
pthread_attr_getinheritsched.c \
|
||||
|
pthread_setschedparam.c \
|
||||
|
pthread_getschedparam.c \
|
||||
|
sched_get_priority_max.c \
|
||||
|
sched_get_priority_min.c \
|
||||
|
sched_setscheduler.c \
|
||||
|
sched_getscheduler.c \
|
||||
|
sched_yield.c |
||||
|
|
||||
|
SEMAPHORE_SRCS = \
|
||||
|
sem_init.c \
|
||||
|
sem_destroy.c \
|
||||
|
sem_trywait.c \
|
||||
|
sem_timedwait.c \
|
||||
|
sem_wait.c \
|
||||
|
sem_post.c \
|
||||
|
sem_post_multiple.c \
|
||||
|
sem_getvalue.c \
|
||||
|
sem_open.c \
|
||||
|
sem_close.c \
|
||||
|
sem_unlink.c |
||||
|
|
||||
|
SPIN_SRCS = \
|
||||
|
ptw32_spinlock_check_need_init.c \
|
||||
|
pthread_spin_init.c \
|
||||
|
pthread_spin_destroy.c \
|
||||
|
pthread_spin_lock.c \
|
||||
|
pthread_spin_unlock.c \
|
||||
|
pthread_spin_trylock.c |
||||
|
|
||||
|
SYNC_SRCS = \
|
||||
|
pthread_detach.c \
|
||||
|
pthread_join.c |
||||
|
|
||||
|
TSD_SRCS = \
|
||||
|
pthread_key_create.c \
|
||||
|
pthread_key_delete.c \
|
||||
|
pthread_setspecific.c \
|
||||
|
pthread_getspecific.c |
||||
|
|
||||
|
|
||||
|
GCE_DLL = pthreadGCE$(DLL_VER).dll |
||||
|
GCED_DLL= pthreadGCE$(DLL_VERD).dll |
||||
|
GCE_LIB = libpthreadGCE$(DLL_VER).a |
||||
|
GCED_LIB= libpthreadGCE$(DLL_VERD).a |
||||
|
GCE_INLINED_STAMP = pthreadGCE$(DLL_VER).stamp |
||||
|
GCED_INLINED_STAMP = pthreadGCE$(DLL_VERD).stamp |
||||
|
GCE_STATIC_STAMP = libpthreadGCE$(DLL_VER).stamp |
||||
|
GCED_STATIC_STAMP = libpthreadGCE$(DLL_VERD).stamp |
||||
|
|
||||
|
GC_DLL = pthreadGC$(DLL_VER).dll |
||||
|
GCD_DLL = pthreadGC$(DLL_VERD).dll |
||||
|
GC_LIB = libpthreadGC$(DLL_VER).a |
||||
|
GCD_LIB = libpthreadGC$(DLL_VERD).a |
||||
|
GC_INLINED_STAMP = pthreadGC$(DLL_VER).stamp |
||||
|
GCD_INLINED_STAMP = pthreadGC$(DLL_VERD).stamp |
||||
|
GC_STATIC_STAMP = libpthreadGC$(DLL_VER).stamp |
||||
|
GCD_STATIC_STAMP = libpthreadGC$(DLL_VERD).stamp |
||||
|
|
||||
|
PTHREAD_DEF = pthread.def |
||||
|
|
||||
|
help: |
||||
|
@ echo "Run one of the following command lines:" |
||||
|
@ echo "make clean GC (to build the GNU C dll with C cleanup code)" |
||||
|
@ echo "make clean GCE (to build the GNU C dll with C++ exception handling)" |
||||
|
@ echo "make clean GC-inlined (to build the GNU C inlined dll with C cleanup code)" |
||||
|
@ echo "make clean GCE-inlined (to build the GNU C inlined dll with C++ exception handling)" |
||||
|
@ echo "make clean GC-static (to build the GNU C inlined static lib with C cleanup code)" |
||||
|
@ echo "make clean GC-debug (to build the GNU C debug dll with C cleanup code)" |
||||
|
@ echo "make clean GCE-debug (to build the GNU C debug dll with C++ exception handling)" |
||||
|
@ echo "make clean GC-inlined-debug (to build the GNU C inlined debug dll with C cleanup code)" |
||||
|
@ echo "make clean GCE-inlined-debug (to build the GNU C inlined debug dll with C++ exception handling)" |
||||
|
@ echo "make clean GC-static-debug (to build the GNU C inlined static debug lib with C cleanup code)" |
||||
|
|
||||
|
all: |
||||
|
@ $(MAKE) clean GCE |
||||
|
@ $(MAKE) clean GC |
||||
|
|
||||
|
GC: |
||||
|
$(MAKE) CLEANUP=-D__CLEANUP_C XC_FLAGS="$(GC_CFLAGS)" OBJ="$(DLL_OBJS)" $(GC_DLL) |
||||
|
|
||||
|
GC-debug: |
||||
|
$(MAKE) CLEANUP=-D__CLEANUP_C XC_FLAGS="$(GC_CFLAGS)" OBJ="$(DLL_OBJS)" DLL_VER=$(DLL_VERD) OPT="-D__CLEANUP_C -g -O0" $(GCD_DLL) |
||||
|
|
||||
|
GCE: |
||||
|
$(MAKE) CC=$(CXX) CLEANUP=-D__CLEANUP_CXX XC_FLAGS="$(GCE_CFLAGS)" OBJ="$(DLL_OBJS)" $(GCE_DLL) |
||||
|
|
||||
|
GCE-debug: |
||||
|
$(MAKE) CC=$(CXX) CLEANUP=-D__CLEANUP_CXX XC_FLAGS="$(GCE_CFLAGS)" OBJ="$(DLL_OBJS)" DLL_VER=$(DLL_VERD) OPT="-D__CLEANUP_CXX -g -O0" $(GCED_DLL) |
||||
|
|
||||
|
GC-inlined: |
||||
|
$(MAKE) XOPT="-DPTW32_BUILD_INLINED" CLEANUP=-D__CLEANUP_C XC_FLAGS="$(GC_CFLAGS)" OBJ="$(DLL_INLINED_OBJS)" $(GC_INLINED_STAMP) |
||||
|
|
||||
|
GC-inlined-debug: |
||||
|
$(MAKE) XOPT="-DPTW32_BUILD_INLINED" CLEANUP=-D__CLEANUP_C XC_FLAGS="$(GC_CFLAGS)" OBJ="$(DLL_INLINED_OBJS)" DLL_VER=$(DLL_VERD) OPT="-D__CLEANUP_C -g -O0" $(GCD_INLINED_STAMP) |
||||
|
|
||||
|
GCE-inlined: |
||||
|
$(MAKE) CC=$(CXX) XOPT="-DPTW32_BUILD_INLINED" CLEANUP=-D__CLEANUP_CXX XC_FLAGS="$(GCE_CFLAGS)" OBJ="$(DLL_INLINED_OBJS)" $(GCE_INLINED_STAMP) |
||||
|
|
||||
|
GCE-inlined-debug: |
||||
|
$(MAKE) CC=$(CXX) XOPT="-DPTW32_BUILD_INLINED" CLEANUP=-D__CLEANUP_CXX XC_FLAGS="$(GCE_CFLAGS)" OBJ="$(DLL_INLINED_OBJS)" DLL_VER=$(DLL_VERD) OPT="-D__CLEANUP_CXX -g -O0" $(GCED_INLINED_STAMP) |
||||
|
|
||||
|
GC-static: |
||||
|
$(MAKE) XOPT="-DPTW32_BUILD_INLINED -DPTW32_STATIC_LIB" CLEANUP=-D__CLEANUP_C XC_FLAGS="$(GC_CFLAGS)" OBJ="$(DLL_INLINED_OBJS)" $(GC_STATIC_STAMP) |
||||
|
|
||||
|
GC-static-debug: |
||||
|
$(MAKE) XOPT="-DPTW32_BUILD_INLINED -DPTW32_STATIC_LIB" CLEANUP=-D__CLEANUP_C XC_FLAGS="$(GC_CFLAGS)" OBJ="$(DLL_INLINED_OBJS)" DLL_VER=$(DLL_VERD) OPT="-D__CLEANUP_C -g -O0" $(GCD_STATIC_STAMP) |
||||
|
|
||||
|
tests: |
||||
|
@ cd tests |
||||
|
@ $(MAKE) auto |
||||
|
|
||||
|
%.pre: %.c |
||||
|
$(CC) -E -o $@ $(CFLAGS) $^ |
||||
|
|
||||
|
%.s: %.c |
||||
|
$(CC) -c $(CFLAGS) -DPTW32_BUILD_INLINED -Wa,-ahl $^ > $@ |
||||
|
|
||||
|
%.o: %.rc |
||||
|
$(RC) $(RCFLAGS) $(CLEANUP) -o $@ $< |
||||
|
|
||||
|
.SUFFIXES: .dll .rc .c .o |
||||
|
|
||||
|
.c.o:; $(CC) -c -o $@ $(CFLAGS) $(XC_FLAGS) $< |
||||
|
|
||||
|
|
||||
|
$(GC_DLL) $(GCD_DLL): $(DLL_OBJS) |
||||
|
$(CC) $(OPT) -shared -o $(GC_DLL) $(DLL_OBJS) $(LFLAGS) |
||||
|
$(DLLTOOL) -z pthread.def $(DLL_OBJS) |
||||
|
$(DLLTOOL) -k --dllname $@ --output-lib $(GC_LIB) --def $(PTHREAD_DEF) |
||||
|
|
||||
|
$(GCE_DLL): $(DLL_OBJS) |
||||
|
$(CC) $(OPT) -mthreads -shared -o $(GCE_DLL) $(DLL_OBJS) $(LFLAGS) |
||||
|
$(DLLTOOL) -z pthread.def $(DLL_OBJS) |
||||
|
$(DLLTOOL) -k --dllname $@ --output-lib $(GCE_LIB) --def $(PTHREAD_DEF) |
||||
|
|
||||
|
$(GC_INLINED_STAMP) $(GCD_INLINED_STAMP): $(DLL_INLINED_OBJS) |
||||
|
$(CC) $(OPT) $(XOPT) -shared -o $(GC_DLL) $(DLL_INLINED_OBJS) $(LFLAGS) |
||||
|
$(DLLTOOL) -z pthread.def $(DLL_INLINED_OBJS) |
||||
|
$(DLLTOOL) -k --dllname $(GC_DLL) --output-lib $(GC_LIB) --def $(PTHREAD_DEF) |
||||
|
echo touched > $(GC_INLINED_STAMP) |
||||
|
|
||||
|
$(GCE_INLINED_STAMP) $(GCED_INLINED_STAMP): $(DLL_INLINED_OBJS) |
||||
|
$(CC) $(OPT) $(XOPT) -mthreads -shared -o $(GCE_DLL) $(DLL_INLINED_OBJS) $(LFLAGS) |
||||
|
$(DLLTOOL) -z pthread.def $(DLL_INLINED_OBJS) |
||||
|
$(DLLTOOL) -k --dllname $(GCE_DLL) --output-lib $(GCE_LIB) --def $(PTHREAD_DEF) |
||||
|
echo touched > $(GCE_INLINED_STAMP) |
||||
|
|
||||
|
$(GC_STATIC_STAMP) $(GCD_STATIC_STAMP): $(DLL_INLINED_OBJS) |
||||
|
$(RM) $(GC_LIB) |
||||
|
$(AR) -rv $(GC_LIB) $(DLL_INLINED_OBJS) |
||||
|
$(RANLIB) $(GC_LIB) |
||||
|
echo touched > $(GC_STATIC_STAMP) |
||||
|
|
||||
|
clean: |
||||
|
-$(RM) *~ |
||||
|
-$(RM) *.i |
||||
|
-$(RM) *.s |
||||
|
-$(RM) *.o |
||||
|
-$(RM) *.obj |
||||
|
-$(RM) *.exe |
||||
|
-$(RM) $(PTHREAD_DEF) |
||||
|
|
||||
|
realclean: clean |
||||
|
-$(RM) $(GC_LIB) |
||||
|
-$(RM) $(GCE_LIB) |
||||
|
-$(RM) $(GC_DLL) |
||||
|
-$(RM) $(GCE_DLL) |
||||
|
-$(RM) $(GC_INLINED_STAMP) |
||||
|
-$(RM) $(GCE_INLINED_STAMP) |
||||
|
-$(RM) $(GC_STATIC_STAMP) |
||||
|
-$(RM) $(GCD_LIB) |
||||
|
-$(RM) $(GCED_LIB) |
||||
|
-$(RM) $(GCD_DLL) |
||||
|
-$(RM) $(GCED_DLL) |
||||
|
-$(RM) $(GCD_INLINED_STAMP) |
||||
|
-$(RM) $(GCED_INLINED_STAMP) |
||||
|
-$(RM) $(GCD_STATIC_STAMP) |
||||
|
|
||||
|
attr.o: attr.c $(ATTR_SRCS) $(INCL) |
||||
|
barrier.o: barrier.c $(BARRIER_SRCS) $(INCL) |
||||
|
cancel.o: cancel.c $(CANCEL_SRCS) $(INCL) |
||||
|
condvar.o: condvar.c $(CONDVAR_SRCS) $(INCL) |
||||
|
exit.o: exit.c $(EXIT_SRCS) $(INCL) |
||||
|
misc.o: misc.c $(MISC_SRCS) $(INCL) |
||||
|
mutex.o: mutex.c $(MUTEX_SRCS) $(INCL) |
||||
|
nonportable.o: nonportable.c $(NONPORTABLE_SRCS) $(INCL) |
||||
|
private.o: private.c $(PRIVATE_SRCS) $(INCL) |
||||
|
rwlock.o: rwlock.c $(RWLOCK_SRCS) $(INCL) |
||||
|
sched.o: sched.c $(SCHED_SRCS) $(INCL) |
||||
|
semaphore.o: semaphore.c $(SEMAPHORE_SRCS) $(INCL) |
||||
|
spin.o: spin.c $(SPIN_SRCS) $(INCL) |
||||
|
sync.o: sync.c $(SYNC_SRCS) $(INCL) |
||||
|
tsd.o: tsd.c $(TSD_SRCS) $(INCL) |
||||
|
version.o: version.rc $(INCL) |
@ -0,0 +1,4 @@ |
|||||
|
CVS Repository maintainers |
||||
|
|
||||
|
Ross Johnson rpj@ise.canberra.edu.au |
||||
|
Ben Elliston bje@cygnus.com |
@ -0,0 +1,516 @@ |
|||||
|
# This makefile is compatible with MS nmake and can be used as a
|
||||
|
# replacement for buildlib.bat. I've changed the target from an ordinary dll
|
||||
|
# (/LD) to a debugging dll (/LDd).
|
||||
|
#
|
||||
|
# The variables $DLLDEST and $LIBDEST hold the destination directories for the
|
||||
|
# dll and the lib, respectively. Probably all that needs to change is $DEVROOT.
|
||||
|
|
||||
|
|
||||
|
# DLL_VER:
|
||||
|
# See pthread.h and README - This number is computed as 'current - age'
|
||||
|
DLL_VER = 2 |
||||
|
DLL_VERD= $(DLL_VER)d |
||||
|
|
||||
|
DEVROOT = C:\pthreads |
||||
|
|
||||
|
DLLDEST = $(DEVROOT)\dll |
||||
|
LIBDEST = $(DEVROOT)\lib |
||||
|
HDRDEST = $(DEVROOT)\include |
||||
|
|
||||
|
DLLS = pthreadVCE$(DLL_VER).dll pthreadVSE$(DLL_VER).dll pthreadVC$(DLL_VER).dll \
|
||||
|
pthreadVCE$(DLL_VERD).dll pthreadVSE$(DLL_VERD).dll pthreadVC$(DLL_VERD).dll |
||||
|
INLINED_STAMPS = pthreadVCE$(DLL_VER).stamp pthreadVSE$(DLL_VER).stamp pthreadVC$(DLL_VER).stamp \
|
||||
|
pthreadVCE$(DLL_VERD).stamp pthreadVSE$(DLL_VERD).stamp pthreadVC$(DLL_VERD).stamp |
||||
|
STATIC_STAMPS = pthreadVCE$(DLL_VER).static pthreadVSE$(DLL_VER).static pthreadVC$(DLL_VER).static \
|
||||
|
pthreadVCE$(DLL_VERD).static pthreadVSE$(DLL_VERD).static pthreadVC$(DLL_VERD).static |
||||
|
|
||||
|
CC = cl |
||||
|
CPPFLAGS = /I. /DHAVE_PTW32_CONFIG_H |
||||
|
STATICCRT = /MT |
||||
|
STATICCRTD = /MTd |
||||
|
DLLCRT = /MD |
||||
|
DLLCRTD = /MDd |
||||
|
XCFLAGS = /W3 /nologo |
||||
|
CFLAGS = /O2 /Ob2 $(XCFLAGS) |
||||
|
CFLAGSD = /Z7 $(XCFLAGS) |
||||
|
|
||||
|
# Uncomment this if config.h defines RETAIN_WSALASTERROR
|
||||
|
#XLIBS = wsock32.lib
|
||||
|
|
||||
|
# Default cleanup style
|
||||
|
CLEANUP = __CLEANUP_C |
||||
|
|
||||
|
# C++ Exceptions
|
||||
|
VCEFLAGS = /EHsc /TP $(CPPFLAGS) $(CFLAGS) |
||||
|
VCEFLAGSD = /EHsc /TP $(CPPFLAGS) $(CFLAGSD) |
||||
|
#Structured Exceptions
|
||||
|
VSEFLAGS = $(CPPFLAGS) $(CFLAGS) |
||||
|
VSEFLAGSD = $(CPPFLAGS) $(CFLAGSD) |
||||
|
#C cleanup code
|
||||
|
VCFLAGS = $(CPPFLAGS) $(CFLAGS) |
||||
|
VCFLAGSD = $(CPPFLAGS) $(CFLAGSD) |
||||
|
|
||||
|
DLL_INLINED_OBJS = \
|
||||
|
pthread.obj \
|
||||
|
version.res |
||||
|
|
||||
|
# Aggregate modules for inlinability
|
||||
|
DLL_OBJS = \
|
||||
|
attr.obj \
|
||||
|
barrier.obj \
|
||||
|
cancel.obj \
|
||||
|
cleanup.obj \
|
||||
|
condvar.obj \
|
||||
|
create.obj \
|
||||
|
dll.obj \
|
||||
|
autostatic.obj \
|
||||
|
errno.obj \
|
||||
|
exit.obj \
|
||||
|
fork.obj \
|
||||
|
global.obj \
|
||||
|
misc.obj \
|
||||
|
mutex.obj \
|
||||
|
nonportable.obj \
|
||||
|
private.obj \
|
||||
|
rwlock.obj \
|
||||
|
sched.obj \
|
||||
|
semaphore.obj \
|
||||
|
signal.obj \
|
||||
|
spin.obj \
|
||||
|
sync.obj \
|
||||
|
tsd.obj \
|
||||
|
version.res |
||||
|
|
||||
|
# Separate modules for minimising the size of statically linked images
|
||||
|
SMALL_STATIC_OBJS = \
|
||||
|
pthread_attr_init.obj \
|
||||
|
pthread_attr_destroy.obj \
|
||||
|
pthread_attr_getdetachstate.obj \
|
||||
|
pthread_attr_setdetachstate.obj \
|
||||
|
pthread_attr_getstackaddr.obj \
|
||||
|
pthread_attr_setstackaddr.obj \
|
||||
|
pthread_attr_getstacksize.obj \
|
||||
|
pthread_attr_setstacksize.obj \
|
||||
|
pthread_attr_getscope.obj \
|
||||
|
pthread_attr_setscope.obj \
|
||||
|
pthread_attr_setschedpolicy.obj \
|
||||
|
pthread_attr_getschedpolicy.obj \
|
||||
|
pthread_attr_setschedparam.obj \
|
||||
|
pthread_attr_getschedparam.obj \
|
||||
|
pthread_attr_setinheritsched.obj \
|
||||
|
pthread_attr_getinheritsched.obj \
|
||||
|
pthread_barrier_init.obj \
|
||||
|
pthread_barrier_destroy.obj \
|
||||
|
pthread_barrier_wait.obj \
|
||||
|
pthread_barrierattr_init.obj \
|
||||
|
pthread_barrierattr_destroy.obj \
|
||||
|
pthread_barrierattr_setpshared.obj \
|
||||
|
pthread_barrierattr_getpshared.obj \
|
||||
|
pthread_setcancelstate.obj \
|
||||
|
pthread_setcanceltype.obj \
|
||||
|
pthread_testcancel.obj \
|
||||
|
pthread_cancel.obj \
|
||||
|
cleanup.obj \
|
||||
|
pthread_condattr_destroy.obj \
|
||||
|
pthread_condattr_getpshared.obj \
|
||||
|
pthread_condattr_init.obj \
|
||||
|
pthread_condattr_setpshared.obj \
|
||||
|
pthread_cond_destroy.obj \
|
||||
|
pthread_cond_init.obj \
|
||||
|
pthread_cond_signal.obj \
|
||||
|
pthread_cond_wait.obj \
|
||||
|
create.obj \
|
||||
|
dll.obj \
|
||||
|
autostatic.obj \
|
||||
|
errno.obj \
|
||||
|
pthread_exit.obj \
|
||||
|
fork.obj \
|
||||
|
global.obj \
|
||||
|
pthread_mutex_init.obj \
|
||||
|
pthread_mutex_destroy.obj \
|
||||
|
pthread_mutexattr_init.obj \
|
||||
|
pthread_mutexattr_destroy.obj \
|
||||
|
pthread_mutexattr_getpshared.obj \
|
||||
|
pthread_mutexattr_setpshared.obj \
|
||||
|
pthread_mutexattr_settype.obj \
|
||||
|
pthread_mutexattr_gettype.obj \
|
||||
|
pthread_mutexattr_setrobust.obj \
|
||||
|
pthread_mutexattr_getrobust.obj \
|
||||
|
pthread_mutex_lock.obj \
|
||||
|
pthread_mutex_timedlock.obj \
|
||||
|
pthread_mutex_unlock.obj \
|
||||
|
pthread_mutex_trylock.obj \
|
||||
|
pthread_mutex_consistent.obj \
|
||||
|
pthread_mutexattr_setkind_np.obj \
|
||||
|
pthread_mutexattr_getkind_np.obj \
|
||||
|
pthread_getw32threadhandle_np.obj \
|
||||
|
pthread_getunique_np.obj \
|
||||
|
pthread_delay_np.obj \
|
||||
|
pthread_num_processors_np.obj \
|
||||
|
pthread_win32_attach_detach_np.obj \
|
||||
|
pthread_equal.obj \
|
||||
|
pthread_getconcurrency.obj \
|
||||
|
pthread_once.obj \
|
||||
|
pthread_self.obj \
|
||||
|
pthread_setconcurrency.obj \
|
||||
|
pthread_rwlock_init.obj \
|
||||
|
pthread_rwlock_destroy.obj \
|
||||
|
pthread_rwlockattr_init.obj \
|
||||
|
pthread_rwlockattr_destroy.obj \
|
||||
|
pthread_rwlockattr_getpshared.obj \
|
||||
|
pthread_rwlockattr_setpshared.obj \
|
||||
|
pthread_rwlock_rdlock.obj \
|
||||
|
pthread_rwlock_wrlock.obj \
|
||||
|
pthread_rwlock_unlock.obj \
|
||||
|
pthread_rwlock_tryrdlock.obj \
|
||||
|
pthread_rwlock_trywrlock.obj \
|
||||
|
pthread_setschedparam.obj \
|
||||
|
pthread_getschedparam.obj \
|
||||
|
pthread_timechange_handler_np.obj \
|
||||
|
ptw32_is_attr.obj \
|
||||
|
ptw32_processInitialize.obj \
|
||||
|
ptw32_processTerminate.obj \
|
||||
|
ptw32_threadStart.obj \
|
||||
|
ptw32_threadDestroy.obj \
|
||||
|
ptw32_tkAssocCreate.obj \
|
||||
|
ptw32_tkAssocDestroy.obj \
|
||||
|
ptw32_callUserDestroyRoutines.obj \
|
||||
|
ptw32_timespec.obj \
|
||||
|
ptw32_throw.obj \
|
||||
|
ptw32_getprocessors.obj \
|
||||
|
ptw32_calloc.obj \
|
||||
|
ptw32_new.obj \
|
||||
|
ptw32_reuse.obj \
|
||||
|
ptw32_rwlock_check_need_init.obj \
|
||||
|
ptw32_cond_check_need_init.obj \
|
||||
|
ptw32_mutex_check_need_init.obj \
|
||||
|
ptw32_semwait.obj \
|
||||
|
ptw32_relmillisecs.obj \
|
||||
|
ptw32_MCS_lock.obj \
|
||||
|
sched_get_priority_max.obj \
|
||||
|
sched_get_priority_min.obj \
|
||||
|
sched_setscheduler.obj \
|
||||
|
sched_getscheduler.obj \
|
||||
|
sched_yield.obj \
|
||||
|
sem_init.obj \
|
||||
|
sem_destroy.obj \
|
||||
|
sem_trywait.obj \
|
||||
|
sem_timedwait.obj \
|
||||
|
sem_wait.obj \
|
||||
|
sem_post.obj \
|
||||
|
sem_post_multiple.obj \
|
||||
|
sem_getvalue.obj \
|
||||
|
sem_open.obj \
|
||||
|
sem_close.obj \
|
||||
|
sem_unlink.obj \
|
||||
|
signal.obj \
|
||||
|
pthread_kill.obj \
|
||||
|
ptw32_spinlock_check_need_init.obj \
|
||||
|
pthread_spin_init.obj \
|
||||
|
pthread_spin_destroy.obj \
|
||||
|
pthread_spin_lock.obj \
|
||||
|
pthread_spin_unlock.obj \
|
||||
|
pthread_spin_trylock.obj \
|
||||
|
pthread_detach.obj \
|
||||
|
pthread_join.obj \
|
||||
|
pthread_key_create.obj \
|
||||
|
pthread_key_delete.obj \
|
||||
|
pthread_setspecific.obj \
|
||||
|
pthread_getspecific.obj \
|
||||
|
w32_CancelableWait.obj \
|
||||
|
version.res |
||||
|
|
||||
|
INCL = config.h implement.h semaphore.h pthread.h need_errno.h |
||||
|
|
||||
|
ATTR_SRCS = \
|
||||
|
pthread_attr_init.c \
|
||||
|
pthread_attr_destroy.c \
|
||||
|
pthread_attr_getdetachstate.c \
|
||||
|
pthread_attr_setdetachstate.c \
|
||||
|
pthread_attr_getstackaddr.c \
|
||||
|
pthread_attr_setstackaddr.c \
|
||||
|
pthread_attr_getstacksize.c \
|
||||
|
pthread_attr_setstacksize.c \
|
||||
|
pthread_attr_getscope.c \
|
||||
|
pthread_attr_setscope.c |
||||
|
|
||||
|
BARRIER_SRCS = \
|
||||
|
pthread_barrier_init.c \
|
||||
|
pthread_barrier_destroy.c \
|
||||
|
pthread_barrier_wait.c \
|
||||
|
pthread_barrierattr_init.c \
|
||||
|
pthread_barrierattr_destroy.c \
|
||||
|
pthread_barrierattr_setpshared.c \
|
||||
|
pthread_barrierattr_getpshared.c |
||||
|
|
||||
|
CANCEL_SRCS = \
|
||||
|
pthread_setcancelstate.c \
|
||||
|
pthread_setcanceltype.c \
|
||||
|
pthread_testcancel.c \
|
||||
|
pthread_cancel.c |
||||
|
|
||||
|
CONDVAR_SRCS = \
|
||||
|
ptw32_cond_check_need_init.c \
|
||||
|
pthread_condattr_destroy.c \
|
||||
|
pthread_condattr_getpshared.c \
|
||||
|
pthread_condattr_init.c \
|
||||
|
pthread_condattr_setpshared.c \
|
||||
|
pthread_cond_destroy.c \
|
||||
|
pthread_cond_init.c \
|
||||
|
pthread_cond_signal.c \
|
||||
|
pthread_cond_wait.c |
||||
|
|
||||
|
EXIT_SRCS = \
|
||||
|
pthread_exit.c |
||||
|
|
||||
|
MISC_SRCS = \
|
||||
|
pthread_equal.c \
|
||||
|
pthread_getconcurrency.c \
|
||||
|
pthread_kill.c \
|
||||
|
pthread_once.c \
|
||||
|
pthread_self.c \
|
||||
|
pthread_setconcurrency.c \
|
||||
|
ptw32_calloc.c \
|
||||
|
ptw32_MCS_lock.c \
|
||||
|
ptw32_new.c \
|
||||
|
ptw32_reuse.c \
|
||||
|
ptw32_relmillisecs.c \
|
||||
|
w32_CancelableWait.c |
||||
|
|
||||
|
MUTEX_SRCS = \
|
||||
|
ptw32_mutex_check_need_init.c \
|
||||
|
pthread_mutex_init.c \
|
||||
|
pthread_mutex_destroy.c \
|
||||
|
pthread_mutexattr_init.c \
|
||||
|
pthread_mutexattr_destroy.c \
|
||||
|
pthread_mutexattr_getpshared.c \
|
||||
|
pthread_mutexattr_setpshared.c \
|
||||
|
pthread_mutexattr_settype.c \
|
||||
|
pthread_mutexattr_gettype.c \
|
||||
|
pthread_mutexattr_setrobust.c \
|
||||
|
pthread_mutexattr_getrobust.c \
|
||||
|
pthread_mutex_lock.c \
|
||||
|
pthread_mutex_timedlock.c \
|
||||
|
pthread_mutex_unlock.c \
|
||||
|
pthread_mutex_trylock.c \
|
||||
|
pthread_mutex_consistent.c |
||||
|
|
||||
|
NONPORTABLE_SRCS = \
|
||||
|
pthread_mutexattr_setkind_np.c \
|
||||
|
pthread_mutexattr_getkind_np.c \
|
||||
|
pthread_getw32threadhandle_np.c \
|
||||
|
pthread_getunique_np.c \
|
||||
|
pthread_delay_np.c \
|
||||
|
pthread_num_processors_np.c \
|
||||
|
pthread_win32_attach_detach_np.c \
|
||||
|
pthread_timechange_handler_np.c |
||||
|
|
||||
|
PRIVATE_SRCS = \
|
||||
|
ptw32_is_attr.c \
|
||||
|
ptw32_processInitialize.c \
|
||||
|
ptw32_processTerminate.c \
|
||||
|
ptw32_threadStart.c \
|
||||
|
ptw32_threadDestroy.c \
|
||||
|
ptw32_tkAssocCreate.c \
|
||||
|
ptw32_tkAssocDestroy.c \
|
||||
|
ptw32_callUserDestroyRoutines.c \
|
||||
|
ptw32_semwait.c \
|
||||
|
ptw32_timespec.c \
|
||||
|
ptw32_throw.c \
|
||||
|
ptw32_getprocessors.c |
||||
|
|
||||
|
RWLOCK_SRCS = \
|
||||
|
ptw32_rwlock_check_need_init.c \
|
||||
|
ptw32_rwlock_cancelwrwait.c \
|
||||
|
pthread_rwlock_init.c \
|
||||
|
pthread_rwlock_destroy.c \
|
||||
|
pthread_rwlockattr_init.c \
|
||||
|
pthread_rwlockattr_destroy.c \
|
||||
|
pthread_rwlockattr_getpshared.c \
|
||||
|
pthread_rwlockattr_setpshared.c \
|
||||
|
pthread_rwlock_rdlock.c \
|
||||
|
pthread_rwlock_timedrdlock.c \
|
||||
|
pthread_rwlock_wrlock.c \
|
||||
|
pthread_rwlock_timedwrlock.c \
|
||||
|
pthread_rwlock_unlock.c \
|
||||
|
pthread_rwlock_tryrdlock.c \
|
||||
|
pthread_rwlock_trywrlock.c |
||||
|
|
||||
|
SCHED_SRCS = \
|
||||
|
pthread_attr_setschedpolicy.c \
|
||||
|
pthread_attr_getschedpolicy.c \
|
||||
|
pthread_attr_setschedparam.c \
|
||||
|
pthread_attr_getschedparam.c \
|
||||
|
pthread_attr_setinheritsched.c \
|
||||
|
pthread_attr_getinheritsched.c \
|
||||
|
pthread_setschedparam.c \
|
||||
|
pthread_getschedparam.c \
|
||||
|
sched_get_priority_max.c \
|
||||
|
sched_get_priority_min.c \
|
||||
|
sched_setscheduler.c \
|
||||
|
sched_getscheduler.c \
|
||||
|
sched_yield.c |
||||
|
|
||||
|
SEMAPHORE_SRCS = \
|
||||
|
sem_init.c \
|
||||
|
sem_destroy.c \
|
||||
|
sem_trywait.c \
|
||||
|
sem_timedwait.c \
|
||||
|
sem_wait.c \
|
||||
|
sem_post.c \
|
||||
|
sem_post_multiple.c \
|
||||
|
sem_getvalue.c \
|
||||
|
sem_open.c \
|
||||
|
sem_close.c \
|
||||
|
sem_unlink.c |
||||
|
|
||||
|
SPIN_SRCS = \
|
||||
|
ptw32_spinlock_check_need_init.c \
|
||||
|
pthread_spin_init.c \
|
||||
|
pthread_spin_destroy.c \
|
||||
|
pthread_spin_lock.c \
|
||||
|
pthread_spin_unlock.c \
|
||||
|
pthread_spin_trylock.c |
||||
|
|
||||
|
SYNC_SRCS = \
|
||||
|
pthread_detach.c \
|
||||
|
pthread_join.c |
||||
|
|
||||
|
TSD_SRCS = \
|
||||
|
pthread_key_create.c \
|
||||
|
pthread_key_delete.c \
|
||||
|
pthread_setspecific.c \
|
||||
|
pthread_getspecific.c |
||||
|
|
||||
|
|
||||
|
help: |
||||
|
@ echo Run one of the following command lines: |
||||
|
@ echo nmake clean VCE (to build the MSVC dll with C++ exception handling) |
||||
|
@ echo nmake clean VSE (to build the MSVC dll with structured exception handling) |
||||
|
@ echo nmake clean VC (to build the MSVC dll with C cleanup code) |
||||
|
@ echo nmake clean VCE-inlined (to build the MSVC inlined dll with C++ exception handling) |
||||
|
@ echo nmake clean VSE-inlined (to build the MSVC inlined dll with structured exception handling) |
||||
|
@ echo nmake clean VC-inlined (to build the MSVC inlined dll with C cleanup code) |
||||
|
@ echo nmake clean VC-static (to build the MSVC static lib with C cleanup code) |
||||
|
@ echo nmake clean VCE-debug (to build the debug MSVC dll with C++ exception handling) |
||||
|
@ echo nmake clean VSE-debug (to build the debug MSVC dll with structured exception handling) |
||||
|
@ echo nmake clean VC-debug (to build the debug MSVC dll with C cleanup code) |
||||
|
@ echo nmake clean VCE-inlined-debug (to build the debug MSVC inlined dll with C++ exception handling) |
||||
|
@ echo nmake clean VSE-inlined-debug (to build the debug MSVC inlined dll with structured exception handling) |
||||
|
@ echo nmake clean VC-inlined-debug (to build the debug MSVC inlined dll with C cleanup code) |
||||
|
@ echo nmake clean VC-static-debug (to build the debug MSVC static lib with C cleanup code) |
||||
|
|
||||
|
all: |
||||
|
@ $(MAKE) /E clean VCE-inlined |
||||
|
@ $(MAKE) /E clean VSE-inlined |
||||
|
@ $(MAKE) /E clean VC-inlined |
||||
|
@ $(MAKE) /E clean VCE-inlined-debug |
||||
|
@ $(MAKE) /E clean VSE-inlined-debug |
||||
|
@ $(MAKE) /E clean VC-inlined-debug |
||||
|
|
||||
|
VCE: |
||||
|
@ $(MAKE) /E /nologo EHFLAGS="$(VCEFLAGS) $(DLLCRT)" CLEANUP=__CLEANUP_CXX pthreadVCE$(DLL_VER).dll |
||||
|
|
||||
|
VCE-debug: |
||||
|
@ $(MAKE) /E /nologo EHFLAGS="$(VCEFLAGSD) $(DLLCRTD)" CLEANUP=__CLEANUP_CXX pthreadVCE$(DLL_VERD).dll |
||||
|
|
||||
|
VSE: |
||||
|
@ $(MAKE) /E /nologo EHFLAGS="$(VSEFLAGS) $(DLLCRT)" CLEANUP=__CLEANUP_SEH pthreadVSE$(DLL_VER).dll |
||||
|
|
||||
|
VSE-debug: |
||||
|
@ $(MAKE) /E /nologo EHFLAGS="$(VSEFLAGSD) $(DLLCRTD)" CLEANUP=__CLEANUP_SEH pthreadVSE$(DLL_VERD).dll |
||||
|
|
||||
|
VC: |
||||
|
@ $(MAKE) /E /nologo EHFLAGS="$(VCFLAGS) $(DLLCRT)" CLEANUP=__CLEANUP_C pthreadVC$(DLL_VER).dll |
||||
|
|
||||
|
VC-debug: |
||||
|
@ $(MAKE) /E /nologo EHFLAGS="$(VCFLAGSD) $(DLLCRTD)" CLEANUP=__CLEANUP_C pthreadVC$(DLL_VERD).dll |
||||
|
|
||||
|
#
|
||||
|
# The so-called inlined DLL is just a single translation unit with
|
||||
|
# inlining optimisation turned on.
|
||||
|
#
|
||||
|
VCE-inlined: |
||||
|
@ $(MAKE) /E /nologo EHFLAGS="$(VCEFLAGS) $(DLLCRT) /DPTW32_BUILD_INLINED" CLEANUP=__CLEANUP_CXX pthreadVCE$(DLL_VER).stamp |
||||
|
|
||||
|
VCE-inlined-debug: |
||||
|
@ $(MAKE) /E /nologo EHFLAGS="$(VCEFLAGSD) $(DLLCRTD) /DPTW32_BUILD_INLINED" CLEANUP=__CLEANUP_CXX pthreadVCE$(DLL_VERD).stamp |
||||
|
|
||||
|
VSE-inlined: |
||||
|
@ $(MAKE) /E /nologo EHFLAGS="$(VSEFLAGS) $(DLLCRT) /DPTW32_BUILD_INLINED" CLEANUP=__CLEANUP_SEH pthreadVSE$(DLL_VER).stamp |
||||
|
|
||||
|
VSE-inlined-debug: |
||||
|
@ $(MAKE) /E /nologo EHFLAGS="$(VSEFLAGSD) $(DLLCRTD) /DPTW32_BUILD_INLINED" CLEANUP=__CLEANUP_SEH pthreadVSE$(DLL_VERD).stamp |
||||
|
|
||||
|
VC-inlined: |
||||
|
@ $(MAKE) /E /nologo EHFLAGS="$(VCFLAGS) $(DLLCRT) /DPTW32_BUILD_INLINED" CLEANUP=__CLEANUP_C pthreadVC$(DLL_VER).stamp |
||||
|
|
||||
|
VC-inlined-debug: |
||||
|
@ $(MAKE) /E /nologo EHFLAGS="$(VCFLAGSD) $(DLLCRTD) /DPTW32_BUILD_INLINED" CLEANUP=__CLEANUP_C pthreadVC$(DLL_VERD).stamp |
||||
|
|
||||
|
VC-static: |
||||
|
@ $(MAKE) /E /nologo EHFLAGS="$(VCFLAGS) $(STATICCRT) /DPTW32_BUILD_INLINED /DPTW32_STATIC_LIB" CLEANUP=__CLEANUP_C pthreadVC$(DLL_VER).static |
||||
|
|
||||
|
VC-static-debug: |
||||
|
@ $(MAKE) /E /nologo EHFLAGS="$(VCFLAGSD) $(STATICCRTD) /DPTW32_BUILD_INLINED /DPTW32_STATIC_LIB" CLEANUP=__CLEANUP_C pthreadVC$(DLL_VERD).static |
||||
|
|
||||
|
realclean: clean |
||||
|
if exist pthread*.dll del pthread*.dll |
||||
|
if exist pthread*.lib del pthread*.lib |
||||
|
if exist *.manifest del *.manifest |
||||
|
if exist *.stamp del *.stamp |
||||
|
|
||||
|
clean: |
||||
|
if exist *.obj del *.obj |
||||
|
if exist *.def del *.def |
||||
|
if exist *.ilk del *.ilk |
||||
|
if exist *.pdb del *.pdb |
||||
|
if exist *.exp del *.exp |
||||
|
if exist *.map del *.map |
||||
|
if exist *.o del *.o |
||||
|
if exist *.i del *.i |
||||
|
if exist *.res del *.res |
||||
|
|
||||
|
|
||||
|
install: |
||||
|
copy pthread*.dll $(DLLDEST) |
||||
|
copy pthread*.lib $(LIBDEST) |
||||
|
copy pthread.h $(HDRDEST) |
||||
|
copy sched.h $(HDRDEST) |
||||
|
copy semaphore.h $(HDRDEST) |
||||
|
|
||||
|
$(DLLS): $(DLL_OBJS) |
||||
|
$(CC) /LDd /Zi /nologo $(DLL_OBJS) /link /implib:$*.lib $(XLIBS) /out:$@ |
||||
|
|
||||
|
$(INLINED_STAMPS): $(DLL_INLINED_OBJS) |
||||
|
$(CC) /LDd /Zi /nologo $(DLL_INLINED_OBJS) /link /implib:$*.lib $(XLIBS) /out:$*.dll |
||||
|
|
||||
|
$(STATIC_STAMPS): $(DLL_INLINED_OBJS) |
||||
|
if exist $*.lib del $*.lib |
||||
|
lib $(DLL_INLINED_OBJS) /out:$*.lib |
||||
|
|
||||
|
.c.obj: |
||||
|
$(CC) $(EHFLAGS) /D$(CLEANUP) -c $< |
||||
|
|
||||
|
.rc.res: |
||||
|
rc /dPTW32_RC_MSC /d$(CLEANUP) $< |
||||
|
|
||||
|
.c.i: |
||||
|
$(CC) /P /O2 /Ob1 $(VCFLAGS) $< |
||||
|
|
||||
|
attr.obj: attr.c $(ATTR_SRCS) $(INCL) |
||||
|
barrier.obj: barrier.c $(BARRIER_SRCS) $(INCL) |
||||
|
cancel.obj: cancel.c $(CANCEL_SRCS) $(INCL) |
||||
|
condvar.obj: condvar.c $(CONDVAR_SRCS) $(INCL) |
||||
|
exit.obj: exit.c $(EXIT_SRCS) $(INCL) |
||||
|
misc.obj: misc.c $(MISC_SRCS) $(INCL) |
||||
|
mutex.obj: mutex.c $(MUTEX_SRCS) $(INCL) |
||||
|
nonportable.obj: nonportable.c $(NONPORTABLE_SRCS) $(INCL) |
||||
|
private.obj: private.c $(PRIVATE_SRCS) $(INCL) |
||||
|
rwlock.obj: rwlock.c $(RWLOCK_SRCS) $(INCL) |
||||
|
sched.obj: sched.c $(SCHED_SRCS) $(INCL) |
||||
|
semaphore.obj: semaphore.c $(SEMAPHORE_SRCS) $(INCL) |
||||
|
spin.obj: spin.c $(SPIN_SRCS) $(INCL) |
||||
|
sync.obj: sync.c $(SYNC_SRCS) $(INCL) |
||||
|
tsd.obj: tsd.c $(TSD_SRCS) $(INCL) |
||||
|
version.res: version.rc $(INCL) |
File diff suppressed because it is too large
@ -0,0 +1,24 @@ |
|||||
|
/* |
||||
|
* nmake file for uwin pthread library |
||||
|
*/ |
||||
|
|
||||
|
VERSION = - |
||||
|
CCFLAGS = -V -g $(CC.DLL) |
||||
|
HAVE_PTW32_CONFIG_H == 1 |
||||
|
_MT == 1 |
||||
|
_timeb == timeb |
||||
|
_ftime == ftime |
||||
|
_errno == _ast_errno |
||||
|
|
||||
|
$(INCLUDEDIR) :INSTALLDIR: pthread.h sched.h |
||||
|
|
||||
|
pthread $(VERSION) :LIBRARY: attr.c barrier.c cancel.c cleanup.c condvar.c \ |
||||
|
create.c dll.c exit.c fork.c global.c misc.c mutex.c private.c \ |
||||
|
rwlock.c sched.c semaphore.c spin.c sync.c tsd.c nonportable.c |
||||
|
|
||||
|
:: ANNOUNCE CONTRIBUTORS COPYING.LIB ChangeLog FAQ GNUmakefile MAINTAINERS \ |
||||
|
Makefile Makefile.in Makefile.vc NEWS PROGRESS README README.WinCE \ |
||||
|
TODO WinCE-PORT install-sh errno.c tests tests.mk acconfig.h \ |
||||
|
config.guess config.h.in config.sub configure configure.in signal.c \ |
||||
|
README.CV README.NONPORTABLE pthread.dsp pthread.dsw |
||||
|
|
@ -0,0 +1,260 @@ |
|||||
|
/* for running tests */ |
||||
|
CCFLAGS = -g |
||||
|
_MT == 1 |
||||
|
_timeb == timeb |
||||
|
_ftime == ftime |
||||
|
|
||||
|
.SOURCE: tests |
||||
|
/* |
||||
|
:PACKAGE: pthread |
||||
|
*/ |
||||
|
|
||||
|
set keepgoing |
||||
|
|
||||
|
":test:" : .MAKE .OPERATOR |
||||
|
local I |
||||
|
$(<:D:B:S=.pass) : .IMPLICIT $(>:D:B:S=.pass) |
||||
|
for I $(<) $(>) |
||||
|
$(I:D:B:S=.pass) : .VIRTUAL .FORCE $(I) |
||||
|
$(>) |
||||
|
end |
||||
|
sizes:: sizes.c |
||||
|
loadfree:: loadfree.c |
||||
|
mutex1:: mutex1.c |
||||
|
mutex1e:: mutex1e.c |
||||
|
mutex1n:: mutex1n.c |
||||
|
mutex1r:: mutex1r.c |
||||
|
mutex2:: mutex2.c |
||||
|
mutex2r:: mutex2r.c |
||||
|
mutex2e:: mutex2e.c |
||||
|
exit1:: exit1.c |
||||
|
condvar1:: condvar1.c |
||||
|
condvar1_1:: condvar1_1.c |
||||
|
condvar1_2:: condvar1_2.c |
||||
|
self1:: self1.c |
||||
|
condvar2:: condvar2.c |
||||
|
condvar2_1:: condvar2_1.c |
||||
|
condvar3_1:: condvar3_1.c |
||||
|
condvar3_2:: condvar3_2.c |
||||
|
condvar3_3:: condvar3_3.c |
||||
|
create1.:: create1.c |
||||
|
create2.:: create2.c |
||||
|
cancel1:: cancel1.c |
||||
|
cancel2:: cancel2.c |
||||
|
mutex3:: mutex3.c |
||||
|
mutex3r:: mutex3r.c |
||||
|
mutex3e:: mutex3e.c |
||||
|
mutex4:: mutex4.c |
||||
|
mutex5:: mutex5.c |
||||
|
mutex6:: mutex6.c |
||||
|
mutex6e:: mutex6e.c |
||||
|
mutex6n:: mutex6n.c |
||||
|
mutex6r:: mutex6r.c |
||||
|
mutex7:: mutex7.c |
||||
|
mutex6s:: mutex6s.c |
||||
|
mutex6rs:: mutex6rs.c |
||||
|
mutex6es:: mutex6es.c |
||||
|
mutex7e:: mutex7e.c |
||||
|
mutex7n:: mutex7n.c |
||||
|
mutex7r:: mutex7r.c |
||||
|
mutex8:: mutex8.c |
||||
|
mutex8e:: mutex8e.c |
||||
|
mutex8n:: mutex8n.c |
||||
|
mutex8r:: mutex8r.c |
||||
|
equal1:: equal1.c |
||||
|
exit2:: exit2.c |
||||
|
exit3:: exit3.c |
||||
|
exit4:: exit4.c |
||||
|
exit5:: exit5.c |
||||
|
join0:: join0.c |
||||
|
join1:: join1.c |
||||
|
join2:: join2.c |
||||
|
join3:: join3.c |
||||
|
kill1:: kill1.c |
||||
|
count1:: count1.c |
||||
|
once1:: once1.c |
||||
|
tsd1:: tsd1.c |
||||
|
self2:: self2.c |
||||
|
eyal1:: eyal1.c |
||||
|
condvar3:: condvar3.c |
||||
|
condvar4:: condvar4.c |
||||
|
condvar5:: condvar5.c |
||||
|
condvar6:: condvar6.c |
||||
|
condvar7:: condvar7.c |
||||
|
condvar8:: condvar8.c |
||||
|
condvar9:: condvar9.c |
||||
|
errno1:: errno1.c |
||||
|
reuse1.:: reuse1.c |
||||
|
reuse2.:: reuse2.c |
||||
|
rwlock1:: rwlock1.c |
||||
|
rwlock2:: rwlock2.c |
||||
|
rwlock3:: rwlock3.c |
||||
|
rwlock4:: rwlock4.c |
||||
|
rwlock5:: rwlock5.c |
||||
|
rwlock6:: rwlock6.c |
||||
|
rwlock7:: rwlock7.c |
||||
|
rwlock8:: rwlock8.c |
||||
|
rwlock2_t:: rwlock2_t.c |
||||
|
rwlock3_t:: rwlock3_t.c |
||||
|
rwlock4_t:: rwlock4_t.c |
||||
|
rwlock5_t:: rwlock5_t.c |
||||
|
rwlock6_t:: rwlock6_t.c |
||||
|
rwlock6_t2:: rwlock6_t2.c |
||||
|
semaphore1:: semaphore1.c |
||||
|
semaphore2:: semaphore2.c |
||||
|
semaphore3:: semaphore3.c |
||||
|
context1:: context1.c |
||||
|
cancel3:: cancel3.c |
||||
|
cancel4:: cancel4.c |
||||
|
cancel5:: cancel5.c |
||||
|
cancel6a:: cancel6a.c |
||||
|
cancel6d:: cancel6d.c |
||||
|
cancel7:: cancel7.c |
||||
|
cleanup0:: cleanup0.c |
||||
|
cleanup1:: cleanup1.c |
||||
|
cleanup2:: cleanup2.c |
||||
|
cleanup3:: cleanup3.c |
||||
|
priority1:: priority1.c |
||||
|
priority2:: priority2.c |
||||
|
inherit1:: inherit1.c |
||||
|
spin1:: spin1.c |
||||
|
spin2:: spin2.c |
||||
|
spin3:: spin3.c |
||||
|
spin4:: spin4.c |
||||
|
barrier1:: barrier1.c |
||||
|
barrier2:: barrier2.c |
||||
|
barrier3:: barrier3.c |
||||
|
barrier4:: barrier4.c |
||||
|
barrier5:: barrier5.c |
||||
|
exception1:: exception1.c |
||||
|
exception2:: exception2.c |
||||
|
exception3:: exception3.c |
||||
|
benchtest1:: benchtest1.c |
||||
|
benchtest2:: benchtest2.c |
||||
|
benchtest3:: benchtest3.c |
||||
|
benchtest4:: benchtest4.c |
||||
|
benchtest5:: benchtest5.c |
||||
|
valid1:: valid1.c |
||||
|
valid2:: valid2.c |
||||
|
cancel9:: cancel9.c |
||||
|
|
||||
|
sizes: :test: sizes |
||||
|
loadfree: :test: |
||||
|
mutex5 :test: loadfree |
||||
|
mutex1 :test: loadfree |
||||
|
mutex1n :test: loadfree |
||||
|
mutex1r :test: loadfree |
||||
|
mutex1e :test: loadfree |
||||
|
semaphore1 :test: loadfree |
||||
|
semaphore2 :test: loadfree |
||||
|
semaphore3 :test: loadfree |
||||
|
mutex2 :test: loadfree |
||||
|
mutex2r :test: loadfree |
||||
|
mutex2e :test: loadfree |
||||
|
exit1 :test: loadfree |
||||
|
condvar1 :test: loadfree |
||||
|
kill1 :test: loadfree |
||||
|
condvar1_1 :test: condvar1 |
||||
|
condvar1_2 :test: join2 |
||||
|
self1 :test: loadfree |
||||
|
condvar2 :test: condvar1 |
||||
|
condvar2_1 :test: condvar2 |
||||
|
create1 :test: mutex2 |
||||
|
create2 :test: create1 |
||||
|
reuse1 :test: create2 |
||||
|
reuse2 :test: reuse1 |
||||
|
cancel1 :test: create1 |
||||
|
cancel2 :test: cancel1 |
||||
|
mutex3 :test: create1 |
||||
|
mutex3r :test: create1 |
||||
|
mutex3e :test: create1 |
||||
|
mutex4 :test: mutex3 |
||||
|
mutex6 :test: mutex4 |
||||
|
mutex6n :test: mutex4 |
||||
|
mutex6e :test: mutex4 |
||||
|
mutex6r :test: mutex4 |
||||
|
mutex6s :test: mutex6 |
||||
|
mutex6rs :test: mutex6r |
||||
|
mutex6es :test: mutex6e |
||||
|
mutex7 :test: mutex6 |
||||
|
mutex7n :test: mutex6n |
||||
|
mutex7e :test: mutex6e |
||||
|
mutex7r :test: mutex6r |
||||
|
mutex8 :test: mutex7 |
||||
|
mutex8n :test: mutex7n |
||||
|
mutex8e :test: mutex7e |
||||
|
mutex8r :test: mutex7r |
||||
|
equal1 :test: create1 |
||||
|
exit2 :test: create1 |
||||
|
exit3 :test: create1 |
||||
|
exit4 :test: kill1 |
||||
|
exit5 :test: exit4 |
||||
|
join0 :test: create1 |
||||
|
join1 :test: create1 |
||||
|
join2 :test: create1 |
||||
|
join3 :test: join2 |
||||
|
count1 :test: join1 |
||||
|
once1 :test: create1 |
||||
|
tsd1 :test: join1 |
||||
|
self2 :test: create1 |
||||
|
eyal1 :test: tsd1 |
||||
|
condvar3 :test: create1 |
||||
|
condvar3_1 :test: condvar3 |
||||
|
condvar3_2 :test: condvar3_1 |
||||
|
condvar3_3 :test: condvar3_2 |
||||
|
condvar4 :test: create1 |
||||
|
condvar5 :test: condvar4 |
||||
|
condvar6 :test: condvar5 |
||||
|
condvar7 :test: condvar6 cleanup1 |
||||
|
condvar8 :test: condvar7 |
||||
|
condvar9 :test: condvar8 |
||||
|
errno1 :test: mutex3 |
||||
|
rwlock1 :test: condvar6 |
||||
|
rwlock2 :test: rwlock1 |
||||
|
rwlock3 :test: rwlock2 |
||||
|
rwlock4 :test: rwlock3 |
||||
|
rwlock5 :test: rwlock4 |
||||
|
rwlock6 :test: rwlock5 |
||||
|
rwlock7 :test: rwlock6 |
||||
|
rwlock8 :test: rwlock7 |
||||
|
rwlock2_t :test: rwlock2 |
||||
|
rwlock3_t :test: rwlock2_t |
||||
|
rwlock4_t :test: rwlock3_t |
||||
|
rwlock5_t :test: rwlock4_t |
||||
|
rwlock6_t :test: rwlock5_t |
||||
|
rwlock6_t2 :test: rwlock6_t |
||||
|
context1 :test: cancel2 |
||||
|
cancel3 :test: context1 |
||||
|
cancel4 :test: cancel3 |
||||
|
cancel5 :test: cancel3 |
||||
|
cancel6a :test: cancel3 |
||||
|
cancel6d :test: cancel3 |
||||
|
cancel7 :test: kill1 |
||||
|
cleanup0 :test: cancel5 |
||||
|
cleanup1 :test: cleanup0 |
||||
|
cleanup2 :test: cleanup1 |
||||
|
cleanup3 :test: cleanup2 |
||||
|
priority1 :test: join1 |
||||
|
priority2 :test: priority1 |
||||
|
inherit1 :test: join1 |
||||
|
spin1 :test: |
||||
|
spin2 :test: spin1.c |
||||
|
spin3 :test: spin2.c |
||||
|
spin4 :test: spin3.c |
||||
|
barrier1 :test: |
||||
|
barrier2 :test: barrier1.c |
||||
|
barrier3 :test: barrier2.c |
||||
|
barrier4 :test: barrier3.c |
||||
|
barrier5 :test: barrier4.c |
||||
|
benchtest1 :test: mutex3 |
||||
|
benchtest2 :test: benchtest1 |
||||
|
benchtest3 :test: benchtest2 |
||||
|
benchtest4 :test: benchtest3 |
||||
|
benchtest5 :test: benchtest4 |
||||
|
exception1 :test: cancel4 |
||||
|
exception2 :test: exception1 |
||||
|
exception3 :test: exception2 |
||||
|
exit4 :test: exit3 |
||||
|
valid1 :test: join1 |
||||
|
valid2 :test: valid1 |
||||
|
cancel9 :test: cancel8 |
@ -0,0 +1,4 @@ |
|||||
|
Please see the ANNOUNCE file "Level of Standards Conformance" |
||||
|
or the web page: |
||||
|
|
||||
|
http://sources.redhat.com/pthreads-win32/conformance.html |
@ -0,0 +1,601 @@ |
|||||
|
PTHREADS-WIN32 |
||||
|
============== |
||||
|
|
||||
|
Pthreads-win32 is free software, distributed under the GNU Lesser |
||||
|
General Public License (LGPL). See the file 'COPYING.LIB' for terms |
||||
|
and conditions. Also see the file 'COPYING' for information |
||||
|
specific to pthreads-win32, copyrights and the LGPL. |
||||
|
|
||||
|
|
||||
|
What is it? |
||||
|
----------- |
||||
|
|
||||
|
Pthreads-win32 is an Open Source Software implementation of the |
||||
|
Threads component of the POSIX 1003.1c 1995 Standard (or later) |
||||
|
for Microsoft's Win32 environment. Some functions from POSIX |
||||
|
1003.1b are also supported including semaphores. Other related |
||||
|
functions include the set of read-write lock functions. The |
||||
|
library also supports some of the functionality of the Open |
||||
|
Group's Single Unix specification, version 2, namely mutex types, |
||||
|
plus some common and pthreads-win32 specific non-portable |
||||
|
routines (see README.NONPORTABLE). |
||||
|
|
||||
|
See the file "ANNOUNCE" for more information including standards |
||||
|
conformance details and the list of supported and unsupported |
||||
|
routines. |
||||
|
|
||||
|
|
||||
|
Prerequisites |
||||
|
------------- |
||||
|
MSVC or GNU C (MinGW32 MSys development kit) |
||||
|
To build from source. |
||||
|
|
||||
|
QueueUserAPCEx by Panagiotis E. Hadjidoukas |
||||
|
To support any thread cancelation in C++ library builds or |
||||
|
to support cancelation of blocked threads in any build. |
||||
|
This library is not required otherwise. |
||||
|
|
||||
|
For true async cancelation of threads (including blocked threads). |
||||
|
This is a DLL and Windows driver that provides pre-emptive APC |
||||
|
by forcing threads into an alertable state when the APC is queued. |
||||
|
Both the DLL and driver are provided with the pthreads-win32.exe |
||||
|
self-unpacking ZIP, and on the pthreads-win32 FTP site (in source |
||||
|
and pre-built forms). Currently this is a separate LGPL package to |
||||
|
pthreads-win32. See the README in the QueueUserAPCEx folder for |
||||
|
installation instructions. |
||||
|
|
||||
|
Pthreads-win32 will automatically detect if the QueueUserAPCEx DLL |
||||
|
QuserEx.DLL is available and whether the driver AlertDrv.sys is |
||||
|
loaded. If it is not available, pthreads-win32 will simulate async |
||||
|
cancelation, which means that it can async cancel only threads that |
||||
|
are runnable. The simulated async cancellation cannot cancel blocked |
||||
|
threads. |
||||
|
|
||||
|
[FOR SECURITY] To be found Quserex.dll MUST be installed in the |
||||
|
Windows System Folder. This is not an unreasonable constraint given a |
||||
|
driver must also be installed and loaded at system startup. |
||||
|
|
||||
|
|
||||
|
Library naming |
||||
|
-------------- |
||||
|
|
||||
|
Because the library is being built using various exception |
||||
|
handling schemes and compilers - and because the library |
||||
|
may not work reliably if these are mixed in an application, |
||||
|
each different version of the library has it's own name. |
||||
|
|
||||
|
Note 1: the incompatibility is really between EH implementations |
||||
|
of the different compilers. It should be possible to use the |
||||
|
standard C version from either compiler with C++ applications |
||||
|
built with a different compiler. If you use an EH version of |
||||
|
the library, then you must use the same compiler for the |
||||
|
application. This is another complication and dependency that |
||||
|
can be avoided by using only the standard C library version. |
||||
|
|
||||
|
Note 2: if you use a standard C pthread*.dll with a C++ |
||||
|
application, then any functions that you define that are |
||||
|
intended to be called via pthread_cleanup_push() must be |
||||
|
__cdecl. |
||||
|
|
||||
|
Note 3: the intention was to also name either the VC or GC |
||||
|
version (it should be arbitrary) as pthread.dll, including |
||||
|
pthread.lib and libpthread.a as appropriate. This is no longer |
||||
|
likely to happen. |
||||
|
|
||||
|
Note 4: the compatibility number was added so that applications |
||||
|
can differentiate between binary incompatible versions of the |
||||
|
libs and dlls. |
||||
|
|
||||
|
In general: |
||||
|
pthread[VG]{SE,CE,C}[c].dll |
||||
|
pthread[VG]{SE,CE,C}[c].lib |
||||
|
|
||||
|
where: |
||||
|
[VG] indicates the compiler |
||||
|
V - MS VC, or |
||||
|
G - GNU C |
||||
|
|
||||
|
{SE,CE,C} indicates the exception handling scheme |
||||
|
SE - Structured EH, or |
||||
|
CE - C++ EH, or |
||||
|
C - no exceptions - uses setjmp/longjmp |
||||
|
|
||||
|
c - DLL compatibility number indicating ABI and API |
||||
|
compatibility with applications built against |
||||
|
a snapshot with the same compatibility number. |
||||
|
See 'Version numbering' below. |
||||
|
|
||||
|
The name may also be suffixed by a 'd' to indicate a debugging version |
||||
|
of the library. E.g. pthreadVC2d.lib. Debugging versions contain |
||||
|
additional information for debugging (symbols etc) and are often not |
||||
|
optimised in any way (compiled with optimisation turned off). |
||||
|
|
||||
|
Examples: |
||||
|
pthreadVSE.dll (MSVC/SEH) |
||||
|
pthreadGCE.dll (GNUC/C++ EH) |
||||
|
pthreadGC.dll (GNUC/not dependent on exceptions) |
||||
|
pthreadVC1.dll (MSVC/not dependent on exceptions - not binary |
||||
|
compatible with pthreadVC.dll) |
||||
|
pthreadVC2.dll (MSVC/not dependent on exceptions - not binary |
||||
|
compatible with pthreadVC1.dll or pthreadVC.dll) |
||||
|
|
||||
|
The GNU library archive file names have correspondingly changed to: |
||||
|
|
||||
|
libpthreadGCEc.a |
||||
|
libpthreadGCc.a |
||||
|
|
||||
|
|
||||
|
Versioning numbering |
||||
|
-------------------- |
||||
|
|
||||
|
Version numbering is separate from the snapshot dating system, and |
||||
|
is the canonical version identification system embedded within the |
||||
|
DLL using the Microsoft version resource system. The versioning |
||||
|
system chosen follows the GNU Libtool system. See |
||||
|
http://www.gnu.org/software/libtool/manual.html section 6.2. |
||||
|
|
||||
|
See the resource file 'version.rc'. |
||||
|
|
||||
|
Microsoft version numbers use 4 integers: |
||||
|
|
||||
|
0.0.0.0 |
||||
|
|
||||
|
Pthreads-win32 uses the first 3 following the Libtool convention. |
||||
|
The fourth is commonly used for the build number, but will be reserved |
||||
|
for future use. |
||||
|
|
||||
|
current.revision.age.0 |
||||
|
|
||||
|
The numbers are changed as follows: |
||||
|
|
||||
|
1. If the library source code has changed at all since the last update, |
||||
|
then increment revision (`c:r:a' becomes `c:r+1:a'). |
||||
|
2. If any interfaces have been added, removed, or changed since the last |
||||
|
update, increment current, and set revision to 0. |
||||
|
3. If any interfaces have been added since the last public release, then |
||||
|
increment age. |
||||
|
4. If any interfaces have been removed or changed since the last public |
||||
|
release, then set age to 0. |
||||
|
|
||||
|
|
||||
|
DLL compatibility numbering is an attempt to ensure that applications |
||||
|
always load a compatible pthreads-win32 DLL by using a DLL naming system |
||||
|
that is consistent with the version numbering system. It also allows |
||||
|
older and newer DLLs to coexist in the same filesystem so that older |
||||
|
applications can continue to be used. For pre .NET Windows systems, |
||||
|
this inevitably requires incompatible versions of the same DLLs to have |
||||
|
different names. |
||||
|
|
||||
|
Pthreads-win32 has adopted the Cygwin convention of appending a single |
||||
|
integer number to the DLL name. The number used is based on the library |
||||
|
version number and is computed as 'current' - 'age'. |
||||
|
|
||||
|
(See http://home.att.net/~perlspinr/libversioning.html for a nicely |
||||
|
detailed explanation.) |
||||
|
|
||||
|
Using this method, DLL name/s will only change when the DLL's |
||||
|
backwards compatibility changes. Note that the addition of new |
||||
|
'interfaces' will not of itself change the DLL's compatibility for older |
||||
|
applications. |
||||
|
|
||||
|
|
||||
|
Which of the several dll versions to use? |
||||
|
----------------------------------------- |
||||
|
or, |
||||
|
--- |
||||
|
What are all these pthread*.dll and pthread*.lib files? |
||||
|
------------------------------------------------------- |
||||
|
|
||||
|
Simple, use either pthreadGCv.* if you use GCC, or pthreadVCv.* if you |
||||
|
use MSVC - where 'v' is the DLL versioning (compatibility) number. |
||||
|
|
||||
|
Otherwise, you need to choose carefully and know WHY. |
||||
|
|
||||
|
The most important choice you need to make is whether to use a |
||||
|
version that uses exceptions internally, or not. There are versions |
||||
|
of the library that use exceptions as part of the thread |
||||
|
cancelation and exit implementation. The default version uses |
||||
|
setjmp/longjmp. |
||||
|
|
||||
|
There is some contension amongst POSIX threads experts as |
||||
|
to how POSIX threads cancelation and exit should work |
||||
|
with languages that use exceptions, e.g. C++ and even C |
||||
|
(Microsoft's Structured Exceptions). |
||||
|
|
||||
|
The issue is: should cancelation of a thread in, say, |
||||
|
a C++ application cause object destructors and C++ exception |
||||
|
handlers to be invoked as the stack unwinds during thread |
||||
|
exit, or not? |
||||
|
|
||||
|
There seems to be more opinion in favour of using the |
||||
|
standard C version of the library (no EH) with C++ applications |
||||
|
for the reason that this appears to be the assumption commercial |
||||
|
pthreads implementations make. Therefore, if you use an EH version |
||||
|
of pthreads-win32 then you may be under the illusion that |
||||
|
your application will be portable, when in fact it is likely to |
||||
|
behave differently when linked with other pthreads libraries. |
||||
|
|
||||
|
Now you may be asking: then why have you kept the EH versions of |
||||
|
the library? |
||||
|
|
||||
|
There are a couple of reasons: |
||||
|
- there is division amongst the experts and so the code may |
||||
|
be needed in the future. Yes, it's in the repository and we |
||||
|
can get it out anytime in the future, but it would be difficult |
||||
|
to find. |
||||
|
- pthreads-win32 is one of the few implementations, and possibly |
||||
|
the only freely available one, that has EH versions. It may be |
||||
|
useful to people who want to play with or study application |
||||
|
behaviour under these conditions. |
||||
|
|
||||
|
Notes: |
||||
|
|
||||
|
[If you use either pthreadVCE or pthreadGCE] |
||||
|
|
||||
|
1. [See also the discussion in the FAQ file - Q2, Q4, and Q5] |
||||
|
|
||||
|
If your application contains catch(...) blocks in your POSIX |
||||
|
threads then you will need to replace the "catch(...)" with the macro |
||||
|
"PtW32Catch", eg. |
||||
|
|
||||
|
#ifdef PtW32Catch |
||||
|
PtW32Catch { |
||||
|
... |
||||
|
} |
||||
|
#else |
||||
|
catch(...) { |
||||
|
... |
||||
|
} |
||||
|
#endif |
||||
|
|
||||
|
Otherwise neither pthreads cancelation nor pthread_exit() will work |
||||
|
reliably when using versions of the library that use C++ exceptions |
||||
|
for cancelation and thread exit. |
||||
|
|
||||
|
This is due to what is believed to be a C++ compliance error in VC++ |
||||
|
whereby you may not have multiple handlers for the same exception in |
||||
|
the same try/catch block. GNU G++ doesn't have this restriction. |
||||
|
|
||||
|
|
||||
|
Other name changes |
||||
|
------------------ |
||||
|
|
||||
|
All snapshots prior to and including snapshot 2000-08-13 |
||||
|
used "_pthread_" as the prefix to library internal |
||||
|
functions, and "_PTHREAD_" to many library internal |
||||
|
macros. These have now been changed to "ptw32_" and "PTW32_" |
||||
|
respectively so as to not conflict with the ANSI standard's |
||||
|
reservation of identifiers beginning with "_" and "__" for |
||||
|
use by compiler implementations only. |
||||
|
|
||||
|
If you have written any applications and you are linking |
||||
|
statically with the pthreads-win32 library then you may have |
||||
|
included a call to _pthread_processInitialize. You will |
||||
|
now have to change that to ptw32_processInitialize. |
||||
|
|
||||
|
|
||||
|
Cleanup code default style |
||||
|
-------------------------- |
||||
|
|
||||
|
Previously, if not defined, the cleanup style was determined automatically |
||||
|
from the compiler used, and one of the following was defined accordingly: |
||||
|
|
||||
|
__CLEANUP_SEH MSVC only |
||||
|
__CLEANUP_CXX C++, including MSVC++, GNU G++ |
||||
|
__CLEANUP_C C, including GNU GCC, not MSVC |
||||
|
|
||||
|
These defines determine the style of cleanup (see pthread.h) and, |
||||
|
most importantly, the way that cancelation and thread exit (via |
||||
|
pthread_exit) is performed (see the routine ptw32_throw()). |
||||
|
|
||||
|
In short, the exceptions versions of the library throw an exception |
||||
|
when a thread is canceled, or exits via pthread_exit(). This exception is |
||||
|
caught by a handler in the thread startup routine, so that the |
||||
|
the correct stack unwinding occurs regardless of where the thread |
||||
|
is when it's canceled or exits via pthread_exit(). |
||||
|
|
||||
|
In this snapshot, unless the build explicitly defines (e.g. via a |
||||
|
compiler option) __CLEANUP_SEH, __CLEANUP_CXX, or __CLEANUP_C, then |
||||
|
the build NOW always defaults to __CLEANUP_C style cleanup. This style |
||||
|
uses setjmp/longjmp in the cancelation and pthread_exit implementations, |
||||
|
and therefore won't do stack unwinding even when linked to applications |
||||
|
that have it (e.g. C++ apps). This is for consistency with most/all |
||||
|
commercial Unix POSIX threads implementations. |
||||
|
|
||||
|
Although it was not clearly documented before, it is still necessary to |
||||
|
build your application using the same __CLEANUP_* define as was |
||||
|
used for the version of the library that you link with, so that the |
||||
|
correct parts of pthread.h are included. That is, the possible |
||||
|
defines require the following library versions: |
||||
|
|
||||
|
__CLEANUP_SEH pthreadVSE.dll |
||||
|
__CLEANUP_CXX pthreadVCE.dll or pthreadGCE.dll |
||||
|
__CLEANUP_C pthreadVC.dll or pthreadGC.dll |
||||
|
|
||||
|
It is recommended that you let pthread.h use it's default __CLEANUP_C |
||||
|
for both library and application builds. That is, don't define any of |
||||
|
the above, and then link with pthreadVC.lib (MSVC or MSVC++) and |
||||
|
libpthreadGC.a (MinGW GCC or G++). The reason is explained below, but |
||||
|
another reason is that the prebuilt pthreadVCE.dll is currently broken. |
||||
|
Versions built with MSVC++ later than version 6 may not be broken, but I |
||||
|
can't verify this yet. |
||||
|
|
||||
|
WHY ARE WE MAKING THE DEFAULT STYLE LESS EXCEPTION-FRIENDLY? |
||||
|
Because no commercial Unix POSIX threads implementation allows you to |
||||
|
choose to have stack unwinding. Therefore, providing it in pthread-win32 |
||||
|
as a default is dangerous. We still provide the choice but unless |
||||
|
you consciously choose to do otherwise, your pthreads applications will |
||||
|
now run or crash in similar ways irrespective of the pthreads platform |
||||
|
you use. Or at least this is the hope. |
||||
|
|
||||
|
|
||||
|
Building under VC++ using C++ EH, Structured EH, or just C |
||||
|
---------------------------------------------------------- |
||||
|
|
||||
|
From the source directory run nmake without any arguments to list |
||||
|
help information. E.g. |
||||
|
|
||||
|
$ nmake |
||||
|
|
||||
|
Microsoft (R) Program Maintenance Utility Version 6.00.8168.0 |
||||
|
Copyright (C) Microsoft Corp 1988-1998. All rights reserved. |
||||
|
|
||||
|
Run one of the following command lines: |
||||
|
nmake clean VCE (to build the MSVC dll with C++ exception handling) |
||||
|
nmake clean VSE (to build the MSVC dll with structured exception handling) |
||||
|
nmake clean VC (to build the MSVC dll with C cleanup code) |
||||
|
nmake clean VCE-inlined (to build the MSVC inlined dll with C++ exception handling) |
||||
|
nmake clean VSE-inlined (to build the MSVC inlined dll with structured exception handling) |
||||
|
nmake clean VC-inlined (to build the MSVC inlined dll with C cleanup code) |
||||
|
nmake clean VC-static (to build the MSVC static lib with C cleanup code) |
||||
|
nmake clean VCE-debug (to build the debug MSVC dll with C++ exception handling) |
||||
|
nmake clean VSE-debug (to build the debug MSVC dll with structured exception handling) |
||||
|
nmake clean VC-debug (to build the debug MSVC dll with C cleanup code) |
||||
|
nmake clean VCE-inlined-debug (to build the debug MSVC inlined dll with C++ exception handling) |
||||
|
nmake clean VSE-inlined-debug (to build the debug MSVC inlined dll with structured exception handling) |
||||
|
nmake clean VC-inlined-debug (to build the debug MSVC inlined dll with C cleanup code) |
||||
|
nmake clean VC-static-debug (to build the debug MSVC static lib with C cleanup code) |
||||
|
|
||||
|
|
||||
|
The pre-built dlls are normally built using the *-inlined targets. |
||||
|
|
||||
|
You can run the testsuite by changing to the "tests" directory and |
||||
|
running nmake. E.g.: |
||||
|
|
||||
|
$ cd tests |
||||
|
$ nmake |
||||
|
|
||||
|
Microsoft (R) Program Maintenance Utility Version 6.00.8168.0 |
||||
|
Copyright (C) Microsoft Corp 1988-1998. All rights reserved. |
||||
|
|
||||
|
Run one of the following command lines: |
||||
|
nmake clean VC (to test using VC dll with VC (no EH) applications) |
||||
|
nmake clean VCX (to test using VC dll with VC++ (EH) applications) |
||||
|
nmake clean VCE (to test using the VCE dll with VC++ EH applications) |
||||
|
nmake clean VSE (to test using VSE dll with VC (SEH) applications) |
||||
|
nmake clean VC-bench (to benchtest using VC dll with C bench app) |
||||
|
nmake clean VCX-bench (to benchtest using VC dll with C++ bench app) |
||||
|
nmake clean VCE-bench (to benchtest using VCE dll with C++ bench app) |
||||
|
nmake clean VSE-bench (to benchtest using VSE dll with SEH bench app) |
||||
|
nmake clean VC-static (to test using VC static lib with VC (no EH) applications) |
||||
|
|
||||
|
|
||||
|
Building under Mingw32 |
||||
|
---------------------- |
||||
|
|
||||
|
The dll can be built easily with recent versions of Mingw32. |
||||
|
(The distributed versions are built using Mingw32 and MsysDTK |
||||
|
from www.mingw32.org.) |
||||
|
|
||||
|
From the source directory, run make for help information. E.g.: |
||||
|
|
||||
|
$ make |
||||
|
Run one of the following command lines: |
||||
|
make clean GC (to build the GNU C dll with C cleanup code) |
||||
|
make clean GCE (to build the GNU C dll with C++ exception handling) |
||||
|
make clean GC-inlined (to build the GNU C inlined dll with C cleanup code) |
||||
|
make clean GCE-inlined (to build the GNU C inlined dll with C++ exception handling) |
||||
|
make clean GC-static (to build the GNU C inlined static lib with C cleanup code) |
||||
|
make clean GC-debug (to build the GNU C debug dll with C cleanup code) |
||||
|
make clean GCE-debug (to build the GNU C debug dll with C++ exception handling) |
||||
|
make clean GC-inlined-debug (to build the GNU C inlined debug dll with C cleanup code) |
||||
|
make clean GCE-inlined-debug (to build the GNU C inlined debug dll with C++ exception handling) |
||||
|
make clean GC-static-debug (to build the GNU C inlined static debug lib with C cleanup code) |
||||
|
|
||||
|
|
||||
|
The pre-built dlls are normally built using the *-inlined targets. |
||||
|
|
||||
|
You can run the testsuite by changing to the "tests" directory and |
||||
|
running make for help information. E.g.: |
||||
|
|
||||
|
$ cd tests |
||||
|
$ make |
||||
|
Run one of the following command lines: |
||||
|
make clean GC (to test using GC dll with C (no EH) applications) |
||||
|
make clean GCX (to test using GC dll with C++ (EH) applications) |
||||
|
make clean GCE (to test using GCE dll with C++ (EH) applications) |
||||
|
make clean GC-bench (to benchtest using GNU C dll with C cleanup code) |
||||
|
make clean GCE-bench (to benchtest using GNU C dll with C++ exception handling) |
||||
|
make clean GC-static (to test using GC static lib with C (no EH) applications) |
||||
|
|
||||
|
|
||||
|
Building under Linux using the Mingw32 cross development tools |
||||
|
-------------------------------------------------------------- |
||||
|
|
||||
|
You can build the library without leaving Linux by using the Mingw32 cross |
||||
|
development toolchain. See http://www.libsdl.org/extras/win32/cross/ for |
||||
|
tools and info. The GNUmakefile contains some support for this, for example: |
||||
|
|
||||
|
make CROSS=i386-mingw32msvc- clean GC-inlined |
||||
|
|
||||
|
will build pthreadGCn.dll and libpthreadGCn.a (n=version#), provided your |
||||
|
cross-tools/bin directory is in your PATH (or use the cross-make.sh script |
||||
|
at the URL above). |
||||
|
|
||||
|
|
||||
|
Building the library as a statically linkable library |
||||
|
----------------------------------------------------- |
||||
|
|
||||
|
General: PTW32_STATIC_LIB must be defined for both the library build and the |
||||
|
application build. The makefiles supplied and used by the following 'make' |
||||
|
command lines will define this for you. |
||||
|
|
||||
|
MSVC (creates pthreadVCn.lib as a static link lib): |
||||
|
|
||||
|
nmake clean VC-static |
||||
|
|
||||
|
|
||||
|
MinGW32 (creates libpthreadGCn.a as a static link lib): |
||||
|
|
||||
|
make clean GC-static |
||||
|
|
||||
|
|
||||
|
Define PTW32_STATIC_LIB when building your application. Also, your |
||||
|
application must call a two non-portable routines to initialise the |
||||
|
some state on startup and cleanup before exit. One other routine needs |
||||
|
to be called to cleanup after any Win32 threads have called POSIX API |
||||
|
routines. See README.NONPORTABLE or the html reference manual pages for |
||||
|
details on these routines: |
||||
|
|
||||
|
BOOL pthread_win32_process_attach_np (void); |
||||
|
BOOL pthread_win32_process_detach_np (void); |
||||
|
BOOL pthread_win32_thread_attach_np (void); // Currently a no-op |
||||
|
BOOL pthread_win32_thread_detach_np (void); |
||||
|
|
||||
|
|
||||
|
The tests makefiles have the same targets but only check that the |
||||
|
static library is statically linkable. They don't run the full |
||||
|
testsuite. To run the full testsuite, build the dlls and run the |
||||
|
dll test targets. |
||||
|
|
||||
|
|
||||
|
Building the library under Cygwin |
||||
|
--------------------------------- |
||||
|
|
||||
|
Cygwin is implementing it's own POSIX threads routines and these |
||||
|
will be the ones to use if you develop using Cygwin. |
||||
|
|
||||
|
|
||||
|
Ready to run binaries |
||||
|
--------------------- |
||||
|
|
||||
|
For convenience, the following ready-to-run files can be downloaded |
||||
|
from the FTP site (see under "Availability" below): |
||||
|
|
||||
|
pthread.h |
||||
|
semaphore.h |
||||
|
sched.h |
||||
|
pthreadVC.dll - built with MSVC compiler using C setjmp/longjmp |
||||
|
pthreadVC.lib |
||||
|
pthreadVCE.dll - built with MSVC++ compiler using C++ EH |
||||
|
pthreadVCE.lib |
||||
|
pthreadVSE.dll - built with MSVC compiler using SEH |
||||
|
pthreadVSE.lib |
||||
|
pthreadGC.dll - built with Mingw32 GCC |
||||
|
libpthreadGC.a - derived from pthreadGC.dll |
||||
|
pthreadGCE.dll - built with Mingw32 G++ |
||||
|
libpthreadGCE.a - derived from pthreadGCE.dll |
||||
|
|
||||
|
As of August 2003 pthreads-win32 pthreadG* versions are built and tested |
||||
|
using the MinGW + MsysDTK environment current as of that date or later. |
||||
|
The following file MAY be needed for older MinGW environments. |
||||
|
|
||||
|
gcc.dll - needed to build and run applications that use |
||||
|
pthreadGCE.dll. |
||||
|
|
||||
|
|
||||
|
Building applications with GNU compilers |
||||
|
---------------------------------------- |
||||
|
|
||||
|
If you're using pthreadGC.dll: |
||||
|
|
||||
|
With the three header files, pthreadGC.dll and libpthreadGC.a in the |
||||
|
same directory as your application myapp.c, you could compile, link |
||||
|
and run myapp.c under Mingw32 as follows: |
||||
|
|
||||
|
gcc -o myapp.exe myapp.c -I. -L. -lpthreadGC |
||||
|
myapp |
||||
|
|
||||
|
Or put pthreadGC.dll in an appropriate directory in your PATH, |
||||
|
put libpthreadGC.a in your system lib directory, and |
||||
|
put the three header files in your system include directory, |
||||
|
then use: |
||||
|
|
||||
|
gcc -o myapp.exe myapp.c -lpthreadGC |
||||
|
myapp |
||||
|
|
||||
|
|
||||
|
If you're using pthreadGCE.dll: |
||||
|
|
||||
|
With the three header files, pthreadGCE.dll, gcc.dll and libpthreadGCE.a |
||||
|
in the same directory as your application myapp.c, you could compile, |
||||
|
link and run myapp.c under Mingw32 as follows: |
||||
|
|
||||
|
gcc -x c++ -o myapp.exe myapp.c -I. -L. -lpthreadGCE |
||||
|
myapp |
||||
|
|
||||
|
Or put pthreadGCE.dll and gcc.dll in an appropriate directory in |
||||
|
your PATH, put libpthreadGCE.a in your system lib directory, and |
||||
|
put the three header files in your system include directory, |
||||
|
then use: |
||||
|
|
||||
|
gcc -x c++ -o myapp.exe myapp.c -lpthreadGCE |
||||
|
myapp |
||||
|
|
||||
|
|
||||
|
Availability |
||||
|
------------ |
||||
|
|
||||
|
The complete source code in either unbundled, self-extracting |
||||
|
Zip file, or tar/gzipped format can be found at: |
||||
|
|
||||
|
ftp://sources.redhat.com/pub/pthreads-win32 |
||||
|
|
||||
|
The pre-built DLL, export libraries and matching pthread.h can |
||||
|
be found at: |
||||
|
|
||||
|
ftp://sources.redhat.com/pub/pthreads-win32/dll-latest |
||||
|
|
||||
|
Home page: |
||||
|
|
||||
|
http://sources.redhat.com/pthreads-win32/ |
||||
|
|
||||
|
|
||||
|
Mailing list |
||||
|
------------ |
||||
|
|
||||
|
There is a mailing list for discussing pthreads on Win32. |
||||
|
To join, send email to: |
||||
|
|
||||
|
pthreads-win32-subscribe@sources.redhat.com |
||||
|
|
||||
|
Unsubscribe by sending mail to: |
||||
|
|
||||
|
pthreads-win32-unsubscribe@sources.redhat.com |
||||
|
|
||||
|
|
||||
|
Acknowledgements |
||||
|
---------------- |
||||
|
|
||||
|
See the ANNOUNCE file for acknowledgements. |
||||
|
See the 'CONTRIBUTORS' file for the list of contributors. |
||||
|
|
||||
|
As much as possible, the ChangeLog file attributes |
||||
|
contributions and patches that have been incorporated |
||||
|
in the library to the individuals responsible. |
||||
|
|
||||
|
Finally, thanks to all those who work on and contribute to the |
||||
|
POSIX and Single Unix Specification standards. The maturity of an |
||||
|
industry can be measured by it's open standards. |
||||
|
|
||||
|
---- |
||||
|
Ross Johnson |
||||
|
<rpj@callisto.canberra.edu.au> |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
@ -0,0 +1,57 @@ |
|||||
|
In ptw32_InterlockedCompareExchange.c, I've added a section for |
||||
|
Borland's compiler; it's identical to that for the MS compiler except |
||||
|
that it uses /* ... */ comments instead of ; comments. |
||||
|
|
||||
|
[RPJ: need to define HAVE_TASM32 in config.h to use the above.] |
||||
|
|
||||
|
|
||||
|
The other file is a makefile suitable for use with Borland's compiler |
||||
|
(run "make -fBmakefile" in the directory). It builds a single version |
||||
|
of the library, pthreadBC.dll and the corresponding pthreadBC.lib |
||||
|
import library, which is comparable to the pthreadVC version; I can't |
||||
|
personally see any demand for the versions that include structured or |
||||
|
C++ exception cancellation handling so I haven't attempted to build |
||||
|
those versions of the library. (I imagine a static version might be |
||||
|
of use to some, but we can't legally use that on my commercial |
||||
|
projects so I can't try that out, unfortunately.) |
||||
|
|
||||
|
[RPJ: Added tests\Bmakefile as well.] |
||||
|
|
||||
|
Borland C++ doesn't define the ENOSYS constant used by pthreads-win32; |
||||
|
rather than make more extensive patches to the pthreads-win32 source I |
||||
|
have a mostly-arbitrary constant for it in the makefile. However this |
||||
|
doesn't make it visible to the application using the library, so if |
||||
|
anyone actually wants to use this constant in their apps (why?) |
||||
|
someone might like to make a seperate NEED_BCC_something define to add |
||||
|
this stuff. |
||||
|
|
||||
|
The makefile also #defines EDEADLK as EDEADLOCK, _timeb as timeb, and |
||||
|
_ftime as ftime, to deal with the minor differences between the two |
||||
|
RTLs' naming conventions, and sets the compiler flags as required to |
||||
|
get a normal compile of the library. |
||||
|
|
||||
|
[RPJ: Moved errno values and _timeb etc to pthread.h, so apps will also |
||||
|
use them.] |
||||
|
|
||||
|
(While I'm on the subject, the reason Borland users should recompile |
||||
|
the library, rather than using the impdef/implib technique suggested |
||||
|
previously on the mailing list, is that a) the errno constants are |
||||
|
different, so the results returned by the pthread_* functions can be |
||||
|
meaningless, and b) the errno variable/pseudo-variable itself is |
||||
|
different in the MS & BCC runtimes, so you can't access the |
||||
|
pthreadVC's errno from a Borland C++-compiled host application |
||||
|
correctly - I imagine there are other potential problems from the RTL |
||||
|
mismatch too.) |
||||
|
|
||||
|
[RPJ: Make sure you use the same RTL in both dll and application builds. |
||||
|
The dll and tests Bmakefiles use cw32mti.lib. Having some trouble with |
||||
|
memory read exceptions running the test suite using BCC55.] |
||||
|
|
||||
|
Best regards, |
||||
|
Will |
||||
|
|
||||
|
-- |
||||
|
Will Bryant |
||||
|
Systems Architect, eCOSM Limited |
||||
|
Cell +64 21 655 443, office +64 3 365 4176 |
||||
|
http://www.ecosm.com/ |
File diff suppressed because it is too large
@ -0,0 +1,783 @@ |
|||||
|
This file documents non-portable functions and other issues. |
||||
|
|
||||
|
Non-portable functions included in pthreads-win32 |
||||
|
------------------------------------------------- |
||||
|
|
||||
|
BOOL |
||||
|
pthread_win32_test_features_np(int mask) |
||||
|
|
||||
|
This routine allows an application to check which |
||||
|
run-time auto-detected features are available within |
||||
|
the library. |
||||
|
|
||||
|
The possible features are: |
||||
|
|
||||
|
PTW32_SYSTEM_INTERLOCKED_COMPARE_EXCHANGE |
||||
|
Return TRUE if the native version of |
||||
|
InterlockedCompareExchange() is being used. |
||||
|
This feature is not meaningful in recent |
||||
|
library versions as MSVC builds only support |
||||
|
system implemented ICE. Note that all Mingw |
||||
|
builds use inlined asm versions of all the |
||||
|
Interlocked routines. |
||||
|
PTW32_ALERTABLE_ASYNC_CANCEL |
||||
|
Return TRUE is the QueueUserAPCEx package |
||||
|
QUSEREX.DLL is available and the AlertDrv.sys |
||||
|
driver is loaded into Windows, providing |
||||
|
alertable (pre-emptive) asyncronous threads |
||||
|
cancelation. If this feature returns FALSE |
||||
|
then the default async cancel scheme is in |
||||
|
use, which cannot cancel blocked threads. |
||||
|
|
||||
|
Features may be Or'ed into the mask parameter, in which case |
||||
|
the routine returns TRUE if any of the Or'ed features would |
||||
|
return TRUE. At this stage it doesn't make sense to Or features |
||||
|
but it may some day. |
||||
|
|
||||
|
|
||||
|
void * |
||||
|
pthread_timechange_handler_np(void *) |
||||
|
|
||||
|
To improve tolerance against operator or time service |
||||
|
initiated system clock changes. |
||||
|
|
||||
|
This routine can be called by an application when it |
||||
|
receives a WM_TIMECHANGE message from the system. At |
||||
|
present it broadcasts all condition variables so that |
||||
|
waiting threads can wake up and re-evaluate their |
||||
|
conditions and restart their timed waits if required. |
||||
|
|
||||
|
It has the same return type and argument type as a |
||||
|
thread routine so that it may be called directly |
||||
|
through pthread_create(), i.e. as a separate thread. |
||||
|
|
||||
|
Parameters |
||||
|
|
||||
|
Although a parameter must be supplied, it is ignored. |
||||
|
The value NULL can be used. |
||||
|
|
||||
|
Return values |
||||
|
|
||||
|
It can return an error EAGAIN to indicate that not |
||||
|
all condition variables were broadcast for some reason. |
||||
|
Otherwise, 0 is returned. |
||||
|
|
||||
|
If run as a thread, the return value is returned |
||||
|
through pthread_join(). |
||||
|
|
||||
|
The return value should be cast to an integer. |
||||
|
|
||||
|
|
||||
|
HANDLE |
||||
|
pthread_getw32threadhandle_np(pthread_t thread); |
||||
|
|
||||
|
Returns the win32 thread handle that the POSIX |
||||
|
thread "thread" is running as. |
||||
|
|
||||
|
Applications can use the win32 handle to set |
||||
|
win32 specific attributes of the thread. |
||||
|
|
||||
|
DWORD |
||||
|
pthread_getw32threadid_np (pthread_t thread) |
||||
|
|
||||
|
Returns the Windows native thread ID that the POSIX |
||||
|
thread "thread" is running as. |
||||
|
|
||||
|
Only valid when the library is built where |
||||
|
! (defined(__MINGW64__) || defined(__MINGW32__)) || defined (__MSVCRT__) || defined (__DMC__) |
||||
|
and otherwise returns 0. |
||||
|
|
||||
|
|
||||
|
int |
||||
|
pthread_mutexattr_setkind_np(pthread_mutexattr_t * attr, int kind) |
||||
|
|
||||
|
int |
||||
|
pthread_mutexattr_getkind_np(pthread_mutexattr_t * attr, int *kind) |
||||
|
|
||||
|
These two routines are included for Linux compatibility |
||||
|
and are direct equivalents to the standard routines |
||||
|
pthread_mutexattr_settype |
||||
|
pthread_mutexattr_gettype |
||||
|
|
||||
|
pthread_mutexattr_setkind_np accepts the following |
||||
|
mutex kinds: |
||||
|
PTHREAD_MUTEX_FAST_NP |
||||
|
PTHREAD_MUTEX_ERRORCHECK_NP |
||||
|
PTHREAD_MUTEX_RECURSIVE_NP |
||||
|
|
||||
|
These are really just equivalent to (respectively): |
||||
|
PTHREAD_MUTEX_NORMAL |
||||
|
PTHREAD_MUTEX_ERRORCHECK |
||||
|
PTHREAD_MUTEX_RECURSIVE |
||||
|
|
||||
|
int |
||||
|
pthread_delay_np (const struct timespec *interval); |
||||
|
|
||||
|
This routine causes a thread to delay execution for a specific period of time. |
||||
|
This period ends at the current time plus the specified interval. The routine |
||||
|
will not return before the end of the period is reached, but may return an |
||||
|
arbitrary amount of time after the period has gone by. This can be due to |
||||
|
system load, thread priorities, and system timer granularity. |
||||
|
|
||||
|
Specifying an interval of zero (0) seconds and zero (0) nanoseconds is |
||||
|
allowed and can be used to force the thread to give up the processor or to |
||||
|
deliver a pending cancelation request. |
||||
|
|
||||
|
This routine is a cancelation point. |
||||
|
|
||||
|
The timespec structure contains the following two fields: |
||||
|
|
||||
|
tv_sec is an integer number of seconds. |
||||
|
tv_nsec is an integer number of nanoseconds. |
||||
|
|
||||
|
Return Values |
||||
|
|
||||
|
If an error condition occurs, this routine returns an integer value |
||||
|
indicating the type of error. Possible return values are as follows: |
||||
|
|
||||
|
0 Successful completion. |
||||
|
[EINVAL] The value specified by interval is invalid. |
||||
|
|
||||
|
int |
||||
|
pthread_num_processors_np (void) |
||||
|
|
||||
|
This routine (found on HPUX systems) returns the number of processors |
||||
|
in the system. This implementation actually returns the number of |
||||
|
processors available to the process, which can be a lower number |
||||
|
than the system's number, depending on the process's affinity mask. |
||||
|
|
||||
|
BOOL |
||||
|
pthread_win32_process_attach_np (void); |
||||
|
|
||||
|
BOOL |
||||
|
pthread_win32_process_detach_np (void); |
||||
|
|
||||
|
BOOL |
||||
|
pthread_win32_thread_attach_np (void); |
||||
|
|
||||
|
BOOL |
||||
|
pthread_win32_thread_detach_np (void); |
||||
|
|
||||
|
These functions contain the code normally run via dllMain |
||||
|
when the library is used as a dll but which need to be |
||||
|
called explicitly by an application when the library |
||||
|
is statically linked. As of version 2.9.0 of the library, static |
||||
|
builds using either MSC or GCC will call pthread_win32_process_* |
||||
|
automatically at application startup and exit respectively. |
||||
|
|
||||
|
Otherwise, you will need to call pthread_win32_process_attach_np() |
||||
|
before you can call any pthread routines when statically linking. |
||||
|
You should call pthread_win32_process_detach_np() before |
||||
|
exiting your application to clean up. |
||||
|
|
||||
|
pthread_win32_thread_attach_np() is currently a no-op, but |
||||
|
pthread_win32_thread_detach_np() is needed to clean up |
||||
|
the implicit pthread handle that is allocated to a Win32 thread if |
||||
|
it calls any pthreads routines. Call this routine when the |
||||
|
Win32 thread exits. |
||||
|
|
||||
|
Threads created through pthread_create() do not need to call |
||||
|
pthread_win32_thread_detach_np(). |
||||
|
|
||||
|
These functions invariably return TRUE except for |
||||
|
pthread_win32_process_attach_np() which will return FALSE |
||||
|
if pthreads-win32 initialisation fails. |
||||
|
|
||||
|
int |
||||
|
pthreadCancelableWait (HANDLE waitHandle); |
||||
|
|
||||
|
int |
||||
|
pthreadCancelableTimedWait (HANDLE waitHandle, DWORD timeout); |
||||
|
|
||||
|
These two functions provide hooks into the pthread_cancel |
||||
|
mechanism that will allow you to wait on a Windows handle |
||||
|
and make it a cancellation point. Both functions block |
||||
|
until either the given w32 handle is signaled, or |
||||
|
pthread_cancel has been called. It is implemented using |
||||
|
WaitForMultipleObjects on 'waitHandle' and a manually |
||||
|
reset w32 event used to implement pthread_cancel. |
||||
|
|
||||
|
|
||||
|
Non-portable issues |
||||
|
------------------- |
||||
|
|
||||
|
Thread priority |
||||
|
|
||||
|
POSIX defines a single contiguous range of numbers that determine a |
||||
|
thread's priority. Win32 defines priority classes and priority |
||||
|
levels relative to these classes. Classes are simply priority base |
||||
|
levels that the defined priority levels are relative to such that, |
||||
|
changing a process's priority class will change the priority of all |
||||
|
of it's threads, while the threads retain the same relativity to each |
||||
|
other. |
||||
|
|
||||
|
A Win32 system defines a single contiguous monotonic range of values |
||||
|
that define system priority levels, just like POSIX. However, Win32 |
||||
|
restricts individual threads to a subset of this range on a |
||||
|
per-process basis. |
||||
|
|
||||
|
The following table shows the base priority levels for combinations |
||||
|
of priority class and priority value in Win32. |
||||
|
|
||||
|
Process Priority Class Thread Priority Level |
||||
|
----------------------------------------------------------------- |
||||
|
1 IDLE_PRIORITY_CLASS THREAD_PRIORITY_IDLE |
||||
|
1 BELOW_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_IDLE |
||||
|
1 NORMAL_PRIORITY_CLASS THREAD_PRIORITY_IDLE |
||||
|
1 ABOVE_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_IDLE |
||||
|
1 HIGH_PRIORITY_CLASS THREAD_PRIORITY_IDLE |
||||
|
2 IDLE_PRIORITY_CLASS THREAD_PRIORITY_LOWEST |
||||
|
3 IDLE_PRIORITY_CLASS THREAD_PRIORITY_BELOW_NORMAL |
||||
|
4 IDLE_PRIORITY_CLASS THREAD_PRIORITY_NORMAL |
||||
|
4 BELOW_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_LOWEST |
||||
|
5 IDLE_PRIORITY_CLASS THREAD_PRIORITY_ABOVE_NORMAL |
||||
|
5 BELOW_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_BELOW_NORMAL |
||||
|
5 Background NORMAL_PRIORITY_CLASS THREAD_PRIORITY_LOWEST |
||||
|
6 IDLE_PRIORITY_CLASS THREAD_PRIORITY_HIGHEST |
||||
|
6 BELOW_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_NORMAL |
||||
|
6 Background NORMAL_PRIORITY_CLASS THREAD_PRIORITY_BELOW_NORMAL |
||||
|
7 BELOW_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_ABOVE_NORMAL |
||||
|
7 Background NORMAL_PRIORITY_CLASS THREAD_PRIORITY_NORMAL |
||||
|
7 Foreground NORMAL_PRIORITY_CLASS THREAD_PRIORITY_LOWEST |
||||
|
8 BELOW_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_HIGHEST |
||||
|
8 NORMAL_PRIORITY_CLASS THREAD_PRIORITY_ABOVE_NORMAL |
||||
|
8 Foreground NORMAL_PRIORITY_CLASS THREAD_PRIORITY_BELOW_NORMAL |
||||
|
8 ABOVE_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_LOWEST |
||||
|
9 NORMAL_PRIORITY_CLASS THREAD_PRIORITY_HIGHEST |
||||
|
9 Foreground NORMAL_PRIORITY_CLASS THREAD_PRIORITY_NORMAL |
||||
|
9 ABOVE_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_BELOW_NORMAL |
||||
|
10 Foreground NORMAL_PRIORITY_CLASS THREAD_PRIORITY_ABOVE_NORMAL |
||||
|
10 ABOVE_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_NORMAL |
||||
|
11 Foreground NORMAL_PRIORITY_CLASS THREAD_PRIORITY_HIGHEST |
||||
|
11 ABOVE_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_ABOVE_NORMAL |
||||
|
11 HIGH_PRIORITY_CLASS THREAD_PRIORITY_LOWEST |
||||
|
12 ABOVE_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_HIGHEST |
||||
|
12 HIGH_PRIORITY_CLASS THREAD_PRIORITY_BELOW_NORMAL |
||||
|
13 HIGH_PRIORITY_CLASS THREAD_PRIORITY_NORMAL |
||||
|
14 HIGH_PRIORITY_CLASS THREAD_PRIORITY_ABOVE_NORMAL |
||||
|
15 HIGH_PRIORITY_CLASS THREAD_PRIORITY_HIGHEST |
||||
|
15 HIGH_PRIORITY_CLASS THREAD_PRIORITY_TIME_CRITICAL |
||||
|
15 IDLE_PRIORITY_CLASS THREAD_PRIORITY_TIME_CRITICAL |
||||
|
15 BELOW_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_TIME_CRITICAL |
||||
|
15 NORMAL_PRIORITY_CLASS THREAD_PRIORITY_TIME_CRITICAL |
||||
|
15 ABOVE_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_TIME_CRITICAL |
||||
|
16 REALTIME_PRIORITY_CLASS THREAD_PRIORITY_IDLE |
||||
|
17 REALTIME_PRIORITY_CLASS -7 |
||||
|
18 REALTIME_PRIORITY_CLASS -6 |
||||
|
19 REALTIME_PRIORITY_CLASS -5 |
||||
|
20 REALTIME_PRIORITY_CLASS -4 |
||||
|
21 REALTIME_PRIORITY_CLASS -3 |
||||
|
22 REALTIME_PRIORITY_CLASS THREAD_PRIORITY_LOWEST |
||||
|
23 REALTIME_PRIORITY_CLASS THREAD_PRIORITY_BELOW_NORMAL |
||||
|
24 REALTIME_PRIORITY_CLASS THREAD_PRIORITY_NORMAL |
||||
|
25 REALTIME_PRIORITY_CLASS THREAD_PRIORITY_ABOVE_NORMAL |
||||
|
26 REALTIME_PRIORITY_CLASS THREAD_PRIORITY_HIGHEST |
||||
|
27 REALTIME_PRIORITY_CLASS 3 |
||||
|
28 REALTIME_PRIORITY_CLASS 4 |
||||
|
29 REALTIME_PRIORITY_CLASS 5 |
||||
|
30 REALTIME_PRIORITY_CLASS 6 |
||||
|
31 REALTIME_PRIORITY_CLASS THREAD_PRIORITY_TIME_CRITICAL |
||||
|
|
||||
|
Windows NT: Values -7, -6, -5, -4, -3, 3, 4, 5, and 6 are not supported. |
||||
|
|
||||
|
|
||||
|
As you can see, the real priority levels available to any individual |
||||
|
Win32 thread are non-contiguous. |
||||
|
|
||||
|
An application using pthreads-win32 should not make assumptions about |
||||
|
the numbers used to represent thread priority levels, except that they |
||||
|
are monotonic between the values returned by sched_get_priority_min() |
||||
|
and sched_get_priority_max(). E.g. Windows 95, 98, NT, 2000, XP make |
||||
|
available a non-contiguous range of numbers between -15 and 15, while |
||||
|
at least one version of WinCE (3.0) defines the minimum priority |
||||
|
(THREAD_PRIORITY_LOWEST) as 5, and the maximum priority |
||||
|
(THREAD_PRIORITY_HIGHEST) as 1. |
||||
|
|
||||
|
Internally, pthreads-win32 maps any priority levels between |
||||
|
THREAD_PRIORITY_IDLE and THREAD_PRIORITY_LOWEST to THREAD_PRIORITY_LOWEST, |
||||
|
or between THREAD_PRIORITY_TIME_CRITICAL and THREAD_PRIORITY_HIGHEST to |
||||
|
THREAD_PRIORITY_HIGHEST. Currently, this also applies to |
||||
|
REALTIME_PRIORITY_CLASSi even if levels -7, -6, -5, -4, -3, 3, 4, 5, and 6 |
||||
|
are supported. |
||||
|
|
||||
|
If it wishes, a Win32 application using pthreads-win32 can use the Win32 |
||||
|
defined priority macros THREAD_PRIORITY_IDLE through |
||||
|
THREAD_PRIORITY_TIME_CRITICAL. |
||||
|
|
||||
|
|
||||
|
The opacity of the pthread_t datatype |
||||
|
------------------------------------- |
||||
|
and possible solutions for portable null/compare/hash, etc |
||||
|
---------------------------------------------------------- |
||||
|
|
||||
|
Because pthread_t is an opague datatype an implementation is permitted to define |
||||
|
pthread_t in any way it wishes. That includes defining some bits, if it is |
||||
|
scalar, or members, if it is an aggregate, to store information that may be |
||||
|
extra to the unique identifying value of the ID. As a result, pthread_t values |
||||
|
may not be directly comparable. |
||||
|
|
||||
|
If you want your code to be portable you must adhere to the following contraints: |
||||
|
|
||||
|
1) Don't assume it is a scalar data type, e.g. an integer or pointer value. There |
||||
|
are several other implementations where pthread_t is also a struct. See our FAQ |
||||
|
Question 11 for our reasons for defining pthread_t as a struct. |
||||
|
|
||||
|
2) You must not compare them using relational or equality operators. You must use |
||||
|
the API function pthread_equal() to test for equality. |
||||
|
|
||||
|
3) Never attempt to reference individual members. |
||||
|
|
||||
|
|
||||
|
The problem |
||||
|
|
||||
|
Certain applications would like to be able to access only the 'pure' pthread_t |
||||
|
id values, primarily to use as keys into data structures to manage threads or |
||||
|
thread-related data, but this is not possible in a maximally portable and |
||||
|
standards compliant way for current POSIX threads implementations. |
||||
|
|
||||
|
For implementations that define pthread_t as a scalar, programmers often employ |
||||
|
direct relational and equality operators on pthread_t. This code will break when |
||||
|
ported to an implementation that defines pthread_t as an aggregate type. |
||||
|
|
||||
|
For implementations that define pthread_t as an aggregate, e.g. a struct, |
||||
|
programmers can use memcmp etc., but then face the prospect that the struct may |
||||
|
include alignment padding bytes or bits as well as extra implementation-specific |
||||
|
members that are not part of the unique identifying value. |
||||
|
|
||||
|
[While this is not currently the case for pthreads-win32, opacity also |
||||
|
means that an implementation is free to change the definition, which should |
||||
|
generally only require that applications be recompiled and relinked, not |
||||
|
rewritten.] |
||||
|
|
||||
|
|
||||
|
Doesn't the compiler take care of padding? |
||||
|
|
||||
|
The C89 and later standards only effectively guarrantee element-by-element |
||||
|
equivalence following an assignment or pass by value of a struct or union, |
||||
|
therefore undefined areas of any two otherwise equivalent pthread_t instances |
||||
|
can still compare differently, e.g. attempting to compare two such pthread_t |
||||
|
variables byte-by-byte, e.g. memcmp(&t1, &t2, sizeof(pthread_t) may give an |
||||
|
incorrect result. In practice I'm reasonably confident that compilers routinely |
||||
|
also copy the padding bytes, mainly because assignment of unions would be far |
||||
|
too complicated otherwise. But it just isn't guarranteed by the standard. |
||||
|
|
||||
|
Illustration: |
||||
|
|
||||
|
We have two thread IDs t1 and t2 |
||||
|
|
||||
|
pthread_t t1, t2; |
||||
|
|
||||
|
In an application we create the threads and intend to store the thread IDs in an |
||||
|
ordered data structure (linked list, tree, etc) so we need to be able to compare |
||||
|
them in order to insert them initially and also to traverse. |
||||
|
|
||||
|
Suppose pthread_t contains undefined padding bits and our compiler copies our |
||||
|
pthread_t [struct] element-by-element, then for the assignment: |
||||
|
|
||||
|
pthread_t temp = t1; |
||||
|
|
||||
|
temp and t1 will be equivalent and correct but a byte-for-byte comparison such as |
||||
|
memcmp(&temp, &t1, sizeof(pthread_t)) == 0 may not return true as we expect because |
||||
|
the undefined bits may not have the same values in the two variable instances. |
||||
|
|
||||
|
Similarly if passing by value under the same conditions. |
||||
|
|
||||
|
If, on the other hand, the undefined bits are at least constant through every |
||||
|
assignment and pass-by-value then the byte-for-byte comparison |
||||
|
memcmp(&temp, &t1, sizeof(pthread_t)) == 0 will always return the expected result. |
||||
|
How can we force the behaviour we need? |
||||
|
|
||||
|
|
||||
|
Solutions |
||||
|
|
||||
|
Adding new functions to the standard API or as non-portable extentions is |
||||
|
the only reliable and portable way to provide the necessary operations. |
||||
|
Remember also that POSIX is not tied to the C language. The most common |
||||
|
functions that have been suggested are: |
||||
|
|
||||
|
pthread_null() |
||||
|
pthread_compare() |
||||
|
pthread_hash() |
||||
|
|
||||
|
A single more general purpose function could also be defined as a |
||||
|
basis for at least the last two of the above functions. |
||||
|
|
||||
|
First we need to list the freedoms and constraints with restpect |
||||
|
to pthread_t so that we can be sure our solution is compatible with the |
||||
|
standard. |
||||
|
|
||||
|
What is known or may be deduced from the standard: |
||||
|
1) pthread_t must be able to be passed by value, so it must be a single object. |
||||
|
2) from (1) it must be copyable so cannot embed thread-state information, locks |
||||
|
or other volatile objects required to manage the thread it associates with. |
||||
|
3) pthread_t may carry additional information, e.g. for debugging or to manage |
||||
|
itself. |
||||
|
4) there is an implicit requirement that the size of pthread_t is determinable |
||||
|
at compile-time and size-invariant, because it must be able to copy the object |
||||
|
(i.e. through assignment and pass-by-value). Such copies must be genuine |
||||
|
duplicates, not merely a copy of a pointer to a common instance such as |
||||
|
would be the case if pthread_t were defined as an array. |
||||
|
|
||||
|
|
||||
|
Suppose we define the following function: |
||||
|
|
||||
|
/* This function shall return it's argument */ |
||||
|
pthread_t* pthread_normalize(pthread_t* thread); |
||||
|
|
||||
|
For scalar or aggregate pthread_t types this function would simply zero any bits |
||||
|
within the pthread_t that don't uniquely identify the thread, including padding, |
||||
|
such that client code can return consistent results from operations done on the |
||||
|
result. If the additional bits are a pointer to an associate structure then |
||||
|
this function would ensure that the memory used to store that associate |
||||
|
structure does not leak. After normalization the following compare would be |
||||
|
valid and repeatable: |
||||
|
|
||||
|
memcmp(pthread_normalize(&t1),pthread_normalize(&t2),sizeof(pthread_t)) |
||||
|
|
||||
|
Note 1: such comparisons are intended merely to order and sort pthread_t values |
||||
|
and allow them to index various data structures. They are not intended to reveal |
||||
|
anything about the relationships between threads, like startup order. |
||||
|
|
||||
|
Note 2: the normalized pthread_t is also a valid pthread_t that uniquely |
||||
|
identifies the same thread. |
||||
|
|
||||
|
Advantages: |
||||
|
1) In most existing implementations this function would reduce to a no-op that |
||||
|
emits no additional instructions, i.e after in-lining or optimisation, or if |
||||
|
defined as a macro: |
||||
|
#define pthread_normalise(tptr) (tptr) |
||||
|
|
||||
|
2) This single function allows an application to portably derive |
||||
|
application-level versions of any of the other required functions. |
||||
|
|
||||
|
3) It is a generic function that could enable unanticipated uses. |
||||
|
|
||||
|
Disadvantages: |
||||
|
1) Less efficient than dedicated compare or hash functions for implementations |
||||
|
that include significant extra non-id elements in pthread_t. |
||||
|
|
||||
|
2) Still need to be concerned about padding if copying normalized pthread_t. |
||||
|
See the later section on defining pthread_t to neutralise padding issues. |
||||
|
|
||||
|
Generally a pthread_t may need to be normalized every time it is used, |
||||
|
which could have a significant impact. However, this is a design decision |
||||
|
for the implementor in a competitive environment. An implementation is free |
||||
|
to define a pthread_t in a way that minimises or eliminates padding or |
||||
|
renders this function a no-op. |
||||
|
|
||||
|
Hazards: |
||||
|
1) Pass-by-reference directly modifies 'thread' so the application must |
||||
|
synchronise access or ensure that the pointer refers to a copy. The alternative |
||||
|
of pass-by-value/return-by-value was considered but then this requires two copy |
||||
|
operations, disadvantaging implementations where this function is not a no-op |
||||
|
in terms of speed of execution. This function is intended to be used in high |
||||
|
frequency situations and needs to be efficient, or at least not unnecessarily |
||||
|
inefficient. The alternative also sits awkwardly with functions like memcmp. |
||||
|
|
||||
|
2) [Non-compliant] code that uses relational and equality operators on |
||||
|
arithmetic or pointer style pthread_t types would need to be rewritten, but it |
||||
|
should be rewritten anyway. |
||||
|
|
||||
|
|
||||
|
C implementation of null/compare/hash functions using pthread_normalize(): |
||||
|
|
||||
|
/* In pthread.h */ |
||||
|
pthread_t* pthread_normalize(pthread_t* thread); |
||||
|
|
||||
|
/* In user code */ |
||||
|
/* User-level bitclear function - clear bits in loc corresponding to mask */ |
||||
|
void* bitclear (void* loc, void* mask, size_t count); |
||||
|
|
||||
|
typedef unsigned int hash_t; |
||||
|
|
||||
|
/* User-level hash function */ |
||||
|
hash_t hash(void* ptr, size_t count); |
||||
|
|
||||
|
/* |
||||
|
* User-level pthr_null function - modifies the origin thread handle. |
||||
|
* The concept of a null pthread_t is highly implementation dependent |
||||
|
* and this design may be far from the mark. For example, in an |
||||
|
* implementation "null" may mean setting a special value inside one |
||||
|
* element of pthread_t to mean "INVALID". However, if that value was zero and |
||||
|
* formed part of the id component then we may get away with this design. |
||||
|
*/ |
||||
|
pthread_t* pthr_null(pthread_t* tp) |
||||
|
{ |
||||
|
/* |
||||
|
* This should have the same effect as memset(tp, 0, sizeof(pthread_t)) |
||||
|
* We're just showing that we can do it. |
||||
|
*/ |
||||
|
void* p = (void*) pthread_normalize(tp); |
||||
|
return (pthread_t*) bitclear(p, p, sizeof(pthread_t)); |
||||
|
} |
||||
|
|
||||
|
/* |
||||
|
* Safe user-level pthr_compare function - modifies temporary thread handle copies |
||||
|
*/ |
||||
|
int pthr_compare_safe(pthread_t thread1, pthread_t thread2) |
||||
|
{ |
||||
|
return memcmp(pthread_normalize(&thread1), pthread_normalize(&thread2), sizeof(pthread_t)); |
||||
|
} |
||||
|
|
||||
|
/* |
||||
|
* Fast user-level pthr_compare function - modifies origin thread handles |
||||
|
*/ |
||||
|
int pthr_compare_fast(pthread_t* thread1, pthread_t* thread2) |
||||
|
{ |
||||
|
return memcmp(pthread_normalize(&thread1), pthread_normalize(&thread2), sizeof(pthread_t)); |
||||
|
} |
||||
|
|
||||
|
/* |
||||
|
* Safe user-level pthr_hash function - modifies temporary thread handle copy |
||||
|
*/ |
||||
|
hash_t pthr_hash_safe(pthread_t thread) |
||||
|
{ |
||||
|
return hash((void *) pthread_normalize(&thread), sizeof(pthread_t)); |
||||
|
} |
||||
|
|
||||
|
/* |
||||
|
* Fast user-level pthr_hash function - modifies origin thread handle |
||||
|
*/ |
||||
|
hash_t pthr_hash_fast(pthread_t thread) |
||||
|
{ |
||||
|
return hash((void *) pthread_normalize(&thread), sizeof(pthread_t)); |
||||
|
} |
||||
|
|
||||
|
/* User-level bitclear function - modifies the origin array */ |
||||
|
void* bitclear(void* loc, void* mask, size_t count) |
||||
|
{ |
||||
|
int i; |
||||
|
for (i=0; i < count; i++) { |
||||
|
(unsigned char) *loc++ &= ~((unsigned char) *mask++); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/* Donald Knuth hash */ |
||||
|
hash_t hash(void* str, size_t count) |
||||
|
{ |
||||
|
hash_t hash = (hash_t) count; |
||||
|
unsigned int i = 0; |
||||
|
|
||||
|
for(i = 0; i < len; str++, i++) |
||||
|
{ |
||||
|
hash = ((hash << 5) ^ (hash >> 27)) ^ (*str); |
||||
|
} |
||||
|
return hash; |
||||
|
} |
||||
|
|
||||
|
/* Example of advantage point (3) - split a thread handle into its id and non-id values */ |
||||
|
pthread_t id = thread, non-id = thread; |
||||
|
bitclear((void*) &non-id, (void*) pthread_normalize(&id), sizeof(pthread_t)); |
||||
|
|
||||
|
|
||||
|
A pthread_t type change proposal to neutralise the effects of padding |
||||
|
|
||||
|
Even if pthread_nornalize() is available, padding is still a problem because |
||||
|
the standard only garrantees element-by-element equivalence through |
||||
|
copy operations (assignment and pass-by-value). So padding bit values can |
||||
|
still change randomly after calls to pthread_normalize(). |
||||
|
|
||||
|
[I suspect that most compilers take the easy path and always byte-copy anyway, |
||||
|
partly because it becomes too complex to do (e.g. unions that contain sub-aggregates) |
||||
|
but also because programmers can easily design their aggregates to minimise and |
||||
|
often eliminate padding]. |
||||
|
|
||||
|
How can we eliminate the problem of padding bytes in structs? Could |
||||
|
defining pthread_t as a union rather than a struct provide a solution? |
||||
|
|
||||
|
In fact, the Linux pthread.h defines most of it's pthread_*_t objects (but not |
||||
|
pthread_t itself) as unions, possibly for this and/or other reasons. We'll |
||||
|
borrow some element naming from there but the ideas themselves are well known |
||||
|
- the __align element used to force alignment of the union comes from K&R's |
||||
|
storage allocator example. |
||||
|
|
||||
|
/* Essentially our current pthread_t renamed */ |
||||
|
typedef struct { |
||||
|
struct thread_state_t * __p; |
||||
|
long __x; /* sequence counter */ |
||||
|
} thread_id_t; |
||||
|
|
||||
|
Ensuring that the last element in the above struct is a long ensures that the |
||||
|
overall struct size is a multiple of sizeof(long), so there should be no trailing |
||||
|
padding in this struct or the union we define below. |
||||
|
(Later we'll see that we can handle internal but not trailing padding.) |
||||
|
|
||||
|
/* New pthread_t */ |
||||
|
typedef union { |
||||
|
char __size[sizeof(thread_id_t)]; /* array as the first element */ |
||||
|
thread_id_t __tid; |
||||
|
long __align; /* Ensure that the union starts on long boundary */ |
||||
|
} pthread_t; |
||||
|
|
||||
|
This guarrantees that, during an assignment or pass-by-value, the compiler copies |
||||
|
every byte in our thread_id_t because the compiler guarrantees that the __size |
||||
|
array, which we have ensured is the equal-largest element in the union, retains |
||||
|
equivalence. |
||||
|
|
||||
|
This means that pthread_t values stored, assigned and passed by value will at least |
||||
|
carry the value of any undefined padding bytes along and therefore ensure that |
||||
|
those values remain consistent. Our comparisons will return consistent results and |
||||
|
our hashes of [zero initialised] pthread_t values will also return consistent |
||||
|
results. |
||||
|
|
||||
|
We have also removed the need for a pthread_null() function; we can initialise |
||||
|
at declaration time or easily create our own const pthread_t to use in assignments |
||||
|
later: |
||||
|
|
||||
|
const pthread_t null_tid = {0}; /* braces are required */ |
||||
|
|
||||
|
pthread_t t; |
||||
|
... |
||||
|
t = null_tid; |
||||
|
|
||||
|
|
||||
|
Note that we don't have to explicitly make use of the __size array at all. It's |
||||
|
there just to force the compiler behaviour we want. |
||||
|
|
||||
|
|
||||
|
Partial solutions without a pthread_normalize function |
||||
|
|
||||
|
|
||||
|
An application-level pthread_null and pthread_compare proposal |
||||
|
(and pthread_hash proposal by extention) |
||||
|
|
||||
|
In order to deal with the problem of scalar/aggregate pthread_t type disparity in |
||||
|
portable code I suggest using an old-fashioned union, e.g.: |
||||
|
|
||||
|
Contraints: |
||||
|
- there is no padding, or padding values are preserved through assignment and |
||||
|
pass-by-value (see above); |
||||
|
- there are no extra non-id values in the pthread_t. |
||||
|
|
||||
|
|
||||
|
Example 1: A null initialiser for pthread_t variables... |
||||
|
|
||||
|
typedef union { |
||||
|
unsigned char b[sizeof(pthread_t)]; |
||||
|
pthread_t t; |
||||
|
} init_t; |
||||
|
|
||||
|
const init_t initial = {0}; |
||||
|
|
||||
|
pthread_t tid = initial.t; /* init tid to all zeroes */ |
||||
|
|
||||
|
|
||||
|
Example 2: A comparison function for pthread_t values |
||||
|
|
||||
|
typedef union { |
||||
|
unsigned char b[sizeof(pthread_t)]; |
||||
|
pthread_t t; |
||||
|
} pthcmp_t; |
||||
|
|
||||
|
int pthcmp(pthread_t left, pthread_t right) |
||||
|
{ |
||||
|
/* |
||||
|
* Compare two pthread handles in a way that imposes a repeatable but arbitrary |
||||
|
* ordering on them. |
||||
|
* I.e. given the same set of pthread_t handles the ordering should be the same |
||||
|
* each time but the order has no particular meaning other than that. E.g. |
||||
|
* the ordering does not imply the thread start sequence, or any other |
||||
|
* relationship between threads. |
||||
|
* |
||||
|
* Return values are: |
||||
|
* 1 : left is greater than right |
||||
|
* 0 : left is equal to right |
||||
|
* -1 : left is less than right |
||||
|
*/ |
||||
|
int i; |
||||
|
pthcmp_t L, R; |
||||
|
L.t = left; |
||||
|
R.t = right; |
||||
|
for (i = 0; i < sizeof(pthread_t); i++) |
||||
|
{ |
||||
|
if (L.b[i] > R.b[i]) |
||||
|
return 1; |
||||
|
else if (L.b[i] < R.b[i]) |
||||
|
return -1; |
||||
|
} |
||||
|
return 0; |
||||
|
} |
||||
|
|
||||
|
It has been pointed out that the C99 standard allows for the possibility that |
||||
|
integer types also may include padding bits, which could invalidate the above |
||||
|
method. This addition to C99 was specifically included after it was pointed |
||||
|
out that there was one, presumably not particularly well known, architecture |
||||
|
that included a padding bit in it's 32 bit integer type. See section 6.2.6.2 |
||||
|
of both the standard and the rationale, specifically the paragraph starting at |
||||
|
line 16 on page 43 of the rationale. |
||||
|
|
||||
|
|
||||
|
An aside |
||||
|
|
||||
|
Certain compilers, e.g. gcc and one of the IBM compilers, include a feature |
||||
|
extention: provided the union contains a member of the same type as the |
||||
|
object then the object may be cast to the union itself. |
||||
|
|
||||
|
We could use this feature to speed up the pthrcmp() function from example 2 |
||||
|
above by casting rather than assigning the pthread_t arguments to the union, e.g.: |
||||
|
|
||||
|
int pthcmp(pthread_t left, pthread_t right) |
||||
|
{ |
||||
|
/* |
||||
|
* Compare two pthread handles in a way that imposes a repeatable but arbitrary |
||||
|
* ordering on them. |
||||
|
* I.e. given the same set of pthread_t handles the ordering should be the same |
||||
|
* each time but the order has no particular meaning other than that. E.g. |
||||
|
* the ordering does not imply the thread start sequence, or any other |
||||
|
* relationship between threads. |
||||
|
* |
||||
|
* Return values are: |
||||
|
* 1 : left is greater than right |
||||
|
* 0 : left is equal to right |
||||
|
* -1 : left is less than right |
||||
|
*/ |
||||
|
int i; |
||||
|
for (i = 0; i < sizeof(pthread_t); i++) |
||||
|
{ |
||||
|
if (((pthcmp_t)left).b[i] > ((pthcmp_t)right).b[i]) |
||||
|
return 1; |
||||
|
else if (((pthcmp_t)left).b[i] < ((pthcmp_t)right).b[i]) |
||||
|
return -1; |
||||
|
} |
||||
|
return 0; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
Result thus far |
||||
|
|
||||
|
We can't remove undefined bits if they are there in pthread_t already, but we have |
||||
|
attempted to render them inert for comparison and hashing functions by making them |
||||
|
consistent through assignment, copy and pass-by-value. |
||||
|
|
||||
|
Note: Hashing pthread_t values requires that all pthread_t variables be initialised |
||||
|
to the same value (usually all zeros) before being assigned a proper thread ID, i.e. |
||||
|
to ensure that any padding bits are zero, or at least the same value for all |
||||
|
pthread_t. Since all pthread_t values are generated by the library in the first |
||||
|
instance this need not be an application-level operation. |
||||
|
|
||||
|
|
||||
|
Conclusion |
||||
|
|
||||
|
I've attempted to resolve the multiple issues of type opacity and the possible |
||||
|
presence of undefined bits and bytes in pthread_t values, which prevent |
||||
|
applications from comparing or hashing pthread handles. |
||||
|
|
||||
|
Two complimentary partial solutions have been proposed, one an application-level |
||||
|
scheme to handle both scalar and aggregate pthread_t types equally, plus a |
||||
|
definition of pthread_t itself that neutralises padding bits and bytes by |
||||
|
coercing semantics out of the compiler to eliminate variations in the values of |
||||
|
padding bits. |
||||
|
|
||||
|
I have not provided any solution to the problem of handling extra values embedded |
||||
|
in pthread_t, e.g. debugging or trap information that an implementation is entitled |
||||
|
to include. Therefore none of this replaces the portability and flexibility of API |
||||
|
functions but what functions are needed? The threads standard is unlikely to |
||||
|
include that can be implemented by a combination of existing features and more |
||||
|
generic functions (several references in the threads rationale suggest this. |
||||
|
Therefore I propose that the following function could replace the several functions |
||||
|
that have been suggested in conversations: |
||||
|
|
||||
|
pthread_t * pthread_normalize(pthread_t * handle); |
||||
|
|
||||
|
For most existing pthreads implementations this function, or macro, would reduce to |
||||
|
a no-op with zero call overhead. |
@ -0,0 +1,62 @@ |
|||||
|
Watcom compiler notes |
||||
|
===================== |
||||
|
|
||||
|
Status |
||||
|
------ |
||||
|
Not yet usable. Although the library builds under Watcom it |
||||
|
substantially fails the test suite. |
||||
|
|
||||
|
There is a working Wmakefile for wmake for the library build. |
||||
|
|
||||
|
invoke as any of: |
||||
|
wmake -f Wmakefile clean WC |
||||
|
wmake -f Wmakefile clean WC-inlined |
||||
|
wmake -f Wmakefile clean WCE |
||||
|
wmake -f Wmakefile clean WCE-inlined |
||||
|
|
||||
|
These build pthreadWC.dll and pthreadWCE.dll. |
||||
|
|
||||
|
There is a working Wmakefile for wmake for the test suite. |
||||
|
|
||||
|
invoke as any of: |
||||
|
wmake -f Wmakefile clean WC |
||||
|
wmake -f Wmakefile clean WCX |
||||
|
wmake -f Wmakefile clean WCE |
||||
|
wmake -f Wmakefile clean WC-bench |
||||
|
wmake -f Wmakefile clean WCX-bench |
||||
|
wmake -f Wmakefile clean WCE-bench |
||||
|
|
||||
|
|
||||
|
Current known problems |
||||
|
---------------------- |
||||
|
|
||||
|
Library build: |
||||
|
The Watcom compiler uses a different default call convention to MS C or GNU C and so |
||||
|
applications are not compatible with pthreadVC.dll etc using pre 2003-10-14 versions |
||||
|
of pthread.h, sched.h, or semaphore.h. The cdecl attribute can be used on exposed |
||||
|
function prototypes to force compatibility with MS C built DLLs. |
||||
|
|
||||
|
However, there appear to be other incompatibilities. Errno.h, for example, defines |
||||
|
different values for the standard C and POSIX errors to those defined by the MS C |
||||
|
errno.h. It may be that references to Watcom's threads compatible 'errno' do set |
||||
|
and return translated numbers consistently, but I have not verified this. |
||||
|
|
||||
|
Watcom defines errno as a dereferenced pointer returned by the function |
||||
|
_get_errno_ptr(). This is similar to both the MS and GNU C environments for |
||||
|
multithreaded use. However, the Watcom version appears to have a number of problems: |
||||
|
|
||||
|
- different threads return the same pointer value. Compare with the MS and GNU C |
||||
|
versions which correctly return different values (since each thread must maintain |
||||
|
a thread specific errno value). |
||||
|
|
||||
|
- an errno value set within the DLL appears as zero in the application even though |
||||
|
both share the same thread. |
||||
|
|
||||
|
Therefore applications built using the Watcom compiler may need to use |
||||
|
a Watcom built version of the library (pthreadWC.dll). If this is the case, then |
||||
|
the cdecl function attribute should not be required. |
||||
|
|
||||
|
Application builds: |
||||
|
The test suite fails with the Watcom compiler. |
||||
|
|
||||
|
Test semaphore1.c fails for pthreadWC.dll because errno returns 0 instead of EAGAIN. |
@ -0,0 +1,6 @@ |
|||||
|
WinCE port |
||||
|
---------- |
||||
|
(See the file WinCE-PORT for a detailed explanation.) |
||||
|
|
||||
|
Make sure you define "WINCE" amongst your compiler flags (eg. -DWINCE). |
||||
|
The config.h file will define all the necessary defines for you. |
@ -0,0 +1,7 @@ |
|||||
|
Things that aren't done yet |
||||
|
--------------------------- |
||||
|
|
||||
|
1. Implement PTHREAD_PROCESS_SHARED for semaphores, mutexes, |
||||
|
condition variables, read/write locks, barriers. |
||||
|
|
||||
|
|
@ -0,0 +1,222 @@ |
|||||
|
NOTE: The comments in this file relate to the original WinCE port |
||||
|
done by Tristan Savatier. The semaphore routines have been |
||||
|
completely rewritten since (2005-04-25), having been progressively |
||||
|
broken more and more by changes to the library. All of the semaphore |
||||
|
routines implemented for W9x/WNT/2000 and up should now also work for |
||||
|
WinCE. Also, pthread_mutex_timedlock should now work. |
||||
|
|
||||
|
Additional WinCE updates have been applied since this as well. Check the |
||||
|
ChangeLog file and search for WINCE for example. (2007-01-07) |
||||
|
|
||||
|
[RPJ] |
||||
|
|
||||
|
---- |
||||
|
|
||||
|
Some interesting news: |
||||
|
|
||||
|
I have been able to port pthread-win32 to Windows-CE, |
||||
|
which uses a subset of the WIN32 API. |
||||
|
|
||||
|
Since we intend to keep using pthread-win32 for our |
||||
|
Commercial WinCE developments, I would be very interested |
||||
|
if WinCE support could be added to the main source tree |
||||
|
of pthread-win32. Also, I would like to be credited |
||||
|
for this port :-) |
||||
|
|
||||
|
Now, here is the story... |
||||
|
|
||||
|
The port was performed and tested on a Casio "Cassiopeia" |
||||
|
PalmSize PC, which runs a MIP processor. The OS in the |
||||
|
Casio is WinCE version 2.11, but I used VC++ 6.0 with |
||||
|
the WinCE SDK for version 2.01. |
||||
|
|
||||
|
I used pthread-win32 to port a heavily multithreaded |
||||
|
commercial application (real-time MPEG video player) |
||||
|
from Linux to WinCE. I consider the changes that |
||||
|
I have done to be quite well tested. |
||||
|
|
||||
|
Overall the modifications that we had to do are minor. |
||||
|
|
||||
|
The WinCE port were based on pthread-win32-snap-1999-05-30, |
||||
|
but I am certain that they can be integrated very easiely |
||||
|
to more recent versions of the source. |
||||
|
|
||||
|
I have attached the modified source code: |
||||
|
pthread-win32-snap-1999-05-30-WinCE. |
||||
|
|
||||
|
All the changes do not affect the code compiled on non-WinCE |
||||
|
environment, provided that the macros used for WinCE compilation |
||||
|
are not used, of course! |
||||
|
|
||||
|
Overall description of the WinCE port: |
||||
|
------------------------------------- |
||||
|
|
||||
|
Most of the changes had to be made in areas where |
||||
|
pthread-win32 was relying on some standard-C librairies |
||||
|
(e.g. _ftime, calloc, errno), which are not available |
||||
|
on WinCE. We have changed the code to use native Win32 |
||||
|
API instead (or in some cases we made wrappers). |
||||
|
|
||||
|
The Win32 Semaphores are not available, |
||||
|
so we had to re-implement Semaphores using mutexes |
||||
|
and events. |
||||
|
|
||||
|
Limitations / known problems of the WinCE port: |
||||
|
---------------------------------------------- |
||||
|
|
||||
|
Not all the semaphore routines have been ported |
||||
|
(semaphores are defined by Posix but are not part |
||||
|
pf pthread). I have just done enough to make |
||||
|
pthread routines (that rely internally on semaphores) |
||||
|
work, like signal conditions. |
||||
|
|
||||
|
I noticed that the Win32 threads work slightly |
||||
|
differently on WinCE. This may have some impact |
||||
|
on some tricky parts of pthread-win32, but I have |
||||
|
not really investigated. For example, on WinCE, |
||||
|
the process is killed if the main thread falls off |
||||
|
the bottom (or calls pthread_exit), regardless |
||||
|
of the existence of any other detached thread. |
||||
|
Microsoft manual indicates that this behavior is |
||||
|
deffirent from that of Windows Threads for other |
||||
|
Win32 platforms. |
||||
|
|
||||
|
|
||||
|
Detailed descriptions of the changes and rationals: |
||||
|
|
||||
|
------------------------------------ |
||||
|
- use a new macro NEED_ERRNO. |
||||
|
|
||||
|
If defined, the code in errno.c that defines a reentrant errno |
||||
|
is compiled, regardless of _MT and _REENTRANT. |
||||
|
|
||||
|
Rational: On WinCE, there is no support for <stdio.h>, <errno.h> or |
||||
|
any other standard C library, i.e. even if _MT or _REENTRANT |
||||
|
is defined, errno is not provided by any library. NEED_ERRNO |
||||
|
must be set to compile for WinCE. |
||||
|
|
||||
|
------------------------------------ |
||||
|
- In implement.h, change #include <semaphore.h> to #include "semaphore.h". |
||||
|
|
||||
|
Rational: semaphore.h is provided in pthread-win32 and should not |
||||
|
be searched in the systems standard include. would not compile. |
||||
|
This change does not seem to create problems on "classic" win32 |
||||
|
(e.g. win95). |
||||
|
|
||||
|
------------------------------------ |
||||
|
- use a new macro NEED_CALLOC. |
||||
|
|
||||
|
If defined, some code in misc.c will provide a replacement |
||||
|
for calloc, which is not available on Win32. |
||||
|
|
||||
|
|
||||
|
------------------------------------ |
||||
|
- use a new macro NEED_CREATETHREAD. |
||||
|
|
||||
|
If defined, implement.h defines the macro _beginthreadex |
||||
|
and _endthreadex. |
||||
|
|
||||
|
Rational: On WinCE, the wrappers _beginthreadex and _endthreadex |
||||
|
do not exist. The native Win32 routines must be used. |
||||
|
|
||||
|
------------------------------------ |
||||
|
- in misc.c: |
||||
|
|
||||
|
#ifdef NEED_DUPLICATEHANDLE |
||||
|
/* DuplicateHandle does not exist on WinCE */ |
||||
|
self->threadH = GetCurrentThread(); |
||||
|
#else |
||||
|
if( !DuplicateHandle( |
||||
|
GetCurrentProcess(), |
||||
|
GetCurrentThread(), |
||||
|
GetCurrentProcess(), |
||||
|
&self->threadH, |
||||
|
0, |
||||
|
FALSE, |
||||
|
DUPLICATE_SAME_ACCESS ) ) |
||||
|
{ |
||||
|
free( self ); |
||||
|
return (NULL); |
||||
|
} |
||||
|
#endif |
||||
|
|
||||
|
Rational: On WinCE, DuplicateHandle does not exist. I could not understand |
||||
|
why DuplicateHandle must be used. It seems to me that getting the current |
||||
|
thread handle with GetCurrentThread() is sufficient, and it seems to work |
||||
|
perfectly fine, so maybe DuplicateHandle was just plain useless to begin with ? |
||||
|
|
||||
|
------------------------------------ |
||||
|
- In private.c, added some code at the beginning of ptw32_processInitialize |
||||
|
to detect the case of multiple calls to ptw32_processInitialize. |
||||
|
|
||||
|
Rational: In order to debug pthread-win32, it is easier to compile |
||||
|
it as a regular library (it is not possible to debug DLL's on winCE). |
||||
|
In that case, the application must call ptw32_rocessInitialize() |
||||
|
explicitely, to initialize pthread-win32. It is safer in this circumstance |
||||
|
to handle the case where ptw32_processInitialize() is called on |
||||
|
an already initialized library: |
||||
|
|
||||
|
int |
||||
|
ptw32_processInitialize (void) |
||||
|
{ |
||||
|
if (ptw32_processInitialized) { |
||||
|
/* |
||||
|
* ignore if already initialized. this is useful for |
||||
|
* programs that uses a non-dll pthread |
||||
|
* library. such programs must call ptw32_processInitialize() explicitely, |
||||
|
* since this initialization routine is automatically called only when |
||||
|
* the dll is loaded. |
||||
|
*/ |
||||
|
return TRUE; |
||||
|
} |
||||
|
ptw32_processInitialized = TRUE; |
||||
|
[...] |
||||
|
} |
||||
|
|
||||
|
------------------------------------ |
||||
|
- in private.c, if macro NEED_FTIME is defined, add routines to |
||||
|
convert timespec_to_filetime and filetime_to_timespec, and modified |
||||
|
code that was using _ftime() to use Win32 API instead. |
||||
|
|
||||
|
Rational: _ftime is not available on WinCE. It is necessary to use |
||||
|
the native Win32 time API instead. |
||||
|
|
||||
|
Note: the routine timespec_to_filetime is provided as a convenience and a mean |
||||
|
to test that filetime_to_timespec works, but it is not used by the library. |
||||
|
|
||||
|
------------------------------------ |
||||
|
- in semaphore.c, if macro NEED_SEM is defined, add code for the routines |
||||
|
_increase_semaphore and _decrease_semaphore, and modify significantly |
||||
|
the implementation of the semaphores so that it does not use CreateSemaphore. |
||||
|
|
||||
|
Rational: CreateSemaphore is not available on WinCE. I had to re-implement |
||||
|
semaphores using mutexes and Events. |
||||
|
|
||||
|
Note: Only the semaphore routines that are used by pthread are implemented |
||||
|
(i.e. signal conditions rely on a subset of the semaphores routines, and |
||||
|
this subset works). Some other semaphore routines (e.g. sem_trywait) are |
||||
|
not yet supported on my WinCE port (and since I don't need them, I am not |
||||
|
planning to do anything about them). |
||||
|
|
||||
|
------------------------------------ |
||||
|
- in tsd.c, changed the code that defines TLS_OUT_OF_INDEXES |
||||
|
|
||||
|
/* TLS_OUT_OF_INDEXES not defined on WinCE */ |
||||
|
#ifndef TLS_OUT_OF_INDEXES |
||||
|
#define TLS_OUT_OF_INDEXES 0xffffffff |
||||
|
#endif |
||||
|
|
||||
|
Rational: TLS_OUT_OF_INDEXES is not defined in any standard include file |
||||
|
on WinCE. |
||||
|
|
||||
|
------------------------------------ |
||||
|
- added file need_errno.h |
||||
|
|
||||
|
Rational: On WinCE, there is no errno.h file. need_errno.h is just a |
||||
|
copy of windows version of errno.h, with minor modifications due to the fact |
||||
|
that some of the error codes are defined by the WinCE socket library. |
||||
|
In pthread.h, if NEED_ERRNO is defined, the file need_errno.h is |
||||
|
included (instead of <errno.h>). |
||||
|
|
||||
|
|
||||
|
-- eof |
@ -0,0 +1,53 @@ |
|||||
|
/*
|
||||
|
* attr.c |
||||
|
* |
||||
|
* Description: |
||||
|
* This translation unit agregates operations on thread attribute objects. |
||||
|
* It is used for inline optimisation. |
||||
|
* |
||||
|
* The included modules are used separately when static executable sizes |
||||
|
* must be minimised. |
||||
|
* |
||||
|
* -------------------------------------------------------------------------- |
||||
|
* |
||||
|
* 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 |
||||
|
*/ |
||||
|
|
||||
|
#include "pthread.h" |
||||
|
#include "implement.h" |
||||
|
|
||||
|
#include "pthread_attr_init.c" |
||||
|
#include "pthread_attr_destroy.c" |
||||
|
#include "pthread_attr_getdetachstate.c" |
||||
|
#include "pthread_attr_setdetachstate.c" |
||||
|
#include "pthread_attr_getstackaddr.c" |
||||
|
#include "pthread_attr_setstackaddr.c" |
||||
|
#include "pthread_attr_getstacksize.c" |
||||
|
#include "pthread_attr_setstacksize.c" |
||||
|
#include "pthread_attr_getscope.c" |
||||
|
#include "pthread_attr_setscope.c" |
@ -0,0 +1,69 @@ |
|||||
|
/*
|
||||
|
* autostatic.c |
||||
|
* |
||||
|
* Description: |
||||
|
* This translation unit implements static auto-init and auto-exit logic. |
||||
|
* |
||||
|
* -------------------------------------------------------------------------- |
||||
|
* |
||||
|
* 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(PTW32_STATIC_LIB) |
||||
|
|
||||
|
#if defined(__MINGW64__) || defined(__MINGW32__) || defined(_MSC_VER) |
||||
|
|
||||
|
#include "pthread.h" |
||||
|
#include "implement.h" |
||||
|
|
||||
|
static void on_process_init(void) |
||||
|
{ |
||||
|
pthread_win32_process_attach_np (); |
||||
|
} |
||||
|
|
||||
|
static void on_process_exit(void) |
||||
|
{ |
||||
|
pthread_win32_thread_detach_np (); |
||||
|
pthread_win32_process_detach_np (); |
||||
|
} |
||||
|
|
||||
|
#if defined(__MINGW64__) || defined(__MINGW32__) |
||||
|
# define attribute_section(a) __attribute__((section(a))) |
||||
|
#elif defined(_MSC_VER) |
||||
|
# define attribute_section(a) __pragma(section(a,long,read)); __declspec(allocate(a)) |
||||
|
#endif |
||||
|
|
||||
|
attribute_section(".ctors") void *gcc_ctor = on_process_init; |
||||
|
attribute_section(".dtors") void *gcc_dtor = on_process_exit; |
||||
|
|
||||
|
attribute_section(".CRT$XCU") void *msc_ctor = on_process_init; |
||||
|
attribute_section(".CRT$XPU") void *msc_dtor = on_process_exit; |
||||
|
|
||||
|
#endif /* defined(__MINGW64__) || defined(__MINGW32__) || defined(_MSC_VER) */ |
||||
|
|
||||
|
#endif /* PTW32_STATIC_LIB */ |
@ -0,0 +1,47 @@ |
|||||
|
/*
|
||||
|
* barrier.c |
||||
|
* |
||||
|
* Description: |
||||
|
* This translation unit implements barrier primitives. |
||||
|
* |
||||
|
* -------------------------------------------------------------------------- |
||||
|
* |
||||
|
* 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 |
||||
|
*/ |
||||
|
|
||||
|
#include "pthread.h" |
||||
|
#include "implement.h" |
||||
|
|
||||
|
|
||||
|
#include "pthread_barrier_init.c" |
||||
|
#include "pthread_barrier_destroy.c" |
||||
|
#include "pthread_barrier_wait.c" |
||||
|
#include "pthread_barrierattr_init.c" |
||||
|
#include "pthread_barrierattr_destroy.c" |
||||
|
#include "pthread_barrierattr_getpshared.c" |
||||
|
#include "pthread_barrierattr_setpshared.c" |
@ -0,0 +1,191 @@ |
|||||
|
{ |
||||
|
'target_defaults': { |
||||
|
'default_configuration': 'Debug', |
||||
|
'configurations': { |
||||
|
# TODO: hoist these out and put them somewhere common, because |
||||
|
# RuntimeLibrary MUST MATCH across the entire project |
||||
|
'Debug': { |
||||
|
'defines': [ 'DEBUG', '_DEBUG' ], |
||||
|
'msvs_settings': { |
||||
|
'VCCLCompilerTool': { |
||||
|
'RuntimeLibrary': 1, # static debug |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
'Release': { |
||||
|
'defines': [ 'NDEBUG' ], |
||||
|
'msvs_settings': { |
||||
|
'VCCLCompilerTool': { |
||||
|
'RuntimeLibrary': 0, # static release |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
}, |
||||
|
|
||||
|
'targets': [ |
||||
|
{ |
||||
|
'target_name': 'pthread-win32', |
||||
|
'type': 'static_library', |
||||
|
'include_dirs': [ '../' ], |
||||
|
'direct_dependent_settings': { |
||||
|
'include_dirs': [ '../' ], |
||||
|
}, |
||||
|
'defines': [ |
||||
|
'HAVE_PTW32_CONFIG_H', |
||||
|
'__CLEANUP_C', |
||||
|
'WIN32' |
||||
|
], |
||||
|
'msvs_settings': { |
||||
|
'VCCLCompilerTool': { |
||||
|
}, |
||||
|
'VCLibrarianTool': { |
||||
|
}, |
||||
|
'VCLinkerTool': { |
||||
|
'GenerateDebugInformation': 'true', |
||||
|
}, |
||||
|
}, |
||||
|
'sources': [ |
||||
|
'../autostatic.c', |
||||
|
'../cleanup.c', |
||||
|
'../create.c', |
||||
|
'../dll.c', |
||||
|
'../errno.c', |
||||
|
'../fork.c', |
||||
|
'../global.c', |
||||
|
'../pthread_attr_destroy.c', |
||||
|
'../pthread_attr_getdetachstate.c', |
||||
|
'../pthread_attr_getinheritsched.c', |
||||
|
'../pthread_attr_getschedparam.c', |
||||
|
'../pthread_attr_getschedpolicy.c', |
||||
|
'../pthread_attr_getscope.c', |
||||
|
'../pthread_attr_getstackaddr.c', |
||||
|
'../pthread_attr_getstacksize.c', |
||||
|
'../pthread_attr_init.c', |
||||
|
'../pthread_attr_setdetachstate.c', |
||||
|
'../pthread_attr_setinheritsched.c', |
||||
|
'../pthread_attr_setschedparam.c', |
||||
|
'../pthread_attr_setschedpolicy.c', |
||||
|
'../pthread_attr_setscope.c', |
||||
|
'../pthread_attr_setstackaddr.c', |
||||
|
'../pthread_attr_setstacksize.c', |
||||
|
'../pthread_barrierattr_destroy.c', |
||||
|
'../pthread_barrierattr_getpshared.c', |
||||
|
'../pthread_barrierattr_init.c', |
||||
|
'../pthread_barrierattr_setpshared.c', |
||||
|
'../pthread_barrier_destroy.c', |
||||
|
'../pthread_barrier_init.c', |
||||
|
'../pthread_barrier_wait.c', |
||||
|
'../pthread_cancel.c', |
||||
|
'../pthread_condattr_destroy.c', |
||||
|
'../pthread_condattr_getpshared.c', |
||||
|
'../pthread_condattr_init.c', |
||||
|
'../pthread_condattr_setpshared.c', |
||||
|
'../pthread_cond_destroy.c', |
||||
|
'../pthread_cond_init.c', |
||||
|
'../pthread_cond_signal.c', |
||||
|
'../pthread_cond_wait.c', |
||||
|
'../pthread_delay_np.c', |
||||
|
'../pthread_detach.c', |
||||
|
'../pthread_equal.c', |
||||
|
'../pthread_exit.c', |
||||
|
'../pthread_getconcurrency.c', |
||||
|
'../pthread_getschedparam.c', |
||||
|
'../pthread_getspecific.c', |
||||
|
'../pthread_getunique_np.c', |
||||
|
'../pthread_getw32threadhandle_np.c', |
||||
|
'../pthread_join.c', |
||||
|
'../pthread_key_create.c', |
||||
|
'../pthread_key_delete.c', |
||||
|
'../pthread_kill.c', |
||||
|
'../pthread_mutexattr_destroy.c', |
||||
|
'../pthread_mutexattr_getkind_np.c', |
||||
|
'../pthread_mutexattr_getpshared.c', |
||||
|
'../pthread_mutexattr_getrobust.c', |
||||
|
'../pthread_mutexattr_gettype.c', |
||||
|
'../pthread_mutexattr_init.c', |
||||
|
'../pthread_mutexattr_setkind_np.c', |
||||
|
'../pthread_mutexattr_setpshared.c', |
||||
|
'../pthread_mutexattr_setrobust.c', |
||||
|
'../pthread_mutexattr_settype.c', |
||||
|
'../pthread_mutex_consistent.c', |
||||
|
'../pthread_mutex_destroy.c', |
||||
|
'../pthread_mutex_init.c', |
||||
|
'../pthread_mutex_lock.c', |
||||
|
'../pthread_mutex_timedlock.c', |
||||
|
'../pthread_mutex_trylock.c', |
||||
|
'../pthread_mutex_unlock.c', |
||||
|
'../pthread_num_processors_np.c', |
||||
|
'../pthread_once.c', |
||||
|
'../pthread_rwlockattr_destroy.c', |
||||
|
'../pthread_rwlockattr_getpshared.c', |
||||
|
'../pthread_rwlockattr_init.c', |
||||
|
'../pthread_rwlockattr_setpshared.c', |
||||
|
'../pthread_rwlock_destroy.c', |
||||
|
'../pthread_rwlock_init.c', |
||||
|
'../pthread_rwlock_rdlock.c', |
||||
|
'../pthread_rwlock_timedrdlock.c', |
||||
|
'../pthread_rwlock_timedwrlock.c', |
||||
|
'../pthread_rwlock_tryrdlock.c', |
||||
|
'../pthread_rwlock_trywrlock.c', |
||||
|
'../pthread_rwlock_unlock.c', |
||||
|
'../pthread_rwlock_wrlock.c', |
||||
|
'../pthread_self.c', |
||||
|
'../pthread_setcancelstate.c', |
||||
|
'../pthread_setcanceltype.c', |
||||
|
'../pthread_setconcurrency.c', |
||||
|
'../pthread_setschedparam.c', |
||||
|
'../pthread_setspecific.c', |
||||
|
'../pthread_spin_destroy.c', |
||||
|
'../pthread_spin_init.c', |
||||
|
'../pthread_spin_lock.c', |
||||
|
'../pthread_spin_trylock.c', |
||||
|
'../pthread_spin_unlock.c', |
||||
|
'../pthread_testcancel.c', |
||||
|
'../pthread_timechange_handler_np.c', |
||||
|
'../pthread_win32_attach_detach_np.c', |
||||
|
'../ptw32_calloc.c', |
||||
|
'../ptw32_callUserDestroyRoutines.c', |
||||
|
'../ptw32_cond_check_need_init.c', |
||||
|
'../ptw32_getprocessors.c', |
||||
|
'../ptw32_is_attr.c', |
||||
|
'../ptw32_MCS_lock.c', |
||||
|
'../ptw32_mutex_check_need_init.c', |
||||
|
'../ptw32_new.c', |
||||
|
'../ptw32_processInitialize.c', |
||||
|
'../ptw32_processTerminate.c', |
||||
|
'../ptw32_relmillisecs.c', |
||||
|
'../ptw32_reuse.c', |
||||
|
'../ptw32_rwlock_cancelwrwait.c', |
||||
|
'../ptw32_rwlock_check_need_init.c', |
||||
|
'../ptw32_semwait.c', |
||||
|
'../ptw32_spinlock_check_need_init.c', |
||||
|
'../ptw32_threadDestroy.c', |
||||
|
'../ptw32_threadStart.c', |
||||
|
'../ptw32_throw.c', |
||||
|
'../ptw32_timespec.c', |
||||
|
'../ptw32_tkAssocCreate.c', |
||||
|
'../ptw32_tkAssocDestroy.c', |
||||
|
'../sched_getscheduler.c', |
||||
|
'../sched_get_priority_max.c', |
||||
|
'../sched_get_priority_min.c', |
||||
|
'../sched_setscheduler.c', |
||||
|
'../sched_yield.c', |
||||
|
'../sem_close.c', |
||||
|
'../sem_destroy.c', |
||||
|
'../sem_getvalue.c', |
||||
|
'../sem_init.c', |
||||
|
'../sem_open.c', |
||||
|
'../sem_post.c', |
||||
|
'../sem_post_multiple.c', |
||||
|
'../sem_timedwait.c', |
||||
|
'../sem_trywait.c', |
||||
|
'../sem_unlink.c', |
||||
|
'../sem_wait.c', |
||||
|
'../signal.c', |
||||
|
'../w32_CancelableWait.c', |
||||
|
], |
||||
|
}, |
||||
|
] |
||||
|
} |
||||
|
|
@ -0,0 +1,9 @@ |
|||||
|
; Build the pthreads library with the Digital Mars Compiler |
||||
|
; |
||||
|
set DMCDIR=c:\dm |
||||
|
|
||||
|
; RELEASE |
||||
|
%DMCDIR%\bin\dmc -D_WIN32_WINNT -D_MT -DHAVE_PTW32_CONFIG_H -I.;c:\dm\include -o+all -WD pthread.c user32.lib+kernel32.lib+wsock32.lib -L/impl -L/NODEBUG -L/SU:WINDOWS |
||||
|
|
||||
|
; DEBUG |
||||
|
%DMCDIR%\bin\dmc -g -D_WIN32_WINNT -D_MT -DHAVE_PTW32_CONFIG_H -I.;c:\dm\include -o+all -WD pthread.c user32.lib+kernel32.lib+wsock32.lib -L/impl -L/SU:WINDOWS |
@ -0,0 +1,44 @@ |
|||||
|
/*
|
||||
|
* cancel.c |
||||
|
* |
||||
|
* Description: |
||||
|
* POSIX thread functions related to thread cancellation. |
||||
|
* |
||||
|
* -------------------------------------------------------------------------- |
||||
|
* |
||||
|
* 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 |
||||
|
*/ |
||||
|
|
||||
|
#include "pthread.h" |
||||
|
#include "implement.h" |
||||
|
|
||||
|
|
||||
|
#include "pthread_setcancelstate.c" |
||||
|
#include "pthread_setcanceltype.c" |
||||
|
#include "pthread_testcancel.c" |
||||
|
#include "pthread_cancel.c" |
@ -0,0 +1,148 @@ |
|||||
|
/*
|
||||
|
* cleanup.c |
||||
|
* |
||||
|
* Description: |
||||
|
* This translation unit implements routines associated |
||||
|
* with cleaning up threads. |
||||
|
* |
||||
|
* |
||||
|
* -------------------------------------------------------------------------- |
||||
|
* |
||||
|
* 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 |
||||
|
*/ |
||||
|
|
||||
|
#include "pthread.h" |
||||
|
#include "implement.h" |
||||
|
|
||||
|
|
||||
|
/*
|
||||
|
* The functions ptw32_pop_cleanup and ptw32_push_cleanup |
||||
|
* are implemented here for applications written in C with no |
||||
|
* SEH or C++ destructor support. |
||||
|
*/ |
||||
|
|
||||
|
ptw32_cleanup_t * |
||||
|
ptw32_pop_cleanup (int execute) |
||||
|
/*
|
||||
|
* ------------------------------------------------------ |
||||
|
* DOCPUBLIC |
||||
|
* This function pops the most recently pushed cleanup |
||||
|
* handler. If execute is nonzero, then the cleanup handler |
||||
|
* is executed if non-null. |
||||
|
* |
||||
|
* PARAMETERS |
||||
|
* execute |
||||
|
* if nonzero, execute the cleanup handler |
||||
|
* |
||||
|
* |
||||
|
* DESCRIPTION |
||||
|
* This function pops the most recently pushed cleanup |
||||
|
* handler. If execute is nonzero, then the cleanup handler |
||||
|
* is executed if non-null. |
||||
|
* NOTE: specify 'execute' as nonzero to avoid duplication |
||||
|
* of common cleanup code. |
||||
|
* |
||||
|
* RESULTS |
||||
|
* N/A |
||||
|
* |
||||
|
* ------------------------------------------------------ |
||||
|
*/ |
||||
|
{ |
||||
|
ptw32_cleanup_t *cleanup; |
||||
|
|
||||
|
cleanup = (ptw32_cleanup_t *) pthread_getspecific (ptw32_cleanupKey); |
||||
|
|
||||
|
if (cleanup != NULL) |
||||
|
{ |
||||
|
if (execute && (cleanup->routine != NULL)) |
||||
|
{ |
||||
|
|
||||
|
(*cleanup->routine) (cleanup->arg); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
pthread_setspecific (ptw32_cleanupKey, (void *) cleanup->prev); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
return (cleanup); |
||||
|
|
||||
|
} /* ptw32_pop_cleanup */ |
||||
|
|
||||
|
|
||||
|
void |
||||
|
ptw32_push_cleanup (ptw32_cleanup_t * cleanup, |
||||
|
ptw32_cleanup_callback_t routine, void *arg) |
||||
|
/*
|
||||
|
* ------------------------------------------------------ |
||||
|
* DOCPUBLIC |
||||
|
* This function pushes a new cleanup handler onto the thread's stack |
||||
|
* of cleanup handlers. Each cleanup handler pushed onto the stack is |
||||
|
* popped and invoked with the argument 'arg' when |
||||
|
* a) the thread exits by calling 'pthread_exit', |
||||
|
* b) when the thread acts on a cancellation request, |
||||
|
* c) or when the thread calls pthread_cleanup_pop with a nonzero |
||||
|
* 'execute' argument |
||||
|
* |
||||
|
* PARAMETERS |
||||
|
* cleanup |
||||
|
* a pointer to an instance of pthread_cleanup_t, |
||||
|
* |
||||
|
* routine |
||||
|
* pointer to a cleanup handler, |
||||
|
* |
||||
|
* arg |
||||
|
* parameter to be passed to the cleanup handler |
||||
|
* |
||||
|
* |
||||
|
* DESCRIPTION |
||||
|
* This function pushes a new cleanup handler onto the thread's stack |
||||
|
* of cleanup handlers. Each cleanup handler pushed onto the stack is |
||||
|
* popped and invoked with the argument 'arg' when |
||||
|
* a) the thread exits by calling 'pthread_exit', |
||||
|
* b) when the thread acts on a cancellation request, |
||||
|
* c) or when the thrad calls pthread_cleanup_pop with a nonzero |
||||
|
* 'execute' argument |
||||
|
* NOTE: pthread_push_cleanup, ptw32_pop_cleanup must be paired |
||||
|
* in the same lexical scope. |
||||
|
* |
||||
|
* RESULTS |
||||
|
* pthread_cleanup_t * |
||||
|
* pointer to the previous cleanup |
||||
|
* |
||||
|
* ------------------------------------------------------ |
||||
|
*/ |
||||
|
{ |
||||
|
cleanup->routine = routine; |
||||
|
cleanup->arg = arg; |
||||
|
|
||||
|
cleanup->prev = (ptw32_cleanup_t *) pthread_getspecific (ptw32_cleanupKey); |
||||
|
|
||||
|
pthread_setspecific (ptw32_cleanupKey, (void *) cleanup); |
||||
|
|
||||
|
} /* ptw32_push_cleanup */ |
@ -0,0 +1,50 @@ |
|||||
|
/*
|
||||
|
* condvar.c |
||||
|
* |
||||
|
* Description: |
||||
|
* This translation unit implements condition variables and their primitives. |
||||
|
* |
||||
|
* |
||||
|
* -------------------------------------------------------------------------- |
||||
|
* |
||||
|
* 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 |
||||
|
* |
||||
|
*/ |
||||
|
|
||||
|
#include "pthread.h" |
||||
|
#include "implement.h" |
||||
|
|
||||
|
#include "ptw32_cond_check_need_init.c" |
||||
|
#include "pthread_condattr_init.c" |
||||
|
#include "pthread_condattr_destroy.c" |
||||
|
#include "pthread_condattr_getpshared.c" |
||||
|
#include "pthread_condattr_setpshared.c" |
||||
|
#include "pthread_cond_init.c" |
||||
|
#include "pthread_cond_destroy.c" |
||||
|
#include "pthread_cond_wait.c" |
||||
|
#include "pthread_cond_signal.c" |
@ -0,0 +1,153 @@ |
|||||
|
/* config.h */ |
||||
|
|
||||
|
#ifndef PTW32_CONFIG_H |
||||
|
#define PTW32_CONFIG_H |
||||
|
|
||||
|
/*********************************************************************
|
||||
|
* Defaults: see target specific redefinitions below. |
||||
|
*********************************************************************/ |
||||
|
|
||||
|
/* We're building the pthreads-win32 library */ |
||||
|
#define PTW32_BUILD |
||||
|
|
||||
|
/* Do we know about the C type sigset_t? */ |
||||
|
#undef HAVE_SIGSET_T |
||||
|
|
||||
|
/* Define if you have the <signal.h> header file. */ |
||||
|
#undef HAVE_SIGNAL_H |
||||
|
|
||||
|
/* Define if you have the Borland TASM32 or compatible assembler. */ |
||||
|
#undef HAVE_TASM32 |
||||
|
|
||||
|
/* Define if you don't have Win32 DuplicateHandle. (eg. WinCE) */ |
||||
|
#undef NEED_DUPLICATEHANDLE |
||||
|
|
||||
|
/* Define if you don't have Win32 _beginthreadex. (eg. WinCE) */ |
||||
|
#undef NEED_CREATETHREAD |
||||
|
|
||||
|
/* Define if you don't have Win32 errno. (eg. WinCE) */ |
||||
|
#undef NEED_ERRNO |
||||
|
|
||||
|
/* Define if you don't have Win32 calloc. (eg. WinCE) */ |
||||
|
#undef NEED_CALLOC |
||||
|
|
||||
|
/* Define if you don't have Win32 ftime. (eg. WinCE) */ |
||||
|
#undef NEED_FTIME |
||||
|
|
||||
|
/* Define if you don't have Win32 semaphores. (eg. WinCE 2.1 or earlier) */ |
||||
|
#undef NEED_SEM |
||||
|
|
||||
|
/* Define if you need to convert string parameters to unicode. (eg. WinCE) */ |
||||
|
#undef NEED_UNICODE_CONSTS |
||||
|
|
||||
|
/* Define if your C (not C++) compiler supports "inline" functions. */ |
||||
|
#undef HAVE_C_INLINE |
||||
|
|
||||
|
/* Do we know about type mode_t? */ |
||||
|
#undef HAVE_MODE_T |
||||
|
|
||||
|
/*
|
||||
|
* Define if GCC has atomic builtins, i.e. __sync_* intrinsics |
||||
|
* __sync_lock_* is implemented in mingw32 gcc 4.5.2 at least |
||||
|
* so this define does not turn those on or off. If you get an |
||||
|
* error from __sync_lock* then consider upgrading your gcc. |
||||
|
*/ |
||||
|
#undef HAVE_GCC_ATOMIC_BUILTINS |
||||
|
|
||||
|
/* Define if you have the timespec struct */ |
||||
|
#undef HAVE_STRUCT_TIMESPEC |
||||
|
|
||||
|
/* Define if you don't have the GetProcessAffinityMask() */ |
||||
|
#undef NEED_PROCESS_AFFINITY_MASK |
||||
|
|
||||
|
/* Define if your version of Windows TLSGetValue() clears WSALastError
|
||||
|
* and calling SetLastError() isn't enough restore it. You'll also need to |
||||
|
* link against wsock32.lib (or libwsock32.a for MinGW). |
||||
|
*/ |
||||
|
#undef RETAIN_WSALASTERROR |
||||
|
|
||||
|
/*
|
||||
|
# ---------------------------------------------------------------------- |
||||
|
# The library can be built with some alternative behaviour to better |
||||
|
# facilitate development of applications on Win32 that will be ported |
||||
|
# to other POSIX systems. |
||||
|
# |
||||
|
# Nothing described here will make the library non-compliant and strictly |
||||
|
# compliant applications will not be affected in any way, but |
||||
|
# applications that make assumptions that POSIX does not guarantee are |
||||
|
# not strictly compliant and may fail or misbehave with some settings. |
||||
|
# |
||||
|
# PTW32_THREAD_ID_REUSE_INCREMENT |
||||
|
# Purpose: |
||||
|
# POSIX says that applications should assume that thread IDs can be |
||||
|
# recycled. However, Solaris (and some other systems) use a [very large] |
||||
|
# sequence number as the thread ID, which provides virtual uniqueness. |
||||
|
# This provides a very high but finite level of safety for applications |
||||
|
# that are not meticulous in tracking thread lifecycles e.g. applications |
||||
|
# that call functions which target detached threads without some form of |
||||
|
# thread exit synchronisation. |
||||
|
# |
||||
|
# Usage: |
||||
|
# Set to any value in the range: 0 <= value < 2^wordsize. |
||||
|
# Set to 0 to emulate reusable thread ID behaviour like Linux or *BSD. |
||||
|
# Set to 1 for unique thread IDs like Solaris (this is the default). |
||||
|
# Set to some factor of 2^wordsize to emulate smaller word size types |
||||
|
# (i.e. will wrap sooner). This might be useful to emulate some embedded |
||||
|
# systems. |
||||
|
# |
||||
|
# define PTW32_THREAD_ID_REUSE_INCREMENT 0 |
||||
|
# |
||||
|
# ---------------------------------------------------------------------- |
||||
|
*/ |
||||
|
#undef PTW32_THREAD_ID_REUSE_INCREMENT |
||||
|
|
||||
|
|
||||
|
/*********************************************************************
|
||||
|
* Target specific groups |
||||
|
* |
||||
|
* If you find that these are incorrect or incomplete please report it |
||||
|
* to the pthreads-win32 maintainer. Thanks. |
||||
|
*********************************************************************/ |
||||
|
#if defined(WINCE) |
||||
|
#define NEED_DUPLICATEHANDLE |
||||
|
#define NEED_CREATETHREAD |
||||
|
#define NEED_ERRNO |
||||
|
#define NEED_CALLOC |
||||
|
#define NEED_FTIME |
||||
|
/* #define NEED_SEM */ |
||||
|
#define NEED_UNICODE_CONSTS |
||||
|
#define NEED_PROCESS_AFFINITY_MASK |
||||
|
/* This may not be needed */ |
||||
|
#define RETAIN_WSALASTERROR |
||||
|
#endif |
||||
|
|
||||
|
#if defined(_UWIN) |
||||
|
#define HAVE_MODE_T |
||||
|
#define HAVE_STRUCT_TIMESPEC |
||||
|
#endif |
||||
|
|
||||
|
#if defined(__GNUC__) |
||||
|
#define HAVE_C_INLINE |
||||
|
#endif |
||||
|
|
||||
|
#if defined(__MINGW64__) |
||||
|
#define HAVE_MODE_T |
||||
|
#define HAVE_STRUCT_TIMESPEC |
||||
|
#elif defined(__MINGW32__) |
||||
|
#define HAVE_MODE_T |
||||
|
#endif |
||||
|
|
||||
|
#if defined(__BORLANDC__) |
||||
|
#endif |
||||
|
|
||||
|
#if defined(__WATCOMC__) |
||||
|
#endif |
||||
|
|
||||
|
#if defined(__DMC__) |
||||
|
#define HAVE_SIGNAL_H |
||||
|
#define HAVE_C_INLINE |
||||
|
#endif |
||||
|
|
||||
|
|
||||
|
|
||||
|
#endif |
@ -0,0 +1,74 @@ |
|||||
|
/*
|
||||
|
* context.h |
||||
|
* |
||||
|
* Description: |
||||
|
* POSIX thread macros related to thread cancellation. |
||||
|
* |
||||
|
* -------------------------------------------------------------------------- |
||||
|
* |
||||
|
* 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 PTW32_CONTEXT_H |
||||
|
#define PTW32_CONTEXT_H |
||||
|
|
||||
|
#undef PTW32_PROGCTR |
||||
|
|
||||
|
#if defined(_M_IX86) || (defined(_X86_) && !defined(__amd64__)) |
||||
|
#define PTW32_PROGCTR(Context) ((Context).Eip) |
||||
|
#endif |
||||
|
|
||||
|
#if defined (_M_IA64) || defined(_IA64) |
||||
|
#define PTW32_PROGCTR(Context) ((Context).StIIP) |
||||
|
#endif |
||||
|
|
||||
|
#if defined(_MIPS_) || defined(MIPS) |
||||
|
#define PTW32_PROGCTR(Context) ((Context).Fir) |
||||
|
#endif |
||||
|
|
||||
|
#if defined(_ALPHA_) |
||||
|
#define PTW32_PROGCTR(Context) ((Context).Fir) |
||||
|
#endif |
||||
|
|
||||
|
#if defined(_PPC_) |
||||
|
#define PTW32_PROGCTR(Context) ((Context).Iar) |
||||
|
#endif |
||||
|
|
||||
|
#if defined(_AMD64_) || defined(__amd64__) |
||||
|
#define PTW32_PROGCTR(Context) ((Context).Rip) |
||||
|
#endif |
||||
|
|
||||
|
#if defined(_ARM_) || defined(ARM) |
||||
|
#define PTW32_PROGCTR(Context) ((Context).Pc) |
||||
|
#endif |
||||
|
|
||||
|
#if !defined(PTW32_PROGCTR) |
||||
|
#error Module contains CPU-specific code; modify and recompile. |
||||
|
#endif |
||||
|
|
||||
|
#endif |
@ -0,0 +1,308 @@ |
|||||
|
/*
|
||||
|
* create.c |
||||
|
* |
||||
|
* Description: |
||||
|
* This translation unit implements routines associated with spawning a new |
||||
|
* thread. |
||||
|
* |
||||
|
* -------------------------------------------------------------------------- |
||||
|
* |
||||
|
* 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 |
||||
|
*/ |
||||
|
|
||||
|
#include "pthread.h" |
||||
|
#include "implement.h" |
||||
|
#if ! defined(_UWIN) && ! defined(WINCE) |
||||
|
#include <process.h> |
||||
|
#endif |
||||
|
|
||||
|
int |
||||
|
pthread_create (pthread_t * tid, |
||||
|
const pthread_attr_t * attr, |
||||
|
void *(*start) (void *), void *arg) |
||||
|
/*
|
||||
|
* ------------------------------------------------------ |
||||
|
* DOCPUBLIC |
||||
|
* This function creates a thread running the start function, |
||||
|
* passing it the parameter value, 'arg'. The 'attr' |
||||
|
* argument specifies optional creation attributes. |
||||
|
* The identity of the new thread is returned |
||||
|
* via 'tid', which should not be NULL. |
||||
|
* |
||||
|
* PARAMETERS |
||||
|
* tid |
||||
|
* pointer to an instance of pthread_t |
||||
|
* |
||||
|
* attr |
||||
|
* optional pointer to an instance of pthread_attr_t |
||||
|
* |
||||
|
* start |
||||
|
* pointer to the starting routine for the new thread |
||||
|
* |
||||
|
* arg |
||||
|
* optional parameter passed to 'start' |
||||
|
* |
||||
|
* |
||||
|
* DESCRIPTION |
||||
|
* This function creates a thread running the start function, |
||||
|
* passing it the parameter value, 'arg'. The 'attr' |
||||
|
* argument specifies optional creation attributes. |
||||
|
* The identity of the new thread is returned |
||||
|
* via 'tid', which should not be the NULL pointer. |
||||
|
* |
||||
|
* RESULTS |
||||
|
* 0 successfully created thread, |
||||
|
* EINVAL attr invalid, |
||||
|
* EAGAIN insufficient resources. |
||||
|
* |
||||
|
* ------------------------------------------------------ |
||||
|
*/ |
||||
|
{ |
||||
|
pthread_t thread; |
||||
|
ptw32_thread_t * tp; |
||||
|
register pthread_attr_t a; |
||||
|
HANDLE threadH = 0; |
||||
|
int result = EAGAIN; |
||||
|
int run = PTW32_TRUE; |
||||
|
ThreadParms *parms = NULL; |
||||
|
unsigned int stackSize; |
||||
|
int priority; |
||||
|
pthread_t self; |
||||
|
|
||||
|
/*
|
||||
|
* Before doing anything, check that tid can be stored through |
||||
|
* without invoking a memory protection error (segfault). |
||||
|
* Make sure that the assignment below can't be optimised out by the compiler. |
||||
|
* This is assured by conditionally assigning *tid again at the end. |
||||
|
*/ |
||||
|
tid->x = 0; |
||||
|
|
||||
|
if (attr != NULL) |
||||
|
{ |
||||
|
a = *attr; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
a = NULL; |
||||
|
} |
||||
|
|
||||
|
if ((thread = ptw32_new ()).p == NULL) |
||||
|
{ |
||||
|
goto FAIL0; |
||||
|
} |
||||
|
|
||||
|
tp = (ptw32_thread_t *) thread.p; |
||||
|
|
||||
|
priority = tp->sched_priority; |
||||
|
|
||||
|
if ((parms = (ThreadParms *) malloc (sizeof (*parms))) == NULL) |
||||
|
{ |
||||
|
goto FAIL0; |
||||
|
} |
||||
|
|
||||
|
parms->tid = thread; |
||||
|
parms->start = start; |
||||
|
parms->arg = arg; |
||||
|
|
||||
|
#if defined(HAVE_SIGSET_T) |
||||
|
|
||||
|
/*
|
||||
|
* Threads inherit their initial sigmask from their creator thread. |
||||
|
*/ |
||||
|
self = pthread_self(); |
||||
|
tp->sigmask = ((ptw32_thread_t *)self.p)->sigmask; |
||||
|
|
||||
|
#endif /* HAVE_SIGSET_T */ |
||||
|
|
||||
|
|
||||
|
if (a != NULL) |
||||
|
{ |
||||
|
stackSize = (unsigned int)a->stacksize; |
||||
|
tp->detachState = a->detachstate; |
||||
|
priority = a->param.sched_priority; |
||||
|
|
||||
|
#if (THREAD_PRIORITY_LOWEST > THREAD_PRIORITY_NORMAL) |
||||
|
/* WinCE */ |
||||
|
#else |
||||
|
/* Everything else */ |
||||
|
|
||||
|
/*
|
||||
|
* Thread priority must be set to a valid system level |
||||
|
* without altering the value set by pthread_attr_setschedparam(). |
||||
|
*/ |
||||
|
|
||||
|
/*
|
||||
|
* PTHREAD_EXPLICIT_SCHED is the default because Win32 threads |
||||
|
* don't inherit their creator's priority. They are started with |
||||
|
* THREAD_PRIORITY_NORMAL (win32 value). The result of not supplying |
||||
|
* an 'attr' arg to pthread_create() is equivalent to defaulting to |
||||
|
* PTHREAD_EXPLICIT_SCHED and priority THREAD_PRIORITY_NORMAL. |
||||
|
*/ |
||||
|
if (PTHREAD_INHERIT_SCHED == a->inheritsched) |
||||
|
{ |
||||
|
/*
|
||||
|
* If the thread that called pthread_create() is a Win32 thread |
||||
|
* then the inherited priority could be the result of a temporary |
||||
|
* system adjustment. This is not the case for POSIX threads. |
||||
|
*/ |
||||
|
#if ! defined(HAVE_SIGSET_T) |
||||
|
self = pthread_self (); |
||||
|
#endif |
||||
|
priority = ((ptw32_thread_t *) self.p)->sched_priority; |
||||
|
} |
||||
|
|
||||
|
#endif |
||||
|
|
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
/*
|
||||
|
* Default stackSize |
||||
|
*/ |
||||
|
stackSize = PTHREAD_STACK_MIN; |
||||
|
} |
||||
|
|
||||
|
tp->state = run ? PThreadStateInitial : PThreadStateSuspended; |
||||
|
|
||||
|
tp->keys = NULL; |
||||
|
|
||||
|
/*
|
||||
|
* Threads must be started in suspended mode and resumed if necessary |
||||
|
* after _beginthreadex returns us the handle. Otherwise we set up a |
||||
|
* race condition between the creating and the created threads. |
||||
|
* Note that we also retain a local copy of the handle for use |
||||
|
* by us in case thread.p->threadH gets NULLed later but before we've |
||||
|
* finished with it here. |
||||
|
*/ |
||||
|
|
||||
|
#if ! (defined (__MINGW64__) || defined(__MINGW32__)) || defined (__MSVCRT__) || defined (__DMC__) |
||||
|
|
||||
|
tp->threadH = |
||||
|
threadH = |
||||
|
(HANDLE) _beginthreadex ((void *) NULL, /* No security info */ |
||||
|
stackSize, /* default stack size */ |
||||
|
ptw32_threadStart, |
||||
|
parms, |
||||
|
(unsigned) |
||||
|
CREATE_SUSPENDED, |
||||
|
(unsigned *) &(tp->thread)); |
||||
|
|
||||
|
if (threadH != 0) |
||||
|
{ |
||||
|
if (a != NULL) |
||||
|
{ |
||||
|
(void) ptw32_setthreadpriority (thread, SCHED_OTHER, priority); |
||||
|
} |
||||
|
|
||||
|
if (run) |
||||
|
{ |
||||
|
ResumeThread (threadH); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
#else |
||||
|
|
||||
|
{ |
||||
|
ptw32_mcs_local_node_t stateLock; |
||||
|
|
||||
|
/*
|
||||
|
* This lock will force pthread_threadStart() to wait until we have |
||||
|
* the thread handle and have set the priority. |
||||
|
*/ |
||||
|
ptw32_mcs_lock_acquire(&tp->stateLock, &stateLock); |
||||
|
|
||||
|
tp->threadH = |
||||
|
threadH = |
||||
|
(HANDLE) _beginthread (ptw32_threadStart, stackSize, /* default stack size */ |
||||
|
parms); |
||||
|
|
||||
|
/*
|
||||
|
* Make the return code match _beginthreadex's. |
||||
|
*/ |
||||
|
if (threadH == (HANDLE) - 1L) |
||||
|
{ |
||||
|
tp->threadH = threadH = 0; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
if (!run) |
||||
|
{ |
||||
|
/*
|
||||
|
* beginthread does not allow for create flags, so we do it now. |
||||
|
* Note that beginthread itself creates the thread in SUSPENDED |
||||
|
* mode, and then calls ResumeThread to start it. |
||||
|
*/ |
||||
|
SuspendThread (threadH); |
||||
|
} |
||||
|
|
||||
|
if (a != NULL) |
||||
|
{ |
||||
|
(void) ptw32_setthreadpriority (thread, SCHED_OTHER, priority); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
ptw32_mcs_lock_release (&stateLock); |
||||
|
} |
||||
|
#endif |
||||
|
|
||||
|
result = (threadH != 0) ? 0 : EAGAIN; |
||||
|
|
||||
|
/*
|
||||
|
* Fall Through Intentionally |
||||
|
*/ |
||||
|
|
||||
|
/*
|
||||
|
* ------------ |
||||
|
* Failure Code |
||||
|
* ------------ |
||||
|
*/ |
||||
|
|
||||
|
FAIL0: |
||||
|
if (result != 0) |
||||
|
{ |
||||
|
|
||||
|
ptw32_threadDestroy (thread); |
||||
|
tp = NULL; |
||||
|
|
||||
|
if (parms != NULL) |
||||
|
{ |
||||
|
free (parms); |
||||
|
} |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
*tid = thread; |
||||
|
} |
||||
|
|
||||
|
#if defined(_UWIN) |
||||
|
if (result == 0) |
||||
|
pthread_count++; |
||||
|
#endif |
||||
|
return (result); |
||||
|
|
||||
|
} /* pthread_create */ |
@ -0,0 +1,92 @@ |
|||||
|
/*
|
||||
|
* dll.c |
||||
|
* |
||||
|
* Description: |
||||
|
* This translation unit implements DLL initialisation. |
||||
|
* |
||||
|
* -------------------------------------------------------------------------- |
||||
|
* |
||||
|
* 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(PTW32_STATIC_LIB) |
||||
|
|
||||
|
#include "pthread.h" |
||||
|
#include "implement.h" |
||||
|
|
||||
|
#if defined(_MSC_VER) |
||||
|
/*
|
||||
|
* lpvReserved yields an unreferenced formal parameter; |
||||
|
* ignore it |
||||
|
*/ |
||||
|
#pragma warning( disable : 4100 ) |
||||
|
#endif |
||||
|
|
||||
|
#if defined(__cplusplus) |
||||
|
/*
|
||||
|
* Dear c++: Please don't mangle this name. -thanks |
||||
|
*/ |
||||
|
extern "C" |
||||
|
#endif /* __cplusplus */ |
||||
|
BOOL WINAPI |
||||
|
DllMain (HINSTANCE hinstDll, DWORD fdwReason, LPVOID lpvReserved) |
||||
|
{ |
||||
|
BOOL result = PTW32_TRUE; |
||||
|
|
||||
|
switch (fdwReason) |
||||
|
{ |
||||
|
|
||||
|
case DLL_PROCESS_ATTACH: |
||||
|
result = pthread_win32_process_attach_np (); |
||||
|
break; |
||||
|
|
||||
|
case DLL_THREAD_ATTACH: |
||||
|
/*
|
||||
|
* A thread is being created |
||||
|
*/ |
||||
|
result = pthread_win32_thread_attach_np (); |
||||
|
break; |
||||
|
|
||||
|
case DLL_THREAD_DETACH: |
||||
|
/*
|
||||
|
* A thread is exiting cleanly |
||||
|
*/ |
||||
|
result = pthread_win32_thread_detach_np (); |
||||
|
break; |
||||
|
|
||||
|
case DLL_PROCESS_DETACH: |
||||
|
(void) pthread_win32_thread_detach_np (); |
||||
|
result = pthread_win32_process_detach_np (); |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
return (result); |
||||
|
|
||||
|
} /* DllMain */ |
||||
|
|
||||
|
#endif /* PTW32_STATIC_LIB */ |
@ -0,0 +1,94 @@ |
|||||
|
/*
|
||||
|
* errno.c |
||||
|
* |
||||
|
* Description: |
||||
|
* This translation unit implements routines associated with spawning a new |
||||
|
* thread. |
||||
|
* |
||||
|
* -------------------------------------------------------------------------- |
||||
|
* |
||||
|
* 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(NEED_ERRNO) |
||||
|
|
||||
|
#include "pthread.h" |
||||
|
#include "implement.h" |
||||
|
|
||||
|
static int reallyBad = ENOMEM; |
||||
|
|
||||
|
/*
|
||||
|
* Re-entrant errno. |
||||
|
* |
||||
|
* Each thread has it's own errno variable in pthread_t. |
||||
|
* |
||||
|
* The benefit of using the pthread_t structure |
||||
|
* instead of another TSD key is TSD keys are limited |
||||
|
* on Win32 to 64 per process. Secondly, to implement |
||||
|
* it properly without using pthread_t you'd need |
||||
|
* to dynamically allocate an int on starting the thread |
||||
|
* and store it manually into TLS and then ensure that you free |
||||
|
* it on thread termination. We get all that for free |
||||
|
* by simply storing the errno on the pthread_t structure. |
||||
|
* |
||||
|
* MSVC and Mingw32 already have their own thread-safe errno. |
||||
|
* |
||||
|
* #if defined( _REENTRANT ) || defined( _MT ) |
||||
|
* #define errno *_errno() |
||||
|
* |
||||
|
* int *_errno( void ); |
||||
|
* #else |
||||
|
* extern int errno; |
||||
|
* #endif |
||||
|
* |
||||
|
*/ |
||||
|
|
||||
|
int * |
||||
|
_errno (void) |
||||
|
{ |
||||
|
pthread_t self; |
||||
|
int *result; |
||||
|
|
||||
|
if ((self = pthread_self ()).p == NULL) |
||||
|
{ |
||||
|
/*
|
||||
|
* Yikes! unable to allocate a thread! |
||||
|
* Throw an exception? return an error? |
||||
|
*/ |
||||
|
result = &reallyBad; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
result = (int *)(&self.p->exitStatus); |
||||
|
} |
||||
|
|
||||
|
return (result); |
||||
|
|
||||
|
} /* _errno */ |
||||
|
|
||||
|
#endif /* (NEED_ERRNO) */ |
@ -0,0 +1,44 @@ |
|||||
|
/*
|
||||
|
* exit.c |
||||
|
* |
||||
|
* Description: |
||||
|
* This translation unit implements routines associated with exiting from |
||||
|
* a thread. |
||||
|
* |
||||
|
* -------------------------------------------------------------------------- |
||||
|
* |
||||
|
* 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 |
||||
|
*/ |
||||
|
|
||||
|
#include "pthread.h" |
||||
|
#include "implement.h" |
||||
|
#if ! defined(_UWIN) && ! defined(WINCE) |
||||
|
# include <process.h> |
||||
|
#endif |
||||
|
|
||||
|
#include "pthread_exit.c" |
@ -0,0 +1,39 @@ |
|||||
|
/*
|
||||
|
* fork.c |
||||
|
* |
||||
|
* Description: |
||||
|
* Implementation of fork() for POSIX threads. |
||||
|
* |
||||
|
* -------------------------------------------------------------------------- |
||||
|
* |
||||
|
* 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 |
||||
|
*/ |
||||
|
|
||||
|
|
||||
|
#include "pthread.h" |
||||
|
#include "implement.h" |
@ -0,0 +1,107 @@ |
|||||
|
/*
|
||||
|
* global.c |
||||
|
* |
||||
|
* Description: |
||||
|
* This translation unit instantiates data associated with the implementation |
||||
|
* as a whole. |
||||
|
* |
||||
|
* -------------------------------------------------------------------------- |
||||
|
* |
||||
|
* 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 |
||||
|
*/ |
||||
|
|
||||
|
#include "pthread.h" |
||||
|
#include "implement.h" |
||||
|
|
||||
|
|
||||
|
int ptw32_processInitialized = PTW32_FALSE; |
||||
|
ptw32_thread_t * ptw32_threadReuseTop = PTW32_THREAD_REUSE_EMPTY; |
||||
|
ptw32_thread_t * ptw32_threadReuseBottom = PTW32_THREAD_REUSE_EMPTY; |
||||
|
pthread_key_t ptw32_selfThreadKey = NULL; |
||||
|
pthread_key_t ptw32_cleanupKey = NULL; |
||||
|
pthread_cond_t ptw32_cond_list_head = NULL; |
||||
|
pthread_cond_t ptw32_cond_list_tail = NULL; |
||||
|
|
||||
|
int ptw32_concurrency = 0; |
||||
|
|
||||
|
/* What features have been auto-detected */ |
||||
|
int ptw32_features = 0; |
||||
|
|
||||
|
/*
|
||||
|
* Global [process wide] thread sequence Number |
||||
|
*/ |
||||
|
unsigned __int64 ptw32_threadSeqNumber = 0; |
||||
|
|
||||
|
/*
|
||||
|
* Function pointer to QueueUserAPCEx if it exists, otherwise |
||||
|
* it will be set at runtime to a substitute routine which cannot unblock |
||||
|
* blocked threads. |
||||
|
*/ |
||||
|
DWORD (*ptw32_register_cancelation) (PAPCFUNC, HANDLE, DWORD) = NULL; |
||||
|
|
||||
|
/*
|
||||
|
* Global lock for managing pthread_t struct reuse. |
||||
|
*/ |
||||
|
ptw32_mcs_lock_t ptw32_thread_reuse_lock = 0; |
||||
|
|
||||
|
/*
|
||||
|
* Global lock for testing internal state of statically declared mutexes. |
||||
|
*/ |
||||
|
ptw32_mcs_lock_t ptw32_mutex_test_init_lock = 0; |
||||
|
|
||||
|
/*
|
||||
|
* Global lock for testing internal state of PTHREAD_COND_INITIALIZER |
||||
|
* created condition variables. |
||||
|
*/ |
||||
|
ptw32_mcs_lock_t ptw32_cond_test_init_lock = 0; |
||||
|
|
||||
|
/*
|
||||
|
* Global lock for testing internal state of PTHREAD_RWLOCK_INITIALIZER |
||||
|
* created read/write locks. |
||||
|
*/ |
||||
|
ptw32_mcs_lock_t ptw32_rwlock_test_init_lock = 0; |
||||
|
|
||||
|
/*
|
||||
|
* Global lock for testing internal state of PTHREAD_SPINLOCK_INITIALIZER |
||||
|
* created spin locks. |
||||
|
*/ |
||||
|
ptw32_mcs_lock_t ptw32_spinlock_test_init_lock = 0; |
||||
|
|
||||
|
/*
|
||||
|
* Global lock for condition variable linked list. The list exists |
||||
|
* to wake up CVs when a WM_TIMECHANGE message arrives. See |
||||
|
* w32_TimeChangeHandler.c. |
||||
|
*/ |
||||
|
ptw32_mcs_lock_t ptw32_cond_list_lock = 0; |
||||
|
|
||||
|
#if defined(_UWIN) |
||||
|
/*
|
||||
|
* Keep a count of the number of threads. |
||||
|
*/ |
||||
|
int pthread_count = 0; |
||||
|
#endif |
@ -0,0 +1,944 @@ |
|||||
|
/*
|
||||
|
* implement.h |
||||
|
* |
||||
|
* Definitions that don't need to be public. |
||||
|
* |
||||
|
* Keeps all the internals out of pthread.h |
||||
|
* |
||||
|
* -------------------------------------------------------------------------- |
||||
|
* |
||||
|
* Pthreads-win32 - POSIX Threads Library for Win32 |
||||
|
* Copyright(C) 1998 John E. Bossom |
||||
|
* Copyright(C) 1999,2005 Pthreads-win32 contributors |
||||
|
* |
||||
|
* Contact Email: Ross.Johnson@homemail.com.au |
||||
|
* |
||||
|
* The current list of contributors is contained |
||||
|
* in the file CONTRIBUTORS included with the source |
||||
|
* code distribution. The list can also be seen at the |
||||
|
* following World Wide Web location: |
||||
|
* http://sources.redhat.com/pthreads-win32/contributors.html
|
||||
|
* |
||||
|
* This library is free software; you can redistribute it and/or |
||||
|
* modify it under the terms of the GNU Lesser General Public |
||||
|
* License as published by the Free Software Foundation; either |
||||
|
* version 2 of the License, or (at your option) any later version. |
||||
|
* |
||||
|
* This library is distributed in the hope that it will be useful, |
||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||||
|
* Lesser General Public License for more details. |
||||
|
* |
||||
|
* You should have received a copy of the GNU Lesser General Public |
||||
|
* License along with this library in the file COPYING.LIB; |
||||
|
* if not, write to the Free Software Foundation, Inc., |
||||
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA |
||||
|
*/ |
||||
|
|
||||
|
#if !defined(_IMPLEMENT_H) |
||||
|
#define _IMPLEMENT_H |
||||
|
|
||||
|
#if !defined(_WIN32_WINNT) |
||||
|
#define _WIN32_WINNT 0x0400 |
||||
|
#endif |
||||
|
|
||||
|
#include <windows.h> |
||||
|
|
||||
|
/*
|
||||
|
* In case windows.h doesn't define it (e.g. WinCE perhaps) |
||||
|
*/ |
||||
|
#if defined(WINCE) |
||||
|
typedef VOID (APIENTRY *PAPCFUNC)(DWORD dwParam); |
||||
|
#endif |
||||
|
|
||||
|
/*
|
||||
|
* note: ETIMEDOUT is correctly defined in winsock.h |
||||
|
*/ |
||||
|
#include <winsock.h> |
||||
|
|
||||
|
/*
|
||||
|
* In case ETIMEDOUT hasn't been defined above somehow. |
||||
|
*/ |
||||
|
#if !defined(ETIMEDOUT) |
||||
|
# define ETIMEDOUT 10060 /* This is the value in winsock.h. */ |
||||
|
#endif |
||||
|
|
||||
|
#if !defined(malloc) |
||||
|
#include <malloc.h> |
||||
|
#endif |
||||
|
|
||||
|
#if defined(__CLEANUP_C) |
||||
|
# include <setjmp.h> |
||||
|
#endif |
||||
|
|
||||
|
#if !defined(INT_MAX) |
||||
|
#include <limits.h> |
||||
|
#endif |
||||
|
|
||||
|
/* use local include files during development */ |
||||
|
#include "semaphore.h" |
||||
|
#include "sched.h" |
||||
|
|
||||
|
#if defined(HAVE_C_INLINE) || defined(__cplusplus) |
||||
|
#define INLINE inline |
||||
|
#else |
||||
|
#define INLINE |
||||
|
#endif |
||||
|
|
||||
|
#if defined(_MSC_VER) && _MSC_VER < 1300 |
||||
|
/*
|
||||
|
* MSVC 6 does not use the "volatile" qualifier |
||||
|
*/ |
||||
|
#define PTW32_INTERLOCKED_VOLATILE |
||||
|
#else |
||||
|
#define PTW32_INTERLOCKED_VOLATILE volatile |
||||
|
#endif |
||||
|
#define PTW32_INTERLOCKED_LONG long |
||||
|
#define PTW32_INTERLOCKED_SIZE size_t |
||||
|
#define PTW32_INTERLOCKED_PVOID PVOID |
||||
|
#define PTW32_INTERLOCKED_LONGPTR PTW32_INTERLOCKED_VOLATILE long* |
||||
|
#define PTW32_INTERLOCKED_SIZEPTR PTW32_INTERLOCKED_VOLATILE size_t* |
||||
|
#define PTW32_INTERLOCKED_PVOID_PTR PTW32_INTERLOCKED_VOLATILE PVOID* |
||||
|
|
||||
|
#if defined(__MINGW64__) || defined(__MINGW32__) |
||||
|
# include <stdint.h> |
||||
|
#elif defined(__BORLANDC__) |
||||
|
# define int64_t ULONGLONG |
||||
|
#else |
||||
|
# define int64_t _int64 |
||||
|
# if defined(_MSC_VER) && _MSC_VER < 1300 |
||||
|
typedef long intptr_t; |
||||
|
# endif |
||||
|
#endif |
||||
|
|
||||
|
typedef enum |
||||
|
{ |
||||
|
/*
|
||||
|
* This enumeration represents the state of the thread; |
||||
|
* The thread is still "alive" if the numeric value of the |
||||
|
* state is greater or equal "PThreadStateRunning". |
||||
|
*/ |
||||
|
PThreadStateInitial = 0, /* Thread not running */ |
||||
|
PThreadStateRunning, /* Thread alive & kicking */ |
||||
|
PThreadStateSuspended, /* Thread alive but suspended */ |
||||
|
PThreadStateCancelPending, /* Thread alive but */ |
||||
|
/* has cancelation pending. */ |
||||
|
PThreadStateCanceling, /* Thread alive but is */ |
||||
|
/* in the process of terminating */ |
||||
|
/* due to a cancellation request */ |
||||
|
PThreadStateExiting, /* Thread alive but exiting */ |
||||
|
/* due to an exception */ |
||||
|
PThreadStateLast, /* All handlers have been run and now */ |
||||
|
/* final cleanup can be done. */ |
||||
|
PThreadStateReuse /* In reuse pool. */ |
||||
|
} |
||||
|
PThreadState; |
||||
|
|
||||
|
typedef struct ptw32_mcs_node_t_ ptw32_mcs_local_node_t; |
||||
|
typedef struct ptw32_mcs_node_t_* ptw32_mcs_lock_t; |
||||
|
typedef struct ptw32_robust_node_t_ ptw32_robust_node_t; |
||||
|
typedef struct ptw32_thread_t_ ptw32_thread_t; |
||||
|
|
||||
|
|
||||
|
struct ptw32_thread_t_ |
||||
|
{ |
||||
|
unsigned __int64 seqNumber; /* Process-unique thread sequence number */ |
||||
|
HANDLE threadH; /* Win32 thread handle - POSIX thread is invalid if threadH == 0 */ |
||||
|
pthread_t ptHandle; /* This thread's permanent pthread_t handle */ |
||||
|
ptw32_thread_t * prevReuse; /* Links threads on reuse stack */ |
||||
|
volatile PThreadState state; |
||||
|
ptw32_mcs_lock_t threadLock; /* Used for serialised access to public thread state */ |
||||
|
ptw32_mcs_lock_t stateLock; /* Used for async-cancel safety */ |
||||
|
HANDLE cancelEvent; |
||||
|
void *exitStatus; |
||||
|
void *parms; |
||||
|
void *keys; |
||||
|
void *nextAssoc; |
||||
|
#if defined(__CLEANUP_C) |
||||
|
jmp_buf start_mark; /* Jump buffer follows void* so should be aligned */ |
||||
|
#endif /* __CLEANUP_C */ |
||||
|
#if defined(HAVE_SIGSET_T) |
||||
|
sigset_t sigmask; |
||||
|
#endif /* HAVE_SIGSET_T */ |
||||
|
ptw32_mcs_lock_t |
||||
|
robustMxListLock; /* robustMxList lock */ |
||||
|
ptw32_robust_node_t* |
||||
|
robustMxList; /* List of currenty held robust mutexes */ |
||||
|
int ptErrno; |
||||
|
int detachState; |
||||
|
int sched_priority; /* As set, not as currently is */ |
||||
|
int cancelState; |
||||
|
int cancelType; |
||||
|
int implicit:1; |
||||
|
DWORD thread; /* Win32 thread ID */ |
||||
|
#if defined(_UWIN) |
||||
|
DWORD dummy[5]; |
||||
|
#endif |
||||
|
size_t align; /* Force alignment if this struct is packed */ |
||||
|
}; |
||||
|
|
||||
|
|
||||
|
/*
|
||||
|
* Special value to mark attribute objects as valid. |
||||
|
*/ |
||||
|
#define PTW32_ATTR_VALID ((unsigned long) 0xC4C0FFEE) |
||||
|
|
||||
|
struct pthread_attr_t_ |
||||
|
{ |
||||
|
unsigned long valid; |
||||
|
void *stackaddr; |
||||
|
size_t stacksize; |
||||
|
int detachstate; |
||||
|
struct sched_param param; |
||||
|
int inheritsched; |
||||
|
int contentionscope; |
||||
|
#if defined(HAVE_SIGSET_T) |
||||
|
sigset_t sigmask; |
||||
|
#endif /* HAVE_SIGSET_T */ |
||||
|
}; |
||||
|
|
||||
|
|
||||
|
/*
|
||||
|
* ==================== |
||||
|
* ==================== |
||||
|
* Semaphores, Mutexes and Condition Variables |
||||
|
* ==================== |
||||
|
* ==================== |
||||
|
*/ |
||||
|
|
||||
|
struct sem_t_ |
||||
|
{ |
||||
|
int value; |
||||
|
pthread_mutex_t lock; |
||||
|
HANDLE sem; |
||||
|
#if defined(NEED_SEM) |
||||
|
int leftToUnblock; |
||||
|
#endif |
||||
|
}; |
||||
|
|
||||
|
#define PTW32_OBJECT_AUTO_INIT ((void *)(size_t) -1) |
||||
|
#define PTW32_OBJECT_INVALID NULL |
||||
|
|
||||
|
struct pthread_mutex_t_ |
||||
|
{ |
||||
|
LONG lock_idx; /* Provides exclusive access to mutex state
|
||||
|
via the Interlocked* mechanism. |
||||
|
0: unlocked/free. |
||||
|
1: locked - no other waiters. |
||||
|
-1: locked - with possible other waiters. |
||||
|
*/ |
||||
|
int recursive_count; /* Number of unlocks a thread needs to perform
|
||||
|
before the lock is released (recursive |
||||
|
mutexes only). */ |
||||
|
int kind; /* Mutex type. */ |
||||
|
pthread_t ownerThread; |
||||
|
HANDLE event; /* Mutex release notification to waiting
|
||||
|
threads. */ |
||||
|
ptw32_robust_node_t* |
||||
|
robustNode; /* Extra state for robust mutexes */ |
||||
|
}; |
||||
|
|
||||
|
enum ptw32_robust_state_t_ |
||||
|
{ |
||||
|
PTW32_ROBUST_CONSISTENT, |
||||
|
PTW32_ROBUST_INCONSISTENT, |
||||
|
PTW32_ROBUST_NOTRECOVERABLE |
||||
|
}; |
||||
|
|
||||
|
typedef enum ptw32_robust_state_t_ ptw32_robust_state_t; |
||||
|
|
||||
|
/*
|
||||
|
* Node used to manage per-thread lists of currently-held robust mutexes. |
||||
|
*/ |
||||
|
struct ptw32_robust_node_t_ |
||||
|
{ |
||||
|
pthread_mutex_t mx; |
||||
|
ptw32_robust_state_t stateInconsistent; |
||||
|
ptw32_robust_node_t* prev; |
||||
|
ptw32_robust_node_t* next; |
||||
|
}; |
||||
|
|
||||
|
struct pthread_mutexattr_t_ |
||||
|
{ |
||||
|
int pshared; |
||||
|
int kind; |
||||
|
int robustness; |
||||
|
}; |
||||
|
|
||||
|
/*
|
||||
|
* Possible values, other than PTW32_OBJECT_INVALID, |
||||
|
* for the "interlock" element in a spinlock. |
||||
|
* |
||||
|
* In this implementation, when a spinlock is initialised, |
||||
|
* the number of cpus available to the process is checked. |
||||
|
* If there is only one cpu then "interlock" is set equal to |
||||
|
* PTW32_SPIN_USE_MUTEX and u.mutex is an initialised mutex. |
||||
|
* If the number of cpus is greater than 1 then "interlock" |
||||
|
* is set equal to PTW32_SPIN_UNLOCKED and the number is |
||||
|
* stored in u.cpus. This arrangement allows the spinlock |
||||
|
* routines to attempt an InterlockedCompareExchange on "interlock" |
||||
|
* immediately and, if that fails, to try the inferior mutex. |
||||
|
* |
||||
|
* "u.cpus" isn't used for anything yet, but could be used at |
||||
|
* some point to optimise spinlock behaviour. |
||||
|
*/ |
||||
|
#define PTW32_SPIN_INVALID (0) |
||||
|
#define PTW32_SPIN_UNLOCKED (1) |
||||
|
#define PTW32_SPIN_LOCKED (2) |
||||
|
#define PTW32_SPIN_USE_MUTEX (3) |
||||
|
|
||||
|
struct pthread_spinlock_t_ |
||||
|
{ |
||||
|
long interlock; /* Locking element for multi-cpus. */ |
||||
|
union |
||||
|
{ |
||||
|
int cpus; /* No. of cpus if multi cpus, or */ |
||||
|
pthread_mutex_t mutex; /* mutex if single cpu. */ |
||||
|
} u; |
||||
|
}; |
||||
|
|
||||
|
/*
|
||||
|
* MCS lock queue node - see ptw32_MCS_lock.c |
||||
|
*/ |
||||
|
struct ptw32_mcs_node_t_ |
||||
|
{ |
||||
|
struct ptw32_mcs_node_t_ **lock; /* ptr to tail of queue */ |
||||
|
struct ptw32_mcs_node_t_ *next; /* ptr to successor in queue */ |
||||
|
HANDLE readyFlag; /* set after lock is released by
|
||||
|
predecessor */ |
||||
|
HANDLE nextFlag; /* set after 'next' ptr is set by
|
||||
|
successor */ |
||||
|
}; |
||||
|
|
||||
|
|
||||
|
struct pthread_barrier_t_ |
||||
|
{ |
||||
|
unsigned int nCurrentBarrierHeight; |
||||
|
unsigned int nInitialBarrierHeight; |
||||
|
int pshared; |
||||
|
sem_t semBarrierBreeched; |
||||
|
ptw32_mcs_lock_t lock; |
||||
|
ptw32_mcs_local_node_t proxynode; |
||||
|
}; |
||||
|
|
||||
|
struct pthread_barrierattr_t_ |
||||
|
{ |
||||
|
int pshared; |
||||
|
}; |
||||
|
|
||||
|
struct pthread_key_t_ |
||||
|
{ |
||||
|
DWORD key; |
||||
|
void (*destructor) (void *); |
||||
|
ptw32_mcs_lock_t keyLock; |
||||
|
void *threads; |
||||
|
}; |
||||
|
|
||||
|
|
||||
|
typedef struct ThreadParms ThreadParms; |
||||
|
|
||||
|
struct ThreadParms |
||||
|
{ |
||||
|
pthread_t tid; |
||||
|
void *(*start) (void *); |
||||
|
void *arg; |
||||
|
}; |
||||
|
|
||||
|
|
||||
|
struct pthread_cond_t_ |
||||
|
{ |
||||
|
long nWaitersBlocked; /* Number of threads blocked */ |
||||
|
long nWaitersGone; /* Number of threads timed out */ |
||||
|
long nWaitersToUnblock; /* Number of threads to unblock */ |
||||
|
sem_t semBlockQueue; /* Queue up threads waiting for the */ |
||||
|
/* condition to become signalled */ |
||||
|
sem_t semBlockLock; /* Semaphore that guards access to */ |
||||
|
/* | waiters blocked count/block queue */ |
||||
|
/* +-> Mandatory Sync.LEVEL-1 */ |
||||
|
pthread_mutex_t mtxUnblockLock; /* Mutex that guards access to */ |
||||
|
/* | waiters (to)unblock(ed) counts */ |
||||
|
/* +-> Optional* Sync.LEVEL-2 */ |
||||
|
pthread_cond_t next; /* Doubly linked list */ |
||||
|
pthread_cond_t prev; |
||||
|
}; |
||||
|
|
||||
|
|
||||
|
struct pthread_condattr_t_ |
||||
|
{ |
||||
|
int pshared; |
||||
|
}; |
||||
|
|
||||
|
#define PTW32_RWLOCK_MAGIC 0xfacade2 |
||||
|
|
||||
|
struct pthread_rwlock_t_ |
||||
|
{ |
||||
|
pthread_mutex_t mtxExclusiveAccess; |
||||
|
pthread_mutex_t mtxSharedAccessCompleted; |
||||
|
pthread_cond_t cndSharedAccessCompleted; |
||||
|
int nSharedAccessCount; |
||||
|
int nExclusiveAccessCount; |
||||
|
int nCompletedSharedAccessCount; |
||||
|
int nMagic; |
||||
|
}; |
||||
|
|
||||
|
struct pthread_rwlockattr_t_ |
||||
|
{ |
||||
|
int pshared; |
||||
|
}; |
||||
|
|
||||
|
typedef struct ThreadKeyAssoc ThreadKeyAssoc; |
||||
|
|
||||
|
struct ThreadKeyAssoc |
||||
|
{ |
||||
|
/*
|
||||
|
* Purpose: |
||||
|
* This structure creates an association between a thread and a key. |
||||
|
* It is used to implement the implicit invocation of a user defined |
||||
|
* destroy routine for thread specific data registered by a user upon |
||||
|
* exiting a thread. |
||||
|
* |
||||
|
* Graphically, the arrangement is as follows, where: |
||||
|
* |
||||
|
* K - Key with destructor |
||||
|
* (head of chain is key->threads) |
||||
|
* T - Thread that has called pthread_setspecific(Kn) |
||||
|
* (head of chain is thread->keys) |
||||
|
* A - Association. Each association is a node at the |
||||
|
* intersection of two doubly-linked lists. |
||||
|
* |
||||
|
* T1 T2 T3 |
||||
|
* | | | |
||||
|
* | | | |
||||
|
* K1 -----+-----A-----A-----> |
||||
|
* | | | |
||||
|
* | | | |
||||
|
* K2 -----A-----A-----+-----> |
||||
|
* | | | |
||||
|
* | | | |
||||
|
* K3 -----A-----+-----A-----> |
||||
|
* | | | |
||||
|
* | | | |
||||
|
* V V V |
||||
|
* |
||||
|
* Access to the association is guarded by two locks: the key's |
||||
|
* general lock (guarding the row) and the thread's general |
||||
|
* lock (guarding the column). This avoids the need for a |
||||
|
* dedicated lock for each association, which not only consumes |
||||
|
* more handles but requires that the lock resources persist |
||||
|
* until both the key is deleted and the thread has called the |
||||
|
* destructor. The two-lock arrangement allows those resources |
||||
|
* to be freed as soon as either thread or key is concluded. |
||||
|
* |
||||
|
* To avoid deadlock, whenever both locks are required both the |
||||
|
* key and thread locks are acquired consistently in the order |
||||
|
* "key lock then thread lock". An exception to this exists |
||||
|
* when a thread calls the destructors, however, this is done |
||||
|
* carefully (but inelegantly) to avoid deadlock. |
||||
|
* |
||||
|
* An association is created when a thread first calls |
||||
|
* pthread_setspecific() on a key that has a specified |
||||
|
* destructor. |
||||
|
* |
||||
|
* An association is destroyed either immediately after the |
||||
|
* thread calls the key destructor function on thread exit, or |
||||
|
* when the key is deleted. |
||||
|
* |
||||
|
* Attributes: |
||||
|
* thread |
||||
|
* reference to the thread that owns the |
||||
|
* association. This is actually the pointer to the |
||||
|
* thread struct itself. Since the association is |
||||
|
* destroyed before the thread exits, this can never |
||||
|
* point to a different logical thread to the one that |
||||
|
* created the assoc, i.e. after thread struct reuse. |
||||
|
* |
||||
|
* key |
||||
|
* reference to the key that owns the association. |
||||
|
* |
||||
|
* nextKey |
||||
|
* The pthread_t->keys attribute is the head of a |
||||
|
* chain of associations that runs through the nextKey |
||||
|
* link. This chain provides the 1 to many relationship |
||||
|
* between a pthread_t and all pthread_key_t on which |
||||
|
* it called pthread_setspecific. |
||||
|
* |
||||
|
* prevKey |
||||
|
* Similarly. |
||||
|
* |
||||
|
* nextThread |
||||
|
* The pthread_key_t->threads attribute is the head of |
||||
|
* a chain of associations that runs through the |
||||
|
* nextThreads link. This chain provides the 1 to many |
||||
|
* relationship between a pthread_key_t and all the |
||||
|
* PThreads that have called pthread_setspecific for |
||||
|
* this pthread_key_t. |
||||
|
* |
||||
|
* prevThread |
||||
|
* Similarly. |
||||
|
* |
||||
|
* Notes: |
||||
|
* 1) As soon as either the key or the thread is no longer |
||||
|
* referencing the association, it can be destroyed. The |
||||
|
* association will be removed from both chains. |
||||
|
* |
||||
|
* 2) Under WIN32, an association is only created by |
||||
|
* pthread_setspecific if the user provided a |
||||
|
* destroyRoutine when they created the key. |
||||
|
* |
||||
|
* |
||||
|
*/ |
||||
|
ptw32_thread_t * thread; |
||||
|
pthread_key_t key; |
||||
|
ThreadKeyAssoc *nextKey; |
||||
|
ThreadKeyAssoc *nextThread; |
||||
|
ThreadKeyAssoc *prevKey; |
||||
|
ThreadKeyAssoc *prevThread; |
||||
|
}; |
||||
|
|
||||
|
|
||||
|
#if defined(__CLEANUP_SEH) |
||||
|
/*
|
||||
|
* -------------------------------------------------------------- |
||||
|
* MAKE_SOFTWARE_EXCEPTION |
||||
|
* This macro constructs a software exception code following |
||||
|
* the same format as the standard Win32 error codes as defined |
||||
|
* in WINERROR.H |
||||
|
* Values are 32 bit values laid out as follows: |
||||
|
* |
||||
|
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 |
||||
|
* +---+-+-+-----------------------+-------------------------------+ |
||||
|
* |Sev|C|R| Facility | Code | |
||||
|
* +---+-+-+-----------------------+-------------------------------+ |
||||
|
* |
||||
|
* Severity Values: |
||||
|
*/ |
||||
|
#define SE_SUCCESS 0x00 |
||||
|
#define SE_INFORMATION 0x01 |
||||
|
#define SE_WARNING 0x02 |
||||
|
#define SE_ERROR 0x03 |
||||
|
|
||||
|
#define MAKE_SOFTWARE_EXCEPTION( _severity, _facility, _exception ) \ |
||||
|
( (DWORD) ( ( (_severity) << 30 ) | /* Severity code */ \ |
||||
|
( 1 << 29 ) | /* MS=0, User=1 */ \ |
||||
|
( 0 << 28 ) | /* Reserved */ \ |
||||
|
( (_facility) << 16 ) | /* Facility Code */ \ |
||||
|
( (_exception) << 0 ) /* Exception Code */ \ |
||||
|
) ) |
||||
|
|
||||
|
/*
|
||||
|
* We choose one specific Facility/Error code combination to |
||||
|
* identify our software exceptions vs. WIN32 exceptions. |
||||
|
* We store our actual component and error code within |
||||
|
* the optional information array. |
||||
|
*/ |
||||
|
#define EXCEPTION_PTW32_SERVICES \ |
||||
|
MAKE_SOFTWARE_EXCEPTION( SE_ERROR, \ |
||||
|
PTW32_SERVICES_FACILITY, \ |
||||
|
PTW32_SERVICES_ERROR ) |
||||
|
|
||||
|
#define PTW32_SERVICES_FACILITY 0xBAD |
||||
|
#define PTW32_SERVICES_ERROR 0xDEED |
||||
|
|
||||
|
#endif /* __CLEANUP_SEH */ |
||||
|
|
||||
|
/*
|
||||
|
* Services available through EXCEPTION_PTW32_SERVICES |
||||
|
* and also used [as parameters to ptw32_throw()] as |
||||
|
* generic exception selectors. |
||||
|
*/ |
||||
|
|
||||
|
#define PTW32_EPS_EXIT (1) |
||||
|
#define PTW32_EPS_CANCEL (2) |
||||
|
|
||||
|
|
||||
|
/* Useful macros */ |
||||
|
#define PTW32_MAX(a,b) ((a)<(b)?(b):(a)) |
||||
|
#define PTW32_MIN(a,b) ((a)>(b)?(b):(a)) |
||||
|
|
||||
|
|
||||
|
/* Declared in pthread_cancel.c */ |
||||
|
extern DWORD (*ptw32_register_cancelation) (PAPCFUNC, HANDLE, DWORD); |
||||
|
|
||||
|
/* Thread Reuse stack bottom marker. Must not be NULL or any valid pointer to memory. */ |
||||
|
#define PTW32_THREAD_REUSE_EMPTY ((ptw32_thread_t *)(size_t) 1) |
||||
|
|
||||
|
extern int ptw32_processInitialized; |
||||
|
extern ptw32_thread_t * ptw32_threadReuseTop; |
||||
|
extern ptw32_thread_t * ptw32_threadReuseBottom; |
||||
|
extern pthread_key_t ptw32_selfThreadKey; |
||||
|
extern pthread_key_t ptw32_cleanupKey; |
||||
|
extern pthread_cond_t ptw32_cond_list_head; |
||||
|
extern pthread_cond_t ptw32_cond_list_tail; |
||||
|
|
||||
|
extern int ptw32_mutex_default_kind; |
||||
|
|
||||
|
extern unsigned __int64 ptw32_threadSeqNumber; |
||||
|
|
||||
|
extern int ptw32_concurrency; |
||||
|
|
||||
|
extern int ptw32_features; |
||||
|
|
||||
|
extern ptw32_mcs_lock_t ptw32_thread_reuse_lock; |
||||
|
extern ptw32_mcs_lock_t ptw32_mutex_test_init_lock; |
||||
|
extern ptw32_mcs_lock_t ptw32_cond_list_lock; |
||||
|
extern ptw32_mcs_lock_t ptw32_cond_test_init_lock; |
||||
|
extern ptw32_mcs_lock_t ptw32_rwlock_test_init_lock; |
||||
|
extern ptw32_mcs_lock_t ptw32_spinlock_test_init_lock; |
||||
|
|
||||
|
#if defined(_UWIN) |
||||
|
extern int pthread_count; |
||||
|
#endif |
||||
|
|
||||
|
#if defined(__cplusplus) |
||||
|
extern "C" |
||||
|
{ |
||||
|
#endif /* __cplusplus */ |
||||
|
|
||||
|
/*
|
||||
|
* ===================== |
||||
|
* ===================== |
||||
|
* Forward Declarations |
||||
|
* ===================== |
||||
|
* ===================== |
||||
|
*/ |
||||
|
|
||||
|
int ptw32_is_attr (const pthread_attr_t * attr); |
||||
|
|
||||
|
int ptw32_cond_check_need_init (pthread_cond_t * cond); |
||||
|
int ptw32_mutex_check_need_init (pthread_mutex_t * mutex); |
||||
|
int ptw32_rwlock_check_need_init (pthread_rwlock_t * rwlock); |
||||
|
int ptw32_spinlock_check_need_init (pthread_spinlock_t * lock); |
||||
|
|
||||
|
int ptw32_robust_mutex_inherit(pthread_mutex_t * mutex); |
||||
|
void ptw32_robust_mutex_add(pthread_mutex_t* mutex, pthread_t self); |
||||
|
void ptw32_robust_mutex_remove(pthread_mutex_t* mutex, ptw32_thread_t* otp); |
||||
|
|
||||
|
DWORD |
||||
|
ptw32_RegisterCancelation (PAPCFUNC callback, |
||||
|
HANDLE threadH, DWORD callback_arg); |
||||
|
|
||||
|
int ptw32_processInitialize (void); |
||||
|
|
||||
|
void ptw32_processTerminate (void); |
||||
|
|
||||
|
void ptw32_threadDestroy (pthread_t tid); |
||||
|
|
||||
|
void ptw32_pop_cleanup_all (int execute); |
||||
|
|
||||
|
pthread_t ptw32_new (void); |
||||
|
|
||||
|
pthread_t ptw32_threadReusePop (void); |
||||
|
|
||||
|
void ptw32_threadReusePush (pthread_t thread); |
||||
|
|
||||
|
int ptw32_getprocessors (int *count); |
||||
|
|
||||
|
int ptw32_setthreadpriority (pthread_t thread, int policy, int priority); |
||||
|
|
||||
|
void ptw32_rwlock_cancelwrwait (void *arg); |
||||
|
|
||||
|
#if ! (defined (__MINGW64__) || defined(__MINGW32__)) || (defined(__MSVCRT__) && ! defined(__DMC__)) |
||||
|
unsigned __stdcall |
||||
|
#else |
||||
|
void |
||||
|
#endif |
||||
|
ptw32_threadStart (void *vthreadParms); |
||||
|
|
||||
|
void ptw32_callUserDestroyRoutines (pthread_t thread); |
||||
|
|
||||
|
int ptw32_tkAssocCreate (ptw32_thread_t * thread, pthread_key_t key); |
||||
|
|
||||
|
void ptw32_tkAssocDestroy (ThreadKeyAssoc * assoc); |
||||
|
|
||||
|
int ptw32_semwait (sem_t * sem); |
||||
|
|
||||
|
DWORD ptw32_relmillisecs (const struct timespec * abstime); |
||||
|
|
||||
|
void ptw32_mcs_lock_acquire (ptw32_mcs_lock_t * lock, ptw32_mcs_local_node_t * node); |
||||
|
|
||||
|
int ptw32_mcs_lock_try_acquire (ptw32_mcs_lock_t * lock, ptw32_mcs_local_node_t * node); |
||||
|
|
||||
|
void ptw32_mcs_lock_release (ptw32_mcs_local_node_t * node); |
||||
|
|
||||
|
void ptw32_mcs_node_transfer (ptw32_mcs_local_node_t * new_node, ptw32_mcs_local_node_t * old_node); |
||||
|
|
||||
|
#if defined(NEED_FTIME) |
||||
|
void ptw32_timespec_to_filetime (const struct timespec *ts, FILETIME * ft); |
||||
|
void ptw32_filetime_to_timespec (const FILETIME * ft, struct timespec *ts); |
||||
|
#endif |
||||
|
|
||||
|
/* Declared in misc.c */ |
||||
|
#if defined(NEED_CALLOC) |
||||
|
#define calloc(n, s) ptw32_calloc(n, s) |
||||
|
void *ptw32_calloc (size_t n, size_t s); |
||||
|
#endif |
||||
|
|
||||
|
/* Declared in private.c */ |
||||
|
#if defined(_MSC_VER) |
||||
|
/*
|
||||
|
* Ignore the warning: |
||||
|
* "C++ exception specification ignored except to indicate that |
||||
|
* the function is not __declspec(nothrow)." |
||||
|
*/ |
||||
|
#pragma warning(disable:4290) |
||||
|
#endif |
||||
|
void ptw32_throw (DWORD exception) |
||||
|
#if defined(__CLEANUP_CXX) |
||||
|
throw(ptw32_exception_cancel,ptw32_exception_exit) |
||||
|
#endif |
||||
|
; |
||||
|
|
||||
|
#if defined(__cplusplus) |
||||
|
} |
||||
|
#endif /* __cplusplus */ |
||||
|
|
||||
|
|
||||
|
#if defined(_UWIN_) |
||||
|
# if defined(_MT) |
||||
|
# if defined(__cplusplus) |
||||
|
extern "C" |
||||
|
{ |
||||
|
# endif |
||||
|
_CRTIMP unsigned long __cdecl _beginthread (void (__cdecl *) (void *), |
||||
|
unsigned, void *); |
||||
|
_CRTIMP void __cdecl _endthread (void); |
||||
|
_CRTIMP unsigned long __cdecl _beginthreadex (void *, unsigned, |
||||
|
unsigned (__stdcall *) (void *), |
||||
|
void *, unsigned, unsigned *); |
||||
|
_CRTIMP void __cdecl _endthreadex (unsigned); |
||||
|
# if defined(__cplusplus) |
||||
|
} |
||||
|
# endif |
||||
|
# endif |
||||
|
#else |
||||
|
# include <process.h> |
||||
|
# endif |
||||
|
|
||||
|
|
||||
|
/*
|
||||
|
* Use intrinsic versions wherever possible. VC will do this |
||||
|
* automatically where possible and GCC define these if available: |
||||
|
* __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 |
||||
|
* __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 |
||||
|
* __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 |
||||
|
* __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 |
||||
|
* __GCC_HAVE_SYNC_COMPARE_AND_SWAP_16 |
||||
|
* |
||||
|
* The full set of Interlocked intrinsics in GCC are (check versions): |
||||
|
* type __sync_fetch_and_add (type *ptr, type value, ...) |
||||
|
* type __sync_fetch_and_sub (type *ptr, type value, ...) |
||||
|
* type __sync_fetch_and_or (type *ptr, type value, ...) |
||||
|
* type __sync_fetch_and_and (type *ptr, type value, ...) |
||||
|
* type __sync_fetch_and_xor (type *ptr, type value, ...) |
||||
|
* type __sync_fetch_and_nand (type *ptr, type value, ...) |
||||
|
* type __sync_add_and_fetch (type *ptr, type value, ...) |
||||
|
* type __sync_sub_and_fetch (type *ptr, type value, ...) |
||||
|
* type __sync_or_and_fetch (type *ptr, type value, ...) |
||||
|
* type __sync_and_and_fetch (type *ptr, type value, ...) |
||||
|
* type __sync_xor_and_fetch (type *ptr, type value, ...) |
||||
|
* type __sync_nand_and_fetch (type *ptr, type value, ...) |
||||
|
* bool __sync_bool_compare_and_swap (type *ptr, type oldval type newval, ...) |
||||
|
* type __sync_val_compare_and_swap (type *ptr, type oldval type newval, ...) |
||||
|
* __sync_synchronize (...) // Full memory barrier
|
||||
|
* type __sync_lock_test_and_set (type *ptr, type value, ...) // Acquire barrier
|
||||
|
* void __sync_lock_release (type *ptr, ...) // Release barrier
|
||||
|
* |
||||
|
* These are all overloaded and take 1,2,4,8 byte scalar or pointer types. |
||||
|
* |
||||
|
* The above aren't available in Mingw32 as of gcc 4.5.2 so define our own. |
||||
|
*/ |
||||
|
#if defined(__GNUC__) |
||||
|
# if defined(_WIN64) |
||||
|
# define PTW32_INTERLOCKED_COMPARE_EXCHANGE_64(location, value, comparand) \ |
||||
|
({ \ |
||||
|
__typeof (value) _result; \ |
||||
|
__asm__ __volatile__ \ |
||||
|
( \ |
||||
|
"lock\n\t" \ |
||||
|
"cmpxchgq %2,(%1)" \ |
||||
|
:"=a" (_result) \ |
||||
|
:"r" (location), "r" (value), "a" (comparand) \ |
||||
|
:"memory", "cc"); \ |
||||
|
_result; \ |
||||
|
}) |
||||
|
# define PTW32_INTERLOCKED_EXCHANGE_64(location, value) \ |
||||
|
({ \ |
||||
|
__typeof (value) _result; \ |
||||
|
__asm__ __volatile__ \ |
||||
|
( \ |
||||
|
"xchgq %0,(%1)" \ |
||||
|
:"=r" (_result) \ |
||||
|
:"r" (location), "0" (value) \ |
||||
|
:"memory", "cc"); \ |
||||
|
_result; \ |
||||
|
}) |
||||
|
# define PTW32_INTERLOCKED_EXCHANGE_ADD_64(location, value) \ |
||||
|
({ \ |
||||
|
__typeof (value) _result; \ |
||||
|
__asm__ __volatile__ \ |
||||
|
( \ |
||||
|
"lock\n\t" \ |
||||
|
"xaddq %0,(%1)" \ |
||||
|
:"=r" (_result) \ |
||||
|
:"r" (location), "0" (value) \ |
||||
|
:"memory", "cc"); \ |
||||
|
_result; \ |
||||
|
}) |
||||
|
# define PTW32_INTERLOCKED_INCREMENT_64(location) \ |
||||
|
({ \ |
||||
|
PTW32_INTERLOCKED_LONG _temp = 1; \ |
||||
|
__asm__ __volatile__ \ |
||||
|
( \ |
||||
|
"lock\n\t" \ |
||||
|
"xaddq %0,(%1)" \ |
||||
|
:"+r" (_temp) \ |
||||
|
:"r" (location) \ |
||||
|
:"memory", "cc"); \ |
||||
|
++_temp; \ |
||||
|
}) |
||||
|
# define PTW32_INTERLOCKED_DECREMENT_64(location) \ |
||||
|
({ \ |
||||
|
PTW32_INTERLOCKED_LONG _temp = -1; \ |
||||
|
__asm__ __volatile__ \ |
||||
|
( \ |
||||
|
"lock\n\t" \ |
||||
|
"xaddq %2,(%1)" \ |
||||
|
:"+r" (_temp) \ |
||||
|
:"r" (location) \ |
||||
|
:"memory", "cc"); \ |
||||
|
--_temp; \ |
||||
|
}) |
||||
|
#endif |
||||
|
# define PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG(location, value, comparand) \ |
||||
|
({ \ |
||||
|
__typeof (value) _result; \ |
||||
|
__asm__ __volatile__ \ |
||||
|
( \ |
||||
|
"lock\n\t" \ |
||||
|
"cmpxchgl %2,(%1)" \ |
||||
|
:"=a" (_result) \ |
||||
|
:"r" (location), "r" (value), "a" (comparand) \ |
||||
|
:"memory", "cc"); \ |
||||
|
_result; \ |
||||
|
}) |
||||
|
# define PTW32_INTERLOCKED_EXCHANGE_LONG(location, value) \ |
||||
|
({ \ |
||||
|
__typeof (value) _result; \ |
||||
|
__asm__ __volatile__ \ |
||||
|
( \ |
||||
|
"xchgl %0,(%1)" \ |
||||
|
:"=r" (_result) \ |
||||
|
:"r" (location), "0" (value) \ |
||||
|
:"memory", "cc"); \ |
||||
|
_result; \ |
||||
|
}) |
||||
|
# define PTW32_INTERLOCKED_EXCHANGE_ADD_LONG(location, value) \ |
||||
|
({ \ |
||||
|
__typeof (value) _result; \ |
||||
|
__asm__ __volatile__ \ |
||||
|
( \ |
||||
|
"lock\n\t" \ |
||||
|
"xaddl %0,(%1)" \ |
||||
|
:"=r" (_result) \ |
||||
|
:"r" (location), "0" (value) \ |
||||
|
:"memory", "cc"); \ |
||||
|
_result; \ |
||||
|
}) |
||||
|
# define PTW32_INTERLOCKED_INCREMENT_LONG(location) \ |
||||
|
({ \ |
||||
|
PTW32_INTERLOCKED_LONG _temp = 1; \ |
||||
|
__asm__ __volatile__ \ |
||||
|
( \ |
||||
|
"lock\n\t" \ |
||||
|
"xaddl %0,(%1)" \ |
||||
|
:"+r" (_temp) \ |
||||
|
:"r" (location) \ |
||||
|
:"memory", "cc"); \ |
||||
|
++_temp; \ |
||||
|
}) |
||||
|
# define PTW32_INTERLOCKED_DECREMENT_LONG(location) \ |
||||
|
({ \ |
||||
|
PTW32_INTERLOCKED_LONG _temp = -1; \ |
||||
|
__asm__ __volatile__ \ |
||||
|
( \ |
||||
|
"lock\n\t" \ |
||||
|
"xaddl %0,(%1)" \ |
||||
|
:"+r" (_temp) \ |
||||
|
:"r" (location) \ |
||||
|
:"memory", "cc"); \ |
||||
|
--_temp; \ |
||||
|
}) |
||||
|
# define PTW32_INTERLOCKED_COMPARE_EXCHANGE_PTR(location, value, comparand) \ |
||||
|
PTW32_INTERLOCKED_COMPARE_EXCHANGE_SIZE((PTW32_INTERLOCKED_SIZEPTR)location, \ |
||||
|
(PTW32_INTERLOCKED_SIZE)value, \ |
||||
|
(PTW32_INTERLOCKED_SIZE)comparand) |
||||
|
# define PTW32_INTERLOCKED_EXCHANGE_PTR(location, value) \ |
||||
|
PTW32_INTERLOCKED_EXCHANGE_SIZE((PTW32_INTERLOCKED_SIZEPTR)location, \ |
||||
|
(PTW32_INTERLOCKED_SIZE)value) |
||||
|
#else |
||||
|
# if defined(_WIN64) |
||||
|
# define PTW32_INTERLOCKED_COMPARE_EXCHANGE_64 InterlockedCompareExchange64 |
||||
|
# define PTW32_INTERLOCKED_EXCHANGE_64 InterlockedExchange64 |
||||
|
# define PTW32_INTERLOCKED_EXCHANGE_ADD_64 InterlockedExchangeAdd64 |
||||
|
# define PTW32_INTERLOCKED_INCREMENT_64 InterlockedIncrement64 |
||||
|
# define PTW32_INTERLOCKED_DECREMENT_64 InterlockedDecrement64 |
||||
|
# endif |
||||
|
# if defined(_MSC_VER) && _MSC_VER < 1300 && !defined(_WIN64) /* MSVC 6 */ |
||||
|
# define PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG(location, value, comparand) \ |
||||
|
((LONG)InterlockedCompareExchange((PVOID *)(location), (PVOID)(value), (PVOID)(comparand))) |
||||
|
# else |
||||
|
# define PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG InterlockedCompareExchange |
||||
|
# endif |
||||
|
# define PTW32_INTERLOCKED_EXCHANGE_LONG InterlockedExchange |
||||
|
# define PTW32_INTERLOCKED_EXCHANGE_ADD_LONG InterlockedExchangeAdd |
||||
|
# define PTW32_INTERLOCKED_INCREMENT_LONG InterlockedIncrement |
||||
|
# define PTW32_INTERLOCKED_DECREMENT_LONG InterlockedDecrement |
||||
|
# if defined(_MSC_VER) && _MSC_VER < 1300 && !defined(_WIN64) /* MSVC 6 */ |
||||
|
# define PTW32_INTERLOCKED_COMPARE_EXCHANGE_PTR InterlockedCompareExchange |
||||
|
# define PTW32_INTERLOCKED_EXCHANGE_PTR(location, value) \ |
||||
|
((PVOID)InterlockedExchange((LPLONG)(location), (LONG)(value))) |
||||
|
# else |
||||
|
# define PTW32_INTERLOCKED_COMPARE_EXCHANGE_PTR InterlockedCompareExchangePointer |
||||
|
# define PTW32_INTERLOCKED_EXCHANGE_PTR InterlockedExchangePointer |
||||
|
# endif |
||||
|
#endif |
||||
|
#if defined(_WIN64) |
||||
|
# define PTW32_INTERLOCKED_COMPARE_EXCHANGE_SIZE PTW32_INTERLOCKED_COMPARE_EXCHANGE_64 |
||||
|
# define PTW32_INTERLOCKED_EXCHANGE_SIZE PTW32_INTERLOCKED_EXCHANGE_64 |
||||
|
# define PTW32_INTERLOCKED_EXCHANGE_ADD_SIZE PTW32_INTERLOCKED_EXCHANGE_ADD_64 |
||||
|
# define PTW32_INTERLOCKED_INCREMENT_SIZE PTW32_INTERLOCKED_INCREMENT_64 |
||||
|
# define PTW32_INTERLOCKED_DECREMENT_SIZE PTW32_INTERLOCKED_DECREMENT_64 |
||||
|
#else |
||||
|
# define PTW32_INTERLOCKED_COMPARE_EXCHANGE_SIZE PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG |
||||
|
# define PTW32_INTERLOCKED_EXCHANGE_SIZE PTW32_INTERLOCKED_EXCHANGE_LONG |
||||
|
# define PTW32_INTERLOCKED_EXCHANGE_ADD_SIZE PTW32_INTERLOCKED_EXCHANGE_ADD_LONG |
||||
|
# define PTW32_INTERLOCKED_INCREMENT_SIZE PTW32_INTERLOCKED_INCREMENT_LONG |
||||
|
# define PTW32_INTERLOCKED_DECREMENT_SIZE PTW32_INTERLOCKED_DECREMENT_LONG |
||||
|
#endif |
||||
|
|
||||
|
#if defined(NEED_CREATETHREAD) |
||||
|
|
||||
|
/*
|
||||
|
* Macro uses args so we can cast start_proc to LPTHREAD_START_ROUTINE |
||||
|
* in order to avoid warnings because of return type |
||||
|
*/ |
||||
|
|
||||
|
#define _beginthreadex(security, \ |
||||
|
stack_size, \ |
||||
|
start_proc, \ |
||||
|
arg, \ |
||||
|
flags, \ |
||||
|
pid) \ |
||||
|
CreateThread(security, \ |
||||
|
stack_size, \ |
||||
|
(LPTHREAD_START_ROUTINE) start_proc, \ |
||||
|
arg, \ |
||||
|
flags, \ |
||||
|
pid) |
||||
|
|
||||
|
#define _endthreadex ExitThread |
||||
|
|
||||
|
#endif /* NEED_CREATETHREAD */ |
||||
|
|
||||
|
|
||||
|
#endif /* _IMPLEMENT_H */ |
@ -0,0 +1,50 @@ |
|||||
|
/*
|
||||
|
* misc.c |
||||
|
* |
||||
|
* Description: |
||||
|
* This translation unit implements miscellaneous thread functions. |
||||
|
* |
||||
|
* -------------------------------------------------------------------------- |
||||
|
* |
||||
|
* 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 |
||||
|
*/ |
||||
|
|
||||
|
#include "pthread.h" |
||||
|
#include "implement.h" |
||||
|
|
||||
|
|
||||
|
#include "pthread_kill.c" |
||||
|
#include "pthread_once.c" |
||||
|
#include "pthread_self.c" |
||||
|
#include "pthread_equal.c" |
||||
|
#include "pthread_setconcurrency.c" |
||||
|
#include "pthread_getconcurrency.c" |
||||
|
#include "ptw32_new.c" |
||||
|
#include "ptw32_calloc.c" |
||||
|
#include "ptw32_reuse.c" |
||||
|
#include "w32_CancelableWait.c" |
@ -0,0 +1,62 @@ |
|||||
|
/*
|
||||
|
* mutex.c |
||||
|
* |
||||
|
* Description: |
||||
|
* This translation unit implements mutual exclusion (mutex) primitives. |
||||
|
* |
||||
|
* -------------------------------------------------------------------------- |
||||
|
* |
||||
|
* 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(_UWIN) && ! defined(WINCE) |
||||
|
# include <process.h> |
||||
|
#endif |
||||
|
#if !defined(NEED_FTIME) |
||||
|
#include <sys/timeb.h> |
||||
|
#endif |
||||
|
#include "pthread.h" |
||||
|
#include "implement.h" |
||||
|
|
||||
|
|
||||
|
#include "ptw32_mutex_check_need_init.c" |
||||
|
#include "pthread_mutex_init.c" |
||||
|
#include "pthread_mutex_destroy.c" |
||||
|
#include "pthread_mutexattr_init.c" |
||||
|
#include "pthread_mutexattr_destroy.c" |
||||
|
#include "pthread_mutexattr_getpshared.c" |
||||
|
#include "pthread_mutexattr_setpshared.c" |
||||
|
#include "pthread_mutexattr_settype.c" |
||||
|
#include "pthread_mutexattr_gettype.c" |
||||
|
#include "pthread_mutexattr_setrobust.c" |
||||
|
#include "pthread_mutexattr_getrobust.c" |
||||
|
#include "pthread_mutex_lock.c" |
||||
|
#include "pthread_mutex_timedlock.c" |
||||
|
#include "pthread_mutex_unlock.c" |
||||
|
#include "pthread_mutex_trylock.c" |
||||
|
#include "pthread_mutex_consistent.c" |
@ -0,0 +1,145 @@ |
|||||
|
/***
|
||||
|
* errno.h - system wide error numbers (set by system calls) |
||||
|
* |
||||
|
* Copyright (c) 1985-1997, Microsoft Corporation. All rights reserved. |
||||
|
* |
||||
|
* Purpose: |
||||
|
* This file defines the system-wide error numbers (set by |
||||
|
* system calls). Conforms to the XENIX standard. Extended |
||||
|
* for compatibility with Uniforum standard. |
||||
|
* [System V] |
||||
|
* |
||||
|
* [Public] |
||||
|
* |
||||
|
****/ |
||||
|
|
||||
|
#if _MSC_VER > 1000 |
||||
|
#pragma once |
||||
|
#endif |
||||
|
|
||||
|
#if !defined(_INC_ERRNO) |
||||
|
#define _INC_ERRNO |
||||
|
|
||||
|
#if !defined(_WIN32) |
||||
|
#error ERROR: Only Win32 targets supported! |
||||
|
#endif |
||||
|
|
||||
|
#include <winsock.h> |
||||
|
|
||||
|
#if defined(__cplusplus) |
||||
|
extern "C" { |
||||
|
#endif |
||||
|
|
||||
|
|
||||
|
|
||||
|
/* Define _CRTIMP */ |
||||
|
|
||||
|
#ifndef _CRTIMP |
||||
|
#if defined(_DLL) |
||||
|
#define _CRTIMP __declspec(dllimport) |
||||
|
#else /* ndef _DLL */ |
||||
|
#define _CRTIMP |
||||
|
#endif /* _DLL */ |
||||
|
#endif /* _CRTIMP */ |
||||
|
|
||||
|
|
||||
|
/* Define __cdecl for non-Microsoft compilers */ |
||||
|
|
||||
|
#if ( !defined(_MSC_VER) && !defined(__cdecl) ) |
||||
|
#define __cdecl |
||||
|
#endif |
||||
|
|
||||
|
/* Define _CRTAPI1 (for compatibility with the NT SDK) */ |
||||
|
|
||||
|
#if !defined(_CRTAPI1) |
||||
|
#if _MSC_VER >= 800 && _M_IX86 >= 300 |
||||
|
#define _CRTAPI1 __cdecl |
||||
|
#else |
||||
|
#define _CRTAPI1 |
||||
|
#endif |
||||
|
#endif |
||||
|
|
||||
|
#if !defined(PTW32_STATIC_LIB) |
||||
|
# if defined(PTW32_BUILD) |
||||
|
# define PTW32_DLLPORT __declspec (dllexport) |
||||
|
# else |
||||
|
# define PTW32_DLLPORT __declspec (dllimport) |
||||
|
# endif |
||||
|
#else |
||||
|
# define PTW32_DLLPORT |
||||
|
#endif |
||||
|
|
||||
|
/* declare reference to errno */ |
||||
|
|
||||
|
#if (defined(_MT) || defined(_MD) || defined(_DLL)) && !defined(_MAC) |
||||
|
PTW32_DLLPORT int * __cdecl _errno(void); |
||||
|
#define errno (*_errno()) |
||||
|
#else /* ndef _MT && ndef _MD && ndef _DLL */ |
||||
|
_CRTIMP extern int errno; |
||||
|
#endif /* _MT || _MD || _DLL */ |
||||
|
|
||||
|
/* Error Codes */ |
||||
|
|
||||
|
#define EPERM 1 |
||||
|
#define ENOENT 2 |
||||
|
#define ESRCH 3 |
||||
|
#define EINTR 4 |
||||
|
#define EIO 5 |
||||
|
#define ENXIO 6 |
||||
|
#define E2BIG 7 |
||||
|
#define ENOEXEC 8 |
||||
|
#define EBADF 9 |
||||
|
#define ECHILD 10 |
||||
|
#define EAGAIN 11 |
||||
|
#define ENOMEM 12 |
||||
|
#define EACCES 13 |
||||
|
#define EFAULT 14 |
||||
|
#define EBUSY 16 |
||||
|
#define EEXIST 17 |
||||
|
#define EXDEV 18 |
||||
|
#define ENODEV 19 |
||||
|
#define ENOTDIR 20 |
||||
|
#define EISDIR 21 |
||||
|
#define EINVAL 22 |
||||
|
#define ENFILE 23 |
||||
|
#define EMFILE 24 |
||||
|
#define ENOTTY 25 |
||||
|
#define EFBIG 27 |
||||
|
#define ENOSPC 28 |
||||
|
#define ESPIPE 29 |
||||
|
#define EROFS 30 |
||||
|
#define EMLINK 31 |
||||
|
#define EPIPE 32 |
||||
|
#define EDOM 33 |
||||
|
#define ERANGE 34 |
||||
|
#define EDEADLK 36 |
||||
|
|
||||
|
/* defined differently in winsock.h on WinCE */ |
||||
|
#if !defined(ENAMETOOLONG) |
||||
|
#define ENAMETOOLONG 38 |
||||
|
#endif |
||||
|
|
||||
|
#define ENOLCK 39 |
||||
|
#define ENOSYS 40 |
||||
|
|
||||
|
/* defined differently in winsock.h on WinCE */ |
||||
|
#if !defined(ENOTEMPTY) |
||||
|
#define ENOTEMPTY 41 |
||||
|
#endif |
||||
|
|
||||
|
#define EILSEQ 42 |
||||
|
|
||||
|
/* POSIX 2008 - robust mutexes */ |
||||
|
#define EOWNERDEAD 43 |
||||
|
#define ENOTRECOVERABLE 44 |
||||
|
|
||||
|
/*
|
||||
|
* Support EDEADLOCK for compatibiity with older MS-C versions. |
||||
|
*/ |
||||
|
#define EDEADLOCK EDEADLK |
||||
|
|
||||
|
#if defined(__cplusplus) |
||||
|
} |
||||
|
#endif |
||||
|
|
||||
|
#endif /* _INC_ERRNO */ |
@ -0,0 +1,47 @@ |
|||||
|
/*
|
||||
|
* nonportable.c |
||||
|
* |
||||
|
* Description: |
||||
|
* This translation unit implements non-portable thread functions. |
||||
|
* |
||||
|
* -------------------------------------------------------------------------- |
||||
|
* |
||||
|
* 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 |
||||
|
*/ |
||||
|
|
||||
|
#include "pthread.h" |
||||
|
#include "implement.h" |
||||
|
|
||||
|
#include "pthread_mutexattr_setkind_np.c" |
||||
|
#include "pthread_mutexattr_getkind_np.c" |
||||
|
#include "pthread_getw32threadhandle_np.c" |
||||
|
#include "pthread_getunique_np.c" |
||||
|
#include "pthread_delay_np.c" |
||||
|
#include "pthread_num_processors_np.c" |
||||
|
#include "pthread_win32_attach_detach_np.c" |
||||
|
#include "pthread_timechange_handler_np.c" |
@ -0,0 +1,54 @@ |
|||||
|
/*
|
||||
|
* private.c |
||||
|
* |
||||
|
* Description: |
||||
|
* This translation unit implements routines which are private to |
||||
|
* the implementation and may be used throughout it. |
||||
|
* |
||||
|
* -------------------------------------------------------------------------- |
||||
|
* |
||||
|
* 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 |
||||
|
*/ |
||||
|
|
||||
|
#include "pthread.h" |
||||
|
#include "implement.h" |
||||
|
|
||||
|
#include "ptw32_MCS_lock.c" |
||||
|
#include "ptw32_is_attr.c" |
||||
|
#include "ptw32_processInitialize.c" |
||||
|
#include "ptw32_processTerminate.c" |
||||
|
#include "ptw32_threadStart.c" |
||||
|
#include "ptw32_threadDestroy.c" |
||||
|
#include "ptw32_tkAssocCreate.c" |
||||
|
#include "ptw32_tkAssocDestroy.c" |
||||
|
#include "ptw32_callUserDestroyRoutines.c" |
||||
|
#include "ptw32_semwait.c" |
||||
|
#include "ptw32_timespec.c" |
||||
|
#include "ptw32_relmillisecs.c" |
||||
|
#include "ptw32_throw.c" |
||||
|
#include "ptw32_getprocessors.c" |
@ -0,0 +1,66 @@ |
|||||
|
/*
|
||||
|
* pthread.c |
||||
|
* |
||||
|
* Description: |
||||
|
* This translation unit agregates pthreads-win32 translation units. |
||||
|
* It is used for inline optimisation of the library, |
||||
|
* maximising for speed at the expense of size. |
||||
|
* |
||||
|
* -------------------------------------------------------------------------- |
||||
|
* |
||||
|
* 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 |
||||
|
*/ |
||||
|
|
||||
|
#include "pthread.h" |
||||
|
#include "implement.h" |
||||
|
|
||||
|
/* The following are ordered for inlining */ |
||||
|
|
||||
|
#include "private.c" |
||||
|
#include "attr.c" |
||||
|
#include "barrier.c" |
||||
|
#include "cancel.c" |
||||
|
#include "cleanup.c" |
||||
|
#include "condvar.c" |
||||
|
#include "create.c" |
||||
|
#include "dll.c" |
||||
|
#include "autostatic.c" |
||||
|
#include "errno.c" |
||||
|
#include "exit.c" |
||||
|
#include "fork.c" |
||||
|
#include "global.c" |
||||
|
#include "misc.c" |
||||
|
#include "mutex.c" |
||||
|
#include "nonportable.c" |
||||
|
#include "rwlock.c" |
||||
|
#include "sched.c" |
||||
|
#include "semaphore.c" |
||||
|
#include "signal.c" |
||||
|
#include "spin.c" |
||||
|
#include "sync.c" |
||||
|
#include "tsd.c" |
@ -0,0 +1,142 @@ |
|||||
|
# Microsoft Developer Studio Project File - Name="pthread" - Package Owner=<4> |
||||
|
# Microsoft Developer Studio Generated Build File, Format Version 6.00 |
||||
|
# ** DO NOT EDIT ** |
||||
|
|
||||
|
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 |
||||
|
|
||||
|
CFG=pthread - Win32 Debug |
||||
|
!MESSAGE This is not a valid makefile. To build this project using NMAKE, |
||||
|
!MESSAGE use the Export Makefile command and run |
||||
|
!MESSAGE |
||||
|
!MESSAGE NMAKE /f "pthread.mak". |
||||
|
!MESSAGE |
||||
|
!MESSAGE You can specify a configuration when running NMAKE |
||||
|
!MESSAGE by defining the macro CFG on the command line. For example: |
||||
|
!MESSAGE |
||||
|
!MESSAGE NMAKE /f "pthread.mak" CFG="pthread - Win32 Debug" |
||||
|
!MESSAGE |
||||
|
!MESSAGE Possible choices for configuration are: |
||||
|
!MESSAGE |
||||
|
!MESSAGE "pthread - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") |
||||
|
!MESSAGE "pthread - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") |
||||
|
!MESSAGE |
||||
|
|
||||
|
# Begin Project |
||||
|
# PROP AllowPerConfigDependencies 0 |
||||
|
# PROP Scc_ProjName "" |
||||
|
# PROP Scc_LocalPath "" |
||||
|
CPP=cl.exe |
||||
|
MTL=midl.exe |
||||
|
RSC=rc.exe |
||||
|
|
||||
|
!IF "$(CFG)" == "pthread - Win32 Release" |
||||
|
|
||||
|
# PROP BASE Use_MFC 0 |
||||
|
# PROP BASE Use_Debug_Libraries 0 |
||||
|
# PROP BASE Output_Dir "Release" |
||||
|
# PROP BASE Intermediate_Dir "Release" |
||||
|
# PROP BASE Target_Dir "" |
||||
|
# PROP Use_MFC 0 |
||||
|
# PROP Use_Debug_Libraries 0 |
||||
|
# PROP Output_Dir "." |
||||
|
# PROP Intermediate_Dir "." |
||||
|
# PROP Ignore_Export_Lib 0 |
||||
|
# PROP Target_Dir "" |
||||
|
# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PTW32_BUILD" /YX /FD /c |
||||
|
# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /D "__CLEANUP_C" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PTW32_BUILD" /YX /FD /c |
||||
|
# SUBTRACT CPP /u |
||||
|
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 |
||||
|
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 |
||||
|
# ADD BASE RSC /l 0x809 /d "NDEBUG" |
||||
|
# ADD RSC /l 0x409 /i "." /d "NDEBUG" /d "PTW32_RC_MSC" |
||||
|
BSC32=bscmake.exe |
||||
|
# ADD BASE BSC32 /nologo |
||||
|
# ADD BSC32 /nologo |
||||
|
LINK32=link.exe |
||||
|
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 |
||||
|
# ADD LINK32 kernel32.lib user32.lib ws2_32.lib /nologo /dll /pdb:none /machine:I386 /out:".\pthreadVC2.dll" |
||||
|
|
||||
|
!ELSEIF "$(CFG)" == "pthread - Win32 Debug" |
||||
|
|
||||
|
# PROP BASE Use_MFC 0 |
||||
|
# PROP BASE Use_Debug_Libraries 1 |
||||
|
# PROP BASE Output_Dir "Debug" |
||||
|
# PROP BASE Intermediate_Dir "Debug" |
||||
|
# PROP BASE Target_Dir "" |
||||
|
# PROP Use_MFC 0 |
||||
|
# PROP Use_Debug_Libraries 1 |
||||
|
# PROP Output_Dir "." |
||||
|
# PROP Intermediate_Dir "." |
||||
|
# PROP Ignore_Export_Lib 0 |
||||
|
# PROP Target_Dir "" |
||||
|
# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PTW32_BUILD" /YX /FD /GZ /c |
||||
|
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "." /D "__CLEANUP_C" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PTW32_BUILD" /YX /FD /GZ /c |
||||
|
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 |
||||
|
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 |
||||
|
# ADD BASE RSC /l 0x809 /d "_DEBUG" |
||||
|
# ADD RSC /l 0x409 /i "." /d "_DEBUG" /d "PTW32_RC_MSC" |
||||
|
BSC32=bscmake.exe |
||||
|
# ADD BASE BSC32 /nologo |
||||
|
# ADD BSC32 /nologo |
||||
|
LINK32=link.exe |
||||
|
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept |
||||
|
# ADD LINK32 kernel32.lib user32.lib ws2_32.lib /nologo /dll /map /debug /machine:I386 /out:".\pthreadVC2.dll" /pdbtype:sept |
||||
|
# SUBTRACT LINK32 /pdb:none |
||||
|
|
||||
|
!ENDIF |
||||
|
|
||||
|
# Begin Target |
||||
|
|
||||
|
# Name "pthread - Win32 Release" |
||||
|
# Name "pthread - Win32 Debug" |
||||
|
# Begin Group "Source Files" |
||||
|
|
||||
|
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" |
||||
|
# Begin Source File |
||||
|
|
||||
|
SOURCE=.\pthread.c |
||||
|
# End Source File |
||||
|
# End Group |
||||
|
# Begin Group "Header Files" |
||||
|
|
||||
|
# PROP Default_Filter "h;hpp;hxx;hm;inl" |
||||
|
# Begin Source File |
||||
|
|
||||
|
SOURCE=.\implement.h |
||||
|
# End Source File |
||||
|
# Begin Source File |
||||
|
|
||||
|
SOURCE=.\pthread.h |
||||
|
# End Source File |
||||
|
# Begin Source File |
||||
|
|
||||
|
SOURCE=.\sched.h |
||||
|
# End Source File |
||||
|
# Begin Source File |
||||
|
|
||||
|
SOURCE=.\semaphore.h |
||||
|
# End Source File |
||||
|
# End Group |
||||
|
# Begin Group "Resource Files" |
||||
|
|
||||
|
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" |
||||
|
# Begin Source File |
||||
|
|
||||
|
SOURCE=.\version.rc |
||||
|
|
||||
|
!IF "$(CFG)" == "pthread - Win32 Release" |
||||
|
|
||||
|
# ADD BASE RSC /l 0xc09 |
||||
|
# ADD RSC /l 0x409 /i "." /d "PTW32_RC_MSC" |
||||
|
|
||||
|
!ELSEIF "$(CFG)" == "pthread - Win32 Debug" |
||||
|
|
||||
|
# ADD BASE RSC /l 0xc09 |
||||
|
# ADD RSC /l 0x409 /i "." /d "PTW32_RC_MSC" |
||||
|
|
||||
|
!ENDIF |
||||
|
|
||||
|
# End Source File |
||||
|
# End Group |
||||
|
# End Target |
||||
|
# End Project |
@ -0,0 +1,29 @@ |
|||||
|
Microsoft Developer Studio Workspace File, Format Version 6.00 |
||||
|
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! |
||||
|
|
||||
|
############################################################################### |
||||
|
|
||||
|
Project: "pthread"=.\pthread.dsp - Package Owner=<4> |
||||
|
|
||||
|
Package=<5> |
||||
|
{{{ |
||||
|
}}} |
||||
|
|
||||
|
Package=<4> |
||||
|
{{{ |
||||
|
}}} |
||||
|
|
||||
|
############################################################################### |
||||
|
|
||||
|
Global: |
||||
|
|
||||
|
Package=<5> |
||||
|
{{{ |
||||
|
}}} |
||||
|
|
||||
|
Package=<3> |
||||
|
{{{ |
||||
|
}}} |
||||
|
|
||||
|
############################################################################### |
||||
|
|
File diff suppressed because it is too large
@ -0,0 +1,79 @@ |
|||||
|
/*
|
||||
|
* pthread_attr_destroy.c |
||||
|
* |
||||
|
* Description: |
||||
|
* This translation unit implements operations on thread attribute objects. |
||||
|
* |
||||
|
* -------------------------------------------------------------------------- |
||||
|
* |
||||
|
* 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 |
||||
|
*/ |
||||
|
|
||||
|
#include "pthread.h" |
||||
|
#include "implement.h" |
||||
|
|
||||
|
|
||||
|
int |
||||
|
pthread_attr_destroy (pthread_attr_t * attr) |
||||
|
/*
|
||||
|
* ------------------------------------------------------ |
||||
|
* DOCPUBLIC |
||||
|
* Destroys a thread attributes object. |
||||
|
* |
||||
|
* PARAMETERS |
||||
|
* attr |
||||
|
* pointer to an instance of pthread_attr_t |
||||
|
* |
||||
|
* |
||||
|
* DESCRIPTION |
||||
|
* Destroys a thread attributes object. |
||||
|
* |
||||
|
* NOTES: |
||||
|
* 1) Does not affect threads created with 'attr'. |
||||
|
* |
||||
|
* RESULTS |
||||
|
* 0 successfully destroyed attr, |
||||
|
* EINVAL 'attr' is invalid. |
||||
|
* |
||||
|
* ------------------------------------------------------ |
||||
|
*/ |
||||
|
{ |
||||
|
if (ptw32_is_attr (attr) != 0) |
||||
|
{ |
||||
|
return EINVAL; |
||||
|
} |
||||
|
|
||||
|
/*
|
||||
|
* Set the attribute object to a specific invalid value. |
||||
|
*/ |
||||
|
(*attr)->valid = 0; |
||||
|
free (*attr); |
||||
|
*attr = NULL; |
||||
|
|
||||
|
return 0; |
||||
|
} |
@ -0,0 +1,86 @@ |
|||||
|
/*
|
||||
|
* pthread_attr_getdetachstate.c |
||||
|
* |
||||
|
* Description: |
||||
|
* This translation unit implements operations on thread attribute objects. |
||||
|
* |
||||
|
* -------------------------------------------------------------------------- |
||||
|
* |
||||
|
* 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 |
||||
|
*/ |
||||
|
|
||||
|
#include "pthread.h" |
||||
|
#include "implement.h" |
||||
|
|
||||
|
|
||||
|
int |
||||
|
pthread_attr_getdetachstate (const pthread_attr_t * attr, int *detachstate) |
||||
|
/*
|
||||
|
* ------------------------------------------------------ |
||||
|
* DOCPUBLIC |
||||
|
* This function determines whether threads created with |
||||
|
* 'attr' will run detached. |
||||
|
* |
||||
|
* PARAMETERS |
||||
|
* attr |
||||
|
* pointer to an instance of pthread_attr_t |
||||
|
* |
||||
|
* detachstate |
||||
|
* pointer to an integer into which is returned one |
||||
|
* of: |
||||
|
* |
||||
|
* PTHREAD_CREATE_JOINABLE |
||||
|
* Thread ID is valid, must be joined |
||||
|
* |
||||
|
* PTHREAD_CREATE_DETACHED |
||||
|
* Thread ID is invalid, cannot be joined, |
||||
|
* canceled, or modified |
||||
|
* |
||||
|
* |
||||
|
* DESCRIPTION |
||||
|
* This function determines whether threads created with |
||||
|
* 'attr' will run detached. |
||||
|
* |
||||
|
* NOTES: |
||||
|
* 1) You cannot join or cancel detached threads. |
||||
|
* |
||||
|
* RESULTS |
||||
|
* 0 successfully retrieved detach state, |
||||
|
* EINVAL 'attr' is invalid |
||||
|
* |
||||
|
* ------------------------------------------------------ |
||||
|
*/ |
||||
|
{ |
||||
|
if (ptw32_is_attr (attr) != 0 || detachstate == NULL) |
||||
|
{ |
||||
|
return EINVAL; |
||||
|
} |
||||
|
|
||||
|
*detachstate = (*attr)->detachstate; |
||||
|
return 0; |
||||
|
} |
@ -0,0 +1,51 @@ |
|||||
|
/*
|
||||
|
* pthread_attr_getinheritsched.c |
||||
|
* |
||||
|
* Description: |
||||
|
* POSIX thread functions that deal with thread scheduling. |
||||
|
* |
||||
|
* -------------------------------------------------------------------------- |
||||
|
* |
||||
|
* 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 |
||||
|
*/ |
||||
|
|
||||
|
#include "pthread.h" |
||||
|
#include "implement.h" |
||||
|
#include "sched.h" |
||||
|
|
||||
|
int |
||||
|
pthread_attr_getinheritsched (const pthread_attr_t * attr, int *inheritsched) |
||||
|
{ |
||||
|
if (ptw32_is_attr (attr) != 0 || inheritsched == NULL) |
||||
|
{ |
||||
|
return EINVAL; |
||||
|
} |
||||
|
|
||||
|
*inheritsched = (*attr)->inheritsched; |
||||
|
return 0; |
||||
|
} |
@ -0,0 +1,52 @@ |
|||||
|
/*
|
||||
|
* pthread_attr_getschedparam.c |
||||
|
* |
||||
|
* Description: |
||||
|
* POSIX thread functions that deal with thread scheduling. |
||||
|
* |
||||
|
* -------------------------------------------------------------------------- |
||||
|
* |
||||
|
* 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 |
||||
|
*/ |
||||
|
|
||||
|
#include "pthread.h" |
||||
|
#include "implement.h" |
||||
|
#include "sched.h" |
||||
|
|
||||
|
int |
||||
|
pthread_attr_getschedparam (const pthread_attr_t * attr, |
||||
|
struct sched_param *param) |
||||
|
{ |
||||
|
if (ptw32_is_attr (attr) != 0 || param == NULL) |
||||
|
{ |
||||
|
return EINVAL; |
||||
|
} |
||||
|
|
||||
|
memcpy (param, &(*attr)->param, sizeof (*param)); |
||||
|
return 0; |
||||
|
} |
@ -0,0 +1,61 @@ |
|||||
|
/*
|
||||
|
* pthread_attr_getschedpolicy.c |
||||
|
* |
||||
|
* Description: |
||||
|
* POSIX thread functions that deal with thread scheduling. |
||||
|
* |
||||
|
* -------------------------------------------------------------------------- |
||||
|
* |
||||
|
* 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 |
||||
|
*/ |
||||
|
|
||||
|
#include "pthread.h" |
||||
|
#include "implement.h" |
||||
|
#include "sched.h" |
||||
|
|
||||
|
int |
||||
|
pthread_attr_getschedpolicy (const pthread_attr_t * attr, int *policy) |
||||
|
{ |
||||
|
if (ptw32_is_attr (attr) != 0 || policy == NULL) |
||||
|
{ |
||||
|
return EINVAL; |
||||
|
} |
||||
|
|
||||
|
/*
|
||||
|
* Validate the policy arg. |
||||
|
* Check that a policy constant wasn't passed rather than &policy. |
||||
|
*/ |
||||
|
if (policy <= (int *) SCHED_MAX) |
||||
|
{ |
||||
|
return EINVAL; |
||||
|
} |
||||
|
|
||||
|
*policy = SCHED_OTHER; |
||||
|
|
||||
|
return 0; |
||||
|
} |
@ -0,0 +1,54 @@ |
|||||
|
/*
|
||||
|
* pthread_attr_getscope.c |
||||
|
* |
||||
|
* Description: |
||||
|
* This translation unit implements operations on thread attribute objects. |
||||
|
* |
||||
|
* -------------------------------------------------------------------------- |
||||
|
* |
||||
|
* 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 |
||||
|
*/ |
||||
|
|
||||
|
#include "pthread.h" |
||||
|
#include "implement.h" |
||||
|
|
||||
|
/* ignore warning "unreferenced formal parameter" */ |
||||
|
#if defined(_MSC_VER) |
||||
|
#pragma warning( disable : 4100 ) |
||||
|
#endif |
||||
|
|
||||
|
int |
||||
|
pthread_attr_getscope (const pthread_attr_t * attr, int *contentionscope) |
||||
|
{ |
||||
|
#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING) |
||||
|
*contentionscope = (*attr)->contentionscope; |
||||
|
return 0; |
||||
|
#else |
||||
|
return ENOSYS; |
||||
|
#endif |
||||
|
} |
@ -0,0 +1,97 @@ |
|||||
|
/*
|
||||
|
* pthread_attr_getstackaddr.c |
||||
|
* |
||||
|
* Description: |
||||
|
* This translation unit implements operations on thread attribute objects. |
||||
|
* |
||||
|
* -------------------------------------------------------------------------- |
||||
|
* |
||||
|
* 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 |
||||
|
*/ |
||||
|
|
||||
|
#include "pthread.h" |
||||
|
#include "implement.h" |
||||
|
|
||||
|
/* ignore warning "unreferenced formal parameter" */ |
||||
|
#if defined(_MSC_VER) |
||||
|
#pragma warning( disable : 4100 ) |
||||
|
#endif |
||||
|
|
||||
|
int |
||||
|
pthread_attr_getstackaddr (const pthread_attr_t * attr, void **stackaddr) |
||||
|
/*
|
||||
|
* ------------------------------------------------------ |
||||
|
* DOCPUBLIC |
||||
|
* This function determines the address of the stack |
||||
|
* on which threads created with 'attr' will run. |
||||
|
* |
||||
|
* PARAMETERS |
||||
|
* attr |
||||
|
* pointer to an instance of pthread_attr_t |
||||
|
* |
||||
|
* stackaddr |
||||
|
* pointer into which is returned the stack address. |
||||
|
* |
||||
|
* |
||||
|
* DESCRIPTION |
||||
|
* This function determines the address of the stack |
||||
|
* on which threads created with 'attr' will run. |
||||
|
* |
||||
|
* NOTES: |
||||
|
* 1) Function supported only if this macro is |
||||
|
* defined: |
||||
|
* |
||||
|
* _POSIX_THREAD_ATTR_STACKADDR |
||||
|
* |
||||
|
* 2) Create only one thread for each stack |
||||
|
* address.. |
||||
|
* |
||||
|
* RESULTS |
||||
|
* 0 successfully retreived stack address, |
||||
|
* EINVAL 'attr' is invalid |
||||
|
* ENOSYS function not supported |
||||
|
* |
||||
|
* ------------------------------------------------------ |
||||
|
*/ |
||||
|
{ |
||||
|
#if defined( _POSIX_THREAD_ATTR_STACKADDR ) |
||||
|
|
||||
|
if (ptw32_is_attr (attr) != 0) |
||||
|
{ |
||||
|
return EINVAL; |
||||
|
} |
||||
|
|
||||
|
*stackaddr = (*attr)->stackaddr; |
||||
|
return 0; |
||||
|
|
||||
|
#else |
||||
|
|
||||
|
return ENOSYS; |
||||
|
|
||||
|
#endif /* _POSIX_THREAD_ATTR_STACKADDR */ |
||||
|
} |
@ -0,0 +1,100 @@ |
|||||
|
/*
|
||||
|
* pthread_attr_getstacksize.c |
||||
|
* |
||||
|
* Description: |
||||
|
* This translation unit implements operations on thread attribute objects. |
||||
|
* |
||||
|
* -------------------------------------------------------------------------- |
||||
|
* |
||||
|
* 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 |
||||
|
*/ |
||||
|
|
||||
|
#include "pthread.h" |
||||
|
#include "implement.h" |
||||
|
|
||||
|
/* ignore warning "unreferenced formal parameter" */ |
||||
|
#if defined(_MSC_VER) |
||||
|
#pragma warning( disable : 4100 ) |
||||
|
#endif |
||||
|
|
||||
|
int |
||||
|
pthread_attr_getstacksize (const pthread_attr_t * attr, size_t * stacksize) |
||||
|
/*
|
||||
|
* ------------------------------------------------------ |
||||
|
* DOCPUBLIC |
||||
|
* This function determines the size of the stack on |
||||
|
* which threads created with 'attr' will run. |
||||
|
* |
||||
|
* PARAMETERS |
||||
|
* attr |
||||
|
* pointer to an instance of pthread_attr_t |
||||
|
* |
||||
|
* stacksize |
||||
|
* pointer to size_t into which is returned the |
||||
|
* stack size, in bytes. |
||||
|
* |
||||
|
* |
||||
|
* DESCRIPTION |
||||
|
* This function determines the size of the stack on |
||||
|
* which threads created with 'attr' will run. |
||||
|
* |
||||
|
* NOTES: |
||||
|
* 1) Function supported only if this macro is |
||||
|
* defined: |
||||
|
* |
||||
|
* _POSIX_THREAD_ATTR_STACKSIZE |
||||
|
* |
||||
|
* 2) Use on newly created attributes object to |
||||
|
* find the default stack size. |
||||
|
* |
||||
|
* RESULTS |
||||
|
* 0 successfully retrieved stack size, |
||||
|
* EINVAL 'attr' is invalid |
||||
|
* ENOSYS function not supported |
||||
|
* |
||||
|
* ------------------------------------------------------ |
||||
|
*/ |
||||
|
{ |
||||
|
#if defined(_POSIX_THREAD_ATTR_STACKSIZE) |
||||
|
|
||||
|
if (ptw32_is_attr (attr) != 0) |
||||
|
{ |
||||
|
return EINVAL; |
||||
|
} |
||||
|
|
||||
|
/* Everything is okay. */ |
||||
|
*stacksize = (*attr)->stacksize; |
||||
|
return 0; |
||||
|
|
||||
|
#else |
||||
|
|
||||
|
return ENOSYS; |
||||
|
|
||||
|
#endif /* _POSIX_THREAD_ATTR_STACKSIZE */ |
||||
|
|
||||
|
} |
@ -0,0 +1,117 @@ |
|||||
|
/*
|
||||
|
* pthread_attr_init.c |
||||
|
* |
||||
|
* Description: |
||||
|
* This translation unit implements operations on thread attribute objects. |
||||
|
* |
||||
|
* -------------------------------------------------------------------------- |
||||
|
* |
||||
|
* 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 |
||||
|
*/ |
||||
|
|
||||
|
#include "pthread.h" |
||||
|
#include "implement.h" |
||||
|
|
||||
|
|
||||
|
int |
||||
|
pthread_attr_init (pthread_attr_t * attr) |
||||
|
/*
|
||||
|
* ------------------------------------------------------ |
||||
|
* DOCPUBLIC |
||||
|
* Initializes a thread attributes object with default |
||||
|
* attributes. |
||||
|
* |
||||
|
* PARAMETERS |
||||
|
* attr |
||||
|
* pointer to an instance of pthread_attr_t |
||||
|
* |
||||
|
* |
||||
|
* DESCRIPTION |
||||
|
* Initializes a thread attributes object with default |
||||
|
* attributes. |
||||
|
* |
||||
|
* NOTES: |
||||
|
* 1) Used to define thread attributes |
||||
|
* |
||||
|
* RESULTS |
||||
|
* 0 successfully initialized attr, |
||||
|
* ENOMEM insufficient memory for attr. |
||||
|
* |
||||
|
* ------------------------------------------------------ |
||||
|
*/ |
||||
|
{ |
||||
|
pthread_attr_t attr_result; |
||||
|
|
||||
|
if (attr == NULL) |
||||
|
{ |
||||
|
/* This is disallowed. */ |
||||
|
return EINVAL; |
||||
|
} |
||||
|
|
||||
|
attr_result = (pthread_attr_t) malloc (sizeof (*attr_result)); |
||||
|
|
||||
|
if (attr_result == NULL) |
||||
|
{ |
||||
|
return ENOMEM; |
||||
|
} |
||||
|
|
||||
|
#if defined(_POSIX_THREAD_ATTR_STACKSIZE) |
||||
|
/*
|
||||
|
* Default to zero size. Unless changed explicitly this |
||||
|
* will allow Win32 to set the size to that of the |
||||
|
* main thread. |
||||
|
*/ |
||||
|
attr_result->stacksize = 0; |
||||
|
#endif |
||||
|
|
||||
|
#if defined(_POSIX_THREAD_ATTR_STACKADDR) |
||||
|
/* FIXME: Set this to something sensible when we support it. */ |
||||
|
attr_result->stackaddr = NULL; |
||||
|
#endif |
||||
|
|
||||
|
attr_result->detachstate = PTHREAD_CREATE_JOINABLE; |
||||
|
|
||||
|
#if defined(HAVE_SIGSET_T) |
||||
|
memset (&(attr_result->sigmask), 0, sizeof (sigset_t)); |
||||
|
#endif /* HAVE_SIGSET_T */ |
||||
|
|
||||
|
/*
|
||||
|
* Win32 sets new threads to THREAD_PRIORITY_NORMAL and |
||||
|
* not to that of the parent thread. We choose to default to |
||||
|
* this arrangement. |
||||
|
*/ |
||||
|
attr_result->param.sched_priority = THREAD_PRIORITY_NORMAL; |
||||
|
attr_result->inheritsched = PTHREAD_EXPLICIT_SCHED; |
||||
|
attr_result->contentionscope = PTHREAD_SCOPE_SYSTEM; |
||||
|
|
||||
|
attr_result->valid = PTW32_ATTR_VALID; |
||||
|
|
||||
|
*attr = attr_result; |
||||
|
|
||||
|
return 0; |
||||
|
} |
@ -0,0 +1,91 @@ |
|||||
|
/*
|
||||
|
* pthread_attr_setdetachstate.c |
||||
|
* |
||||
|
* Description: |
||||
|
* This translation unit implements operations on thread attribute objects. |
||||
|
* |
||||
|
* -------------------------------------------------------------------------- |
||||
|
* |
||||
|
* 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 |
||||
|
*/ |
||||
|
|
||||
|
#include "pthread.h" |
||||
|
#include "implement.h" |
||||
|
|
||||
|
|
||||
|
int |
||||
|
pthread_attr_setdetachstate (pthread_attr_t * attr, int detachstate) |
||||
|
/*
|
||||
|
* ------------------------------------------------------ |
||||
|
* DOCPUBLIC |
||||
|
* This function specifies whether threads created with |
||||
|
* 'attr' will run detached. |
||||
|
* |
||||
|
* PARAMETERS |
||||
|
* attr |
||||
|
* pointer to an instance of pthread_attr_t |
||||
|
* |
||||
|
* detachstate |
||||
|
* an integer containing one of: |
||||
|
* |
||||
|
* PTHREAD_CREATE_JOINABLE |
||||
|
* Thread ID is valid, must be joined |
||||
|
* |
||||
|
* PTHREAD_CREATE_DETACHED |
||||
|
* Thread ID is invalid, cannot be joined, |
||||
|
* canceled, or modified |
||||
|
* |
||||
|
* |
||||
|
* DESCRIPTION |
||||
|
* This function specifies whether threads created with |
||||
|
* 'attr' will run detached. |
||||
|
* |
||||
|
* NOTES: |
||||
|
* 1) You cannot join or cancel detached threads. |
||||
|
* |
||||
|
* RESULTS |
||||
|
* 0 successfully set detach state, |
||||
|
* EINVAL 'attr' or 'detachstate' is invalid |
||||
|
* |
||||
|
* ------------------------------------------------------ |
||||
|
*/ |
||||
|
{ |
||||
|
if (ptw32_is_attr (attr) != 0) |
||||
|
{ |
||||
|
return EINVAL; |
||||
|
} |
||||
|
|
||||
|
if (detachstate != PTHREAD_CREATE_JOINABLE && |
||||
|
detachstate != PTHREAD_CREATE_DETACHED) |
||||
|
{ |
||||
|
return EINVAL; |
||||
|
} |
||||
|
|
||||
|
(*attr)->detachstate = detachstate; |
||||
|
return 0; |
||||
|
} |
@ -0,0 +1,57 @@ |
|||||
|
/*
|
||||
|
* pthread_attr_setinheritsched.c |
||||
|
* |
||||
|
* Description: |
||||
|
* POSIX thread functions that deal with thread scheduling. |
||||
|
* |
||||
|
* -------------------------------------------------------------------------- |
||||
|
* |
||||
|
* 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 |
||||
|
*/ |
||||
|
|
||||
|
#include "pthread.h" |
||||
|
#include "implement.h" |
||||
|
#include "sched.h" |
||||
|
|
||||
|
int |
||||
|
pthread_attr_setinheritsched (pthread_attr_t * attr, int inheritsched) |
||||
|
{ |
||||
|
if (ptw32_is_attr (attr) != 0) |
||||
|
{ |
||||
|
return EINVAL; |
||||
|
} |
||||
|
|
||||
|
if (PTHREAD_INHERIT_SCHED != inheritsched |
||||
|
&& PTHREAD_EXPLICIT_SCHED != inheritsched) |
||||
|
{ |
||||
|
return EINVAL; |
||||
|
} |
||||
|
|
||||
|
(*attr)->inheritsched = inheritsched; |
||||
|
return 0; |
||||
|
} |
@ -0,0 +1,63 @@ |
|||||
|
/*
|
||||
|
* pthread_attr_setschedparam.c |
||||
|
* |
||||
|
* Description: |
||||
|
* POSIX thread functions that deal with thread scheduling. |
||||
|
* |
||||
|
* -------------------------------------------------------------------------- |
||||
|
* |
||||
|
* 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 |
||||
|
*/ |
||||
|
|
||||
|
#include "pthread.h" |
||||
|
#include "implement.h" |
||||
|
#include "sched.h" |
||||
|
|
||||
|
int |
||||
|
pthread_attr_setschedparam (pthread_attr_t * attr, |
||||
|
const struct sched_param *param) |
||||
|
{ |
||||
|
int priority; |
||||
|
|
||||
|
if (ptw32_is_attr (attr) != 0 || param == NULL) |
||||
|
{ |
||||
|
return EINVAL; |
||||
|
} |
||||
|
|
||||
|
priority = param->sched_priority; |
||||
|
|
||||
|
/* Validate priority level. */ |
||||
|
if (priority < sched_get_priority_min (SCHED_OTHER) || |
||||
|
priority > sched_get_priority_max (SCHED_OTHER)) |
||||
|
{ |
||||
|
return EINVAL; |
||||
|
} |
||||
|
|
||||
|
memcpy (&(*attr)->param, param, sizeof (*param)); |
||||
|
return 0; |
||||
|
} |
@ -0,0 +1,55 @@ |
|||||
|
/*
|
||||
|
* pthread_attr_setschedpolicy.c |
||||
|
* |
||||
|
* Description: |
||||
|
* POSIX thread functions that deal with thread scheduling. |
||||
|
* |
||||
|
* -------------------------------------------------------------------------- |
||||
|
* |
||||
|
* 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 |
||||
|
*/ |
||||
|
|
||||
|
#include "pthread.h" |
||||
|
#include "implement.h" |
||||
|
#include "sched.h" |
||||
|
|
||||
|
int |
||||
|
pthread_attr_setschedpolicy (pthread_attr_t * attr, int policy) |
||||
|
{ |
||||
|
if (ptw32_is_attr (attr) != 0) |
||||
|
{ |
||||
|
return EINVAL; |
||||
|
} |
||||
|
|
||||
|
if (policy != SCHED_OTHER) |
||||
|
{ |
||||
|
return ENOTSUP; |
||||
|
} |
||||
|
|
||||
|
return 0; |
||||
|
} |
@ -0,0 +1,62 @@ |
|||||
|
/*
|
||||
|
* pthread_attr_setscope.c |
||||
|
* |
||||
|
* Description: |
||||
|
* This translation unit implements operations on thread attribute objects. |
||||
|
* |
||||
|
* -------------------------------------------------------------------------- |
||||
|
* |
||||
|
* 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 |
||||
|
*/ |
||||
|
|
||||
|
#include "pthread.h" |
||||
|
#include "implement.h" |
||||
|
|
||||
|
/* ignore warning "unreferenced formal parameter" */ |
||||
|
#if defined(_MSC_VER) |
||||
|
#pragma warning( disable : 4100 ) |
||||
|
#endif |
||||
|
|
||||
|
int |
||||
|
pthread_attr_setscope (pthread_attr_t * attr, int contentionscope) |
||||
|
{ |
||||
|
#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING) |
||||
|
switch (contentionscope) |
||||
|
{ |
||||
|
case PTHREAD_SCOPE_SYSTEM: |
||||
|
(*attr)->contentionscope = contentionscope; |
||||
|
return 0; |
||||
|
case PTHREAD_SCOPE_PROCESS: |
||||
|
return ENOTSUP; |
||||
|
default: |
||||
|
return EINVAL; |
||||
|
} |
||||
|
#else |
||||
|
return ENOSYS; |
||||
|
#endif |
||||
|
} |
@ -0,0 +1,97 @@ |
|||||
|
/*
|
||||
|
* pthread_attr_setstackaddr.c |
||||
|
* |
||||
|
* Description: |
||||
|
* This translation unit implements operations on thread attribute objects. |
||||
|
* |
||||
|
* -------------------------------------------------------------------------- |
||||
|
* |
||||
|
* 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 |
||||
|
*/ |
||||
|
|
||||
|
#include "pthread.h" |
||||
|
#include "implement.h" |
||||
|
|
||||
|
|
||||
|
int |
||||
|
pthread_attr_setstackaddr (pthread_attr_t * attr, void *stackaddr) |
||||
|
/*
|
||||
|
* ------------------------------------------------------ |
||||
|
* DOCPUBLIC |
||||
|
* Threads created with 'attr' will run on the stack |
||||
|
* starting at 'stackaddr'. |
||||
|
* Stack must be at least PTHREAD_STACK_MIN bytes. |
||||
|
* |
||||
|
* PARAMETERS |
||||
|
* attr |
||||
|
* pointer to an instance of pthread_attr_t |
||||
|
* |
||||
|
* stackaddr |
||||
|
* the address of the stack to use |
||||
|
* |
||||
|
* |
||||
|
* DESCRIPTION |
||||
|
* Threads created with 'attr' will run on the stack |
||||
|
* starting at 'stackaddr'. |
||||
|
* Stack must be at least PTHREAD_STACK_MIN bytes. |
||||
|
* |
||||
|
* NOTES: |
||||
|
* 1) Function supported only if this macro is |
||||
|
* defined: |
||||
|
* |
||||
|
* _POSIX_THREAD_ATTR_STACKADDR |
||||
|
* |
||||
|
* 2) Create only one thread for each stack |
||||
|
* address.. |
||||
|
* |
||||
|
* 3) Ensure that stackaddr is aligned. |
||||
|
* |
||||
|
* RESULTS |
||||
|
* 0 successfully set stack address, |
||||
|
* EINVAL 'attr' is invalid |
||||
|
* ENOSYS function not supported |
||||
|
* |
||||
|
* ------------------------------------------------------ |
||||
|
*/ |
||||
|
{ |
||||
|
#if defined( _POSIX_THREAD_ATTR_STACKADDR ) |
||||
|
|
||||
|
if (ptw32_is_attr (attr) != 0) |
||||
|
{ |
||||
|
return EINVAL; |
||||
|
} |
||||
|
|
||||
|
(*attr)->stackaddr = stackaddr; |
||||
|
return 0; |
||||
|
|
||||
|
#else |
||||
|
|
||||
|
return ENOSYS; |
||||
|
|
||||
|
#endif /* _POSIX_THREAD_ATTR_STACKADDR */ |
||||
|
} |
@ -0,0 +1,110 @@ |
|||||
|
/*
|
||||
|
* pthread_attr_setstacksize.c |
||||
|
* |
||||
|
* Description: |
||||
|
* This translation unit implements operations on thread attribute objects. |
||||
|
* |
||||
|
* -------------------------------------------------------------------------- |
||||
|
* |
||||
|
* 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 |
||||
|
*/ |
||||
|
|
||||
|
#include "pthread.h" |
||||
|
#include "implement.h" |
||||
|
|
||||
|
|
||||
|
int |
||||
|
pthread_attr_setstacksize (pthread_attr_t * attr, size_t stacksize) |
||||
|
/*
|
||||
|
* ------------------------------------------------------ |
||||
|
* DOCPUBLIC |
||||
|
* This function specifies the size of the stack on |
||||
|
* which threads created with 'attr' will run. |
||||
|
* |
||||
|
* PARAMETERS |
||||
|
* attr |
||||
|
* pointer to an instance of pthread_attr_t |
||||
|
* |
||||
|
* stacksize |
||||
|
* stack size, in bytes. |
||||
|
* |
||||
|
* |
||||
|
* DESCRIPTION |
||||
|
* This function specifies the size of the stack on |
||||
|
* which threads created with 'attr' will run. |
||||
|
* |
||||
|
* NOTES: |
||||
|
* 1) Function supported only if this macro is |
||||
|
* defined: |
||||
|
* |
||||
|
* _POSIX_THREAD_ATTR_STACKSIZE |
||||
|
* |
||||
|
* 2) Find the default first (using |
||||
|
* pthread_attr_getstacksize), then increase |
||||
|
* by multiplying. |
||||
|
* |
||||
|
* 3) Only use if thread needs more than the |
||||
|
* default. |
||||
|
* |
||||
|
* RESULTS |
||||
|
* 0 successfully set stack size, |
||||
|
* EINVAL 'attr' is invalid or stacksize too |
||||
|
* small or too big. |
||||
|
* ENOSYS function not supported |
||||
|
* |
||||
|
* ------------------------------------------------------ |
||||
|
*/ |
||||
|
{ |
||||
|
#if defined(_POSIX_THREAD_ATTR_STACKSIZE) |
||||
|
|
||||
|
#if PTHREAD_STACK_MIN > 0 |
||||
|
|
||||
|
/* Verify that the stack size is within range. */ |
||||
|
if (stacksize < PTHREAD_STACK_MIN) |
||||
|
{ |
||||
|
return EINVAL; |
||||
|
} |
||||
|
|
||||
|
#endif |
||||
|
|
||||
|
if (ptw32_is_attr (attr) != 0) |
||||
|
{ |
||||
|
return EINVAL; |
||||
|
} |
||||
|
|
||||
|
/* Everything is okay. */ |
||||
|
(*attr)->stacksize = stacksize; |
||||
|
return 0; |
||||
|
|
||||
|
#else |
||||
|
|
||||
|
return ENOSYS; |
||||
|
|
||||
|
#endif /* _POSIX_THREAD_ATTR_STACKSIZE */ |
||||
|
|
||||
|
} |
@ -0,0 +1,103 @@ |
|||||
|
/*
|
||||
|
* pthread_barrier_destroy.c |
||||
|
* |
||||
|
* Description: |
||||
|
* This translation unit implements barrier primitives. |
||||
|
* |
||||
|
* -------------------------------------------------------------------------- |
||||
|
* |
||||
|
* 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 |
||||
|
*/ |
||||
|
|
||||
|
#include "pthread.h" |
||||
|
#include "implement.h" |
||||
|
|
||||
|
int |
||||
|
pthread_barrier_destroy (pthread_barrier_t * barrier) |
||||
|
{ |
||||
|
int result = 0; |
||||
|
pthread_barrier_t b; |
||||
|
ptw32_mcs_local_node_t node; |
||||
|
|
||||
|
if (barrier == NULL || *barrier == (pthread_barrier_t) PTW32_OBJECT_INVALID) |
||||
|
{ |
||||
|
return EINVAL; |
||||
|
} |
||||
|
|
||||
|
if (0 != ptw32_mcs_lock_try_acquire(&(*barrier)->lock, &node)) |
||||
|
{ |
||||
|
return EBUSY; |
||||
|
} |
||||
|
|
||||
|
b = *barrier; |
||||
|
|
||||
|
if (b->nCurrentBarrierHeight < b->nInitialBarrierHeight) |
||||
|
{ |
||||
|
result = EBUSY; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
if (0 == (result = sem_destroy (&(b->semBarrierBreeched)))) |
||||
|
{ |
||||
|
*barrier = (pthread_barrier_t) PTW32_OBJECT_INVALID; |
||||
|
/*
|
||||
|
* Release the lock before freeing b. |
||||
|
* |
||||
|
* FIXME: There may be successors which, when we release the lock, |
||||
|
* will be linked into b->lock, which will be corrupted at some |
||||
|
* point with undefined results for the application. To fix this |
||||
|
* will require changing pthread_barrier_t from a pointer to |
||||
|
* pthread_barrier_t_ to an instance. This is a change to the ABI |
||||
|
* and will require a major version number increment. |
||||
|
*/ |
||||
|
ptw32_mcs_lock_release(&node); |
||||
|
(void) free (b); |
||||
|
return 0; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
/*
|
||||
|
* This should not ever be reached. |
||||
|
* Restore the barrier to working condition before returning. |
||||
|
*/ |
||||
|
(void) sem_init (&(b->semBarrierBreeched), b->pshared, 0); |
||||
|
} |
||||
|
|
||||
|
if (result != 0) |
||||
|
{ |
||||
|
/*
|
||||
|
* The barrier still exists and is valid |
||||
|
* in the event of any error above. |
||||
|
*/ |
||||
|
result = EBUSY; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
ptw32_mcs_lock_release(&node); |
||||
|
return (result); |
||||
|
} |
@ -0,0 +1,69 @@ |
|||||
|
/*
|
||||
|
* pthread_barrier_init.c |
||||
|
* |
||||
|
* Description: |
||||
|
* This translation unit implements barrier primitives. |
||||
|
* |
||||
|
* -------------------------------------------------------------------------- |
||||
|
* |
||||
|
* 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 |
||||
|
*/ |
||||
|
|
||||
|
#include "pthread.h" |
||||
|
#include "implement.h" |
||||
|
|
||||
|
|
||||
|
int |
||||
|
pthread_barrier_init (pthread_barrier_t * barrier, |
||||
|
const pthread_barrierattr_t * attr, unsigned int count) |
||||
|
{ |
||||
|
pthread_barrier_t b; |
||||
|
|
||||
|
if (barrier == NULL || count == 0) |
||||
|
{ |
||||
|
return EINVAL; |
||||
|
} |
||||
|
|
||||
|
if (NULL != (b = (pthread_barrier_t) calloc (1, sizeof (*b)))) |
||||
|
{ |
||||
|
b->pshared = (attr != NULL && *attr != NULL |
||||
|
? (*attr)->pshared : PTHREAD_PROCESS_PRIVATE); |
||||
|
|
||||
|
b->nCurrentBarrierHeight = b->nInitialBarrierHeight = count; |
||||
|
b->lock = 0; |
||||
|
|
||||
|
if (0 == sem_init (&(b->semBarrierBreeched), b->pshared, 0)) |
||||
|
{ |
||||
|
*barrier = b; |
||||
|
return 0; |
||||
|
} |
||||
|
(void) free (b); |
||||
|
} |
||||
|
|
||||
|
return ENOMEM; |
||||
|
} |
@ -0,0 +1,104 @@ |
|||||
|
/*
|
||||
|
* pthread_barrier_wait.c |
||||
|
* |
||||
|
* Description: |
||||
|
* This translation unit implements barrier primitives. |
||||
|
* |
||||
|
* -------------------------------------------------------------------------- |
||||
|
* |
||||
|
* 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 |
||||
|
*/ |
||||
|
|
||||
|
#include "pthread.h" |
||||
|
#include "implement.h" |
||||
|
|
||||
|
|
||||
|
int |
||||
|
pthread_barrier_wait (pthread_barrier_t * barrier) |
||||
|
{ |
||||
|
int result; |
||||
|
pthread_barrier_t b; |
||||
|
|
||||
|
ptw32_mcs_local_node_t node; |
||||
|
|
||||
|
if (barrier == NULL || *barrier == (pthread_barrier_t) PTW32_OBJECT_INVALID) |
||||
|
{ |
||||
|
return EINVAL; |
||||
|
} |
||||
|
|
||||
|
ptw32_mcs_lock_acquire(&(*barrier)->lock, &node); |
||||
|
|
||||
|
b = *barrier; |
||||
|
if (--b->nCurrentBarrierHeight == 0) |
||||
|
{ |
||||
|
/*
|
||||
|
* We are the last thread to arrive at the barrier before it releases us. |
||||
|
* Move our MCS local node to the global scope barrier handle so that the |
||||
|
* last thread out (not necessarily us) can release the lock. |
||||
|
*/ |
||||
|
ptw32_mcs_node_transfer(&b->proxynode, &node); |
||||
|
|
||||
|
/*
|
||||
|
* Any threads that have not quite entered sem_wait below when the |
||||
|
* multiple_post has completed will nevertheless continue through |
||||
|
* the semaphore (barrier). |
||||
|
*/ |
||||
|
result = (b->nInitialBarrierHeight > 1 |
||||
|
? sem_post_multiple (&(b->semBarrierBreeched), |
||||
|
b->nInitialBarrierHeight - 1) : 0); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
ptw32_mcs_lock_release(&node); |
||||
|
/*
|
||||
|
* Use the non-cancelable version of sem_wait(). |
||||
|
* |
||||
|
* It is possible that all nInitialBarrierHeight-1 threads are |
||||
|
* at this point when the last thread enters the barrier, resets |
||||
|
* nCurrentBarrierHeight = nInitialBarrierHeight and leaves. |
||||
|
* If pthread_barrier_destroy is called at that moment then the |
||||
|
* barrier will be destroyed along with the semas. |
||||
|
*/ |
||||
|
result = ptw32_semwait (&(b->semBarrierBreeched)); |
||||
|
} |
||||
|
|
||||
|
if ((PTW32_INTERLOCKED_LONG)PTW32_INTERLOCKED_INCREMENT_LONG((PTW32_INTERLOCKED_LONGPTR)&b->nCurrentBarrierHeight) |
||||
|
== (PTW32_INTERLOCKED_LONG)b->nInitialBarrierHeight) |
||||
|
{ |
||||
|
/*
|
||||
|
* We are the last thread to cross this barrier |
||||
|
*/ |
||||
|
ptw32_mcs_lock_release(&b->proxynode); |
||||
|
if (0 == result) |
||||
|
{ |
||||
|
result = PTHREAD_BARRIER_SERIAL_THREAD; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return (result); |
||||
|
} |
@ -0,0 +1,83 @@ |
|||||
|
/*
|
||||
|
* pthread_barrier_attr_destroy.c |
||||
|
* |
||||
|
* Description: |
||||
|
* This translation unit implements barrier primitives. |
||||
|
* |
||||
|
* -------------------------------------------------------------------------- |
||||
|
* |
||||
|
* 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 |
||||
|
*/ |
||||
|
|
||||
|
#include "pthread.h" |
||||
|
#include "implement.h" |
||||
|
|
||||
|
|
||||
|
int |
||||
|
pthread_barrierattr_destroy (pthread_barrierattr_t * attr) |
||||
|
/*
|
||||
|
* ------------------------------------------------------ |
||||
|
* DOCPUBLIC |
||||
|
* Destroys a barrier attributes object. The object can |
||||
|
* no longer be used. |
||||
|
* |
||||
|
* PARAMETERS |
||||
|
* attr |
||||
|
* pointer to an instance of pthread_barrierattr_t |
||||
|
* |
||||
|
* |
||||
|
* DESCRIPTION |
||||
|
* Destroys a barrier attributes object. The object can |
||||
|
* no longer be used. |
||||
|
* |
||||
|
* NOTES: |
||||
|
* 1) Does not affect barrieres created using 'attr' |
||||
|
* |
||||
|
* RESULTS |
||||
|
* 0 successfully released attr, |
||||
|
* EINVAL 'attr' is invalid. |
||||
|
* |
||||
|
* ------------------------------------------------------ |
||||
|
*/ |
||||
|
{ |
||||
|
int result = 0; |
||||
|
|
||||
|
if (attr == NULL || *attr == NULL) |
||||
|
{ |
||||
|
result = EINVAL; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
pthread_barrierattr_t ba = *attr; |
||||
|
|
||||
|
*attr = NULL; |
||||
|
free (ba); |
||||
|
} |
||||
|
|
||||
|
return (result); |
||||
|
} /* pthread_barrierattr_destroy */ |
@ -0,0 +1,95 @@ |
|||||
|
/*
|
||||
|
* pthread_barrier_attr_getpshared.c |
||||
|
* |
||||
|
* Description: |
||||
|
* This translation unit implements barrier primitives. |
||||
|
* |
||||
|
* -------------------------------------------------------------------------- |
||||
|
* |
||||
|
* 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 |
||||
|
*/ |
||||
|
|
||||
|
#include "pthread.h" |
||||
|
#include "implement.h" |
||||
|
|
||||
|
|
||||
|
int |
||||
|
pthread_barrierattr_getpshared (const pthread_barrierattr_t * attr, |
||||
|
int *pshared) |
||||
|
/*
|
||||
|
* ------------------------------------------------------ |
||||
|
* DOCPUBLIC |
||||
|
* Determine whether barriers created with 'attr' can be |
||||
|
* shared between processes. |
||||
|
* |
||||
|
* PARAMETERS |
||||
|
* attr |
||||
|
* pointer to an instance of pthread_barrierattr_t |
||||
|
* |
||||
|
* pshared |
||||
|
* will be set to one of: |
||||
|
* |
||||
|
* PTHREAD_PROCESS_SHARED |
||||
|
* May be shared if in shared memory |
||||
|
* |
||||
|
* PTHREAD_PROCESS_PRIVATE |
||||
|
* Cannot be shared. |
||||
|
* |
||||
|
* |
||||
|
* DESCRIPTION |
||||
|
* Mutexes creatd with 'attr' can be shared between |
||||
|
* processes if pthread_barrier_t variable is allocated |
||||
|
* in memory shared by these processes. |
||||
|
* NOTES: |
||||
|
* 1) pshared barriers MUST be allocated in shared |
||||
|
* memory. |
||||
|
* 2) The following macro is defined if shared barriers |
||||
|
* are supported: |
||||
|
* _POSIX_THREAD_PROCESS_SHARED |
||||
|
* |
||||
|
* RESULTS |
||||
|
* 0 successfully retrieved attribute, |
||||
|
* EINVAL 'attr' is invalid, |
||||
|
* |
||||
|
* ------------------------------------------------------ |
||||
|
*/ |
||||
|
{ |
||||
|
int result; |
||||
|
|
||||
|
if ((attr != NULL && *attr != NULL) && (pshared != NULL)) |
||||
|
{ |
||||
|
*pshared = (*attr)->pshared; |
||||
|
result = 0; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
result = EINVAL; |
||||
|
} |
||||
|
|
||||
|
return (result); |
||||
|
} /* pthread_barrierattr_getpshared */ |
@ -0,0 +1,85 @@ |
|||||
|
/*
|
||||
|
* pthread_barrier_attr_init.c |
||||
|
* |
||||
|
* Description: |
||||
|
* This translation unit implements barrier primitives. |
||||
|
* |
||||
|
* -------------------------------------------------------------------------- |
||||
|
* |
||||
|
* 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 |
||||
|
*/ |
||||
|
|
||||
|
#include "pthread.h" |
||||
|
#include "implement.h" |
||||
|
|
||||
|
|
||||
|
int |
||||
|
pthread_barrierattr_init (pthread_barrierattr_t * attr) |
||||
|
/*
|
||||
|
* ------------------------------------------------------ |
||||
|
* DOCPUBLIC |
||||
|
* Initializes a barrier attributes object with default |
||||
|
* attributes. |
||||
|
* |
||||
|
* PARAMETERS |
||||
|
* attr |
||||
|
* pointer to an instance of pthread_barrierattr_t |
||||
|
* |
||||
|
* |
||||
|
* DESCRIPTION |
||||
|
* Initializes a barrier attributes object with default |
||||
|
* attributes. |
||||
|
* |
||||
|
* NOTES: |
||||
|
* 1) Used to define barrier types |
||||
|
* |
||||
|
* RESULTS |
||||
|
* 0 successfully initialized attr, |
||||
|
* ENOMEM insufficient memory for attr. |
||||
|
* |
||||
|
* ------------------------------------------------------ |
||||
|
*/ |
||||
|
{ |
||||
|
pthread_barrierattr_t ba; |
||||
|
int result = 0; |
||||
|
|
||||
|
ba = (pthread_barrierattr_t) calloc (1, sizeof (*ba)); |
||||
|
|
||||
|
if (ba == NULL) |
||||
|
{ |
||||
|
result = ENOMEM; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
ba->pshared = PTHREAD_PROCESS_PRIVATE; |
||||
|
} |
||||
|
|
||||
|
*attr = ba; |
||||
|
|
||||
|
return (result); |
||||
|
} /* pthread_barrierattr_init */ |
@ -0,0 +1,119 @@ |
|||||
|
/*
|
||||
|
* pthread_barrier_attr_setpshared.c |
||||
|
* |
||||
|
* Description: |
||||
|
* This translation unit implements barrier primitives. |
||||
|
* |
||||
|
* -------------------------------------------------------------------------- |
||||
|
* |
||||
|
* 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 |
||||
|
*/ |
||||
|
|
||||
|
#include "pthread.h" |
||||
|
#include "implement.h" |
||||
|
|
||||
|
|
||||
|
int |
||||
|
pthread_barrierattr_setpshared (pthread_barrierattr_t * attr, int pshared) |
||||
|
/*
|
||||
|
* ------------------------------------------------------ |
||||
|
* DOCPUBLIC |
||||
|
* Barriers created with 'attr' can be shared between |
||||
|
* processes if pthread_barrier_t variable is allocated |
||||
|
* in memory shared by these processes. |
||||
|
* |
||||
|
* PARAMETERS |
||||
|
* attr |
||||
|
* pointer to an instance of pthread_barrierattr_t |
||||
|
* |
||||
|
* pshared |
||||
|
* must be one of: |
||||
|
* |
||||
|
* PTHREAD_PROCESS_SHARED |
||||
|
* May be shared if in shared memory |
||||
|
* |
||||
|
* PTHREAD_PROCESS_PRIVATE |
||||
|
* Cannot be shared. |
||||
|
* |
||||
|
* DESCRIPTION |
||||
|
* Mutexes creatd with 'attr' can be shared between |
||||
|
* processes if pthread_barrier_t variable is allocated |
||||
|
* in memory shared by these processes. |
||||
|
* |
||||
|
* NOTES: |
||||
|
* 1) pshared barriers MUST be allocated in shared |
||||
|
* memory. |
||||
|
* |
||||
|
* 2) The following macro is defined if shared barriers |
||||
|
* are supported: |
||||
|
* _POSIX_THREAD_PROCESS_SHARED |
||||
|
* |
||||
|
* RESULTS |
||||
|
* 0 successfully set attribute, |
||||
|
* EINVAL 'attr' or pshared is invalid, |
||||
|
* ENOSYS PTHREAD_PROCESS_SHARED not supported, |
||||
|
* |
||||
|
* ------------------------------------------------------ |
||||
|
*/ |
||||
|
{ |
||||
|
int result; |
||||
|
|
||||
|
if ((attr != NULL && *attr != NULL) && |
||||
|
((pshared == PTHREAD_PROCESS_SHARED) || |
||||
|
(pshared == PTHREAD_PROCESS_PRIVATE))) |
||||
|
{ |
||||
|
if (pshared == PTHREAD_PROCESS_SHARED) |
||||
|
{ |
||||
|
|
||||
|
#if !defined( _POSIX_THREAD_PROCESS_SHARED ) |
||||
|
|
||||
|
result = ENOSYS; |
||||
|
pshared = PTHREAD_PROCESS_PRIVATE; |
||||
|
|
||||
|
#else |
||||
|
|
||||
|
result = 0; |
||||
|
|
||||
|
#endif /* _POSIX_THREAD_PROCESS_SHARED */ |
||||
|
|
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
result = 0; |
||||
|
} |
||||
|
|
||||
|
(*attr)->pshared = pshared; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
result = EINVAL; |
||||
|
} |
||||
|
|
||||
|
return (result); |
||||
|
|
||||
|
} /* pthread_barrierattr_setpshared */ |
@ -0,0 +1,189 @@ |
|||||
|
/*
|
||||
|
* pthread_cancel.c |
||||
|
* |
||||
|
* Description: |
||||
|
* POSIX thread functions related to thread cancellation. |
||||
|
* |
||||
|
* -------------------------------------------------------------------------- |
||||
|
* |
||||
|
* 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 |
||||
|
*/ |
||||
|
|
||||
|
#include "pthread.h" |
||||
|
#include "implement.h" |
||||
|
#include "context.h" |
||||
|
|
||||
|
static void |
||||
|
ptw32_cancel_self (void) |
||||
|
{ |
||||
|
ptw32_throw (PTW32_EPS_CANCEL); |
||||
|
|
||||
|
/* Never reached */ |
||||
|
} |
||||
|
|
||||
|
static void CALLBACK |
||||
|
ptw32_cancel_callback (ULONG_PTR unused) |
||||
|
{ |
||||
|
ptw32_throw (PTW32_EPS_CANCEL); |
||||
|
|
||||
|
/* Never reached */ |
||||
|
} |
||||
|
|
||||
|
/*
|
||||
|
* ptw32_RegisterCancelation() - |
||||
|
* Must have args of same type as QueueUserAPCEx because this function |
||||
|
* is a substitute for QueueUserAPCEx if it's not available. |
||||
|
*/ |
||||
|
DWORD |
||||
|
ptw32_RegisterCancelation (PAPCFUNC unused1, HANDLE threadH, DWORD unused2) |
||||
|
{ |
||||
|
CONTEXT context; |
||||
|
|
||||
|
context.ContextFlags = CONTEXT_CONTROL; |
||||
|
GetThreadContext (threadH, &context); |
||||
|
PTW32_PROGCTR (context) = (DWORD_PTR) ptw32_cancel_self; |
||||
|
SetThreadContext (threadH, &context); |
||||
|
return 0; |
||||
|
} |
||||
|
|
||||
|
int |
||||
|
pthread_cancel (pthread_t thread) |
||||
|
/*
|
||||
|
* ------------------------------------------------------ |
||||
|
* DOCPUBLIC |
||||
|
* This function requests cancellation of 'thread'. |
||||
|
* |
||||
|
* PARAMETERS |
||||
|
* thread |
||||
|
* reference to an instance of pthread_t |
||||
|
* |
||||
|
* |
||||
|
* DESCRIPTION |
||||
|
* This function requests cancellation of 'thread'. |
||||
|
* NOTE: cancellation is asynchronous; use pthread_join to |
||||
|
* wait for termination of 'thread' if necessary. |
||||
|
* |
||||
|
* RESULTS |
||||
|
* 0 successfully requested cancellation, |
||||
|
* ESRCH no thread found corresponding to 'thread', |
||||
|
* ENOMEM implicit self thread create failed. |
||||
|
* ------------------------------------------------------ |
||||
|
*/ |
||||
|
{ |
||||
|
int result; |
||||
|
int cancel_self; |
||||
|
pthread_t self; |
||||
|
ptw32_thread_t * tp; |
||||
|
ptw32_mcs_local_node_t stateLock; |
||||
|
|
||||
|
result = pthread_kill (thread, 0); |
||||
|
|
||||
|
if (0 != result) |
||||
|
{ |
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
if ((self = pthread_self ()).p == NULL) |
||||
|
{ |
||||
|
return ENOMEM; |
||||
|
}; |
||||
|
|
||||
|
/*
|
||||
|
* For self cancellation we need to ensure that a thread can't |
||||
|
* deadlock itself trying to cancel itself asynchronously |
||||
|
* (pthread_cancel is required to be an async-cancel |
||||
|
* safe function). |
||||
|
*/ |
||||
|
cancel_self = pthread_equal (thread, self); |
||||
|
|
||||
|
tp = (ptw32_thread_t *) thread.p; |
||||
|
|
||||
|
/*
|
||||
|
* Lock for async-cancel safety. |
||||
|
*/ |
||||
|
ptw32_mcs_lock_acquire (&tp->stateLock, &stateLock); |
||||
|
|
||||
|
if (tp->cancelType == PTHREAD_CANCEL_ASYNCHRONOUS |
||||
|
&& tp->cancelState == PTHREAD_CANCEL_ENABLE |
||||
|
&& tp->state < PThreadStateCanceling) |
||||
|
{ |
||||
|
if (cancel_self) |
||||
|
{ |
||||
|
tp->state = PThreadStateCanceling; |
||||
|
tp->cancelState = PTHREAD_CANCEL_DISABLE; |
||||
|
|
||||
|
ptw32_mcs_lock_release (&stateLock); |
||||
|
ptw32_throw (PTW32_EPS_CANCEL); |
||||
|
|
||||
|
/* Never reached */ |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
HANDLE threadH = tp->threadH; |
||||
|
|
||||
|
SuspendThread (threadH); |
||||
|
|
||||
|
if (WaitForSingleObject (threadH, 0) == WAIT_TIMEOUT) |
||||
|
{ |
||||
|
tp->state = PThreadStateCanceling; |
||||
|
tp->cancelState = PTHREAD_CANCEL_DISABLE; |
||||
|
/*
|
||||
|
* If alertdrv and QueueUserAPCEx is available then the following |
||||
|
* will result in a call to QueueUserAPCEx with the args given, otherwise |
||||
|
* this will result in a call to ptw32_RegisterCancelation and only |
||||
|
* the threadH arg will be used. |
||||
|
*/ |
||||
|
ptw32_register_cancelation ((PAPCFUNC)ptw32_cancel_callback, threadH, 0); |
||||
|
ptw32_mcs_lock_release (&stateLock); |
||||
|
ResumeThread (threadH); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
/*
|
||||
|
* Set for deferred cancellation. |
||||
|
*/ |
||||
|
if (tp->state < PThreadStateCancelPending) |
||||
|
{ |
||||
|
tp->state = PThreadStateCancelPending; |
||||
|
if (!SetEvent (tp->cancelEvent)) |
||||
|
{ |
||||
|
result = ESRCH; |
||||
|
} |
||||
|
} |
||||
|
else if (tp->state >= PThreadStateCanceling) |
||||
|
{ |
||||
|
result = ESRCH; |
||||
|
} |
||||
|
|
||||
|
ptw32_mcs_lock_release (&stateLock); |
||||
|
} |
||||
|
|
||||
|
return (result); |
||||
|
} |
@ -0,0 +1,253 @@ |
|||||
|
/*
|
||||
|
* pthread_cond_destroy.c |
||||
|
* |
||||
|
* Description: |
||||
|
* This translation unit implements condition variables and their primitives. |
||||
|
* |
||||
|
* |
||||
|
* -------------------------------------------------------------------------- |
||||
|
* |
||||
|
* 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 |
||||
|
*/ |
||||
|
|
||||
|
#include "pthread.h" |
||||
|
#include "implement.h" |
||||
|
|
||||
|
int |
||||
|
pthread_cond_destroy (pthread_cond_t * cond) |
||||
|
/*
|
||||
|
* ------------------------------------------------------ |
||||
|
* DOCPUBLIC |
||||
|
* This function destroys a condition variable |
||||
|
* |
||||
|
* |
||||
|
* PARAMETERS |
||||
|
* cond |
||||
|
* pointer to an instance of pthread_cond_t |
||||
|
* |
||||
|
* |
||||
|
* DESCRIPTION |
||||
|
* This function destroys a condition variable. |
||||
|
* |
||||
|
* NOTES: |
||||
|
* 1) A condition variable can be destroyed |
||||
|
* immediately after all the threads that |
||||
|
* are blocked on it are awakened. e.g. |
||||
|
* |
||||
|
* struct list { |
||||
|
* pthread_mutex_t lm; |
||||
|
* ... |
||||
|
* } |
||||
|
* |
||||
|
* struct elt { |
||||
|
* key k; |
||||
|
* int busy; |
||||
|
* pthread_cond_t notbusy; |
||||
|
* ... |
||||
|
* } |
||||
|
* |
||||
|
* |
||||
|
* struct elt * |
||||
|
* list_find(struct list *lp, key k) |
||||
|
* { |
||||
|
* struct elt *ep; |
||||
|
* |
||||
|
* pthread_mutex_lock(&lp->lm); |
||||
|
* while ((ep = find_elt(l,k) != NULL) && ep->busy) |
||||
|
* pthread_cond_wait(&ep->notbusy, &lp->lm); |
||||
|
* if (ep != NULL) |
||||
|
* ep->busy = 1; |
||||
|
* pthread_mutex_unlock(&lp->lm); |
||||
|
* return(ep); |
||||
|
* } |
||||
|
* |
||||
|
* delete_elt(struct list *lp, struct elt *ep) |
||||
|
* { |
||||
|
* pthread_mutex_lock(&lp->lm); |
||||
|
* assert(ep->busy); |
||||
|
* ... remove ep from list ... |
||||
|
* ep->busy = 0; |
||||
|
* (A) pthread_cond_broadcast(&ep->notbusy); |
||||
|
* pthread_mutex_unlock(&lp->lm); |
||||
|
* (B) pthread_cond_destroy(&rp->notbusy); |
||||
|
* free(ep); |
||||
|
* } |
||||
|
* |
||||
|
* In this example, the condition variable |
||||
|
* and its list element may be freed (line B) |
||||
|
* immediately after all threads waiting for |
||||
|
* it are awakened (line A), since the mutex |
||||
|
* and the code ensure that no other thread |
||||
|
* can touch the element to be deleted. |
||||
|
* |
||||
|
* RESULTS |
||||
|
* 0 successfully released condition variable, |
||||
|
* EINVAL 'cond' is invalid, |
||||
|
* EBUSY 'cond' is in use, |
||||
|
* |
||||
|
* ------------------------------------------------------ |
||||
|
*/ |
||||
|
{ |
||||
|
pthread_cond_t cv; |
||||
|
int result = 0, result1 = 0, result2 = 0; |
||||
|
|
||||
|
/*
|
||||
|
* Assuming any race condition here is harmless. |
||||
|
*/ |
||||
|
if (cond == NULL || *cond == NULL) |
||||
|
{ |
||||
|
return EINVAL; |
||||
|
} |
||||
|
|
||||
|
if (*cond != PTHREAD_COND_INITIALIZER) |
||||
|
{ |
||||
|
ptw32_mcs_local_node_t node; |
||||
|
ptw32_mcs_lock_acquire(&ptw32_cond_list_lock, &node); |
||||
|
|
||||
|
cv = *cond; |
||||
|
|
||||
|
/*
|
||||
|
* Close the gate; this will synchronize this thread with |
||||
|
* all already signaled waiters to let them retract their |
||||
|
* waiter status - SEE NOTE 1 ABOVE!!! |
||||
|
*/ |
||||
|
if (ptw32_semwait (&(cv->semBlockLock)) != 0) /* Non-cancelable */ |
||||
|
{ |
||||
|
result = errno; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
/*
|
||||
|
* !TRY! lock mtxUnblockLock; try will detect busy condition |
||||
|
* and will not cause a deadlock with respect to concurrent |
||||
|
* signal/broadcast. |
||||
|
*/ |
||||
|
if ((result = pthread_mutex_trylock (&(cv->mtxUnblockLock))) != 0) |
||||
|
{ |
||||
|
(void) sem_post (&(cv->semBlockLock)); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (result != 0) |
||||
|
{ |
||||
|
ptw32_mcs_lock_release(&node); |
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
/*
|
||||
|
* Check whether cv is still busy (still has waiters) |
||||
|
*/ |
||||
|
if (cv->nWaitersBlocked > cv->nWaitersGone) |
||||
|
{ |
||||
|
if (sem_post (&(cv->semBlockLock)) != 0) |
||||
|
{ |
||||
|
result = errno; |
||||
|
} |
||||
|
result1 = pthread_mutex_unlock (&(cv->mtxUnblockLock)); |
||||
|
result2 = EBUSY; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
/*
|
||||
|
* Now it is safe to destroy |
||||
|
*/ |
||||
|
*cond = NULL; |
||||
|
|
||||
|
if (sem_destroy (&(cv->semBlockLock)) != 0) |
||||
|
{ |
||||
|
result = errno; |
||||
|
} |
||||
|
if (sem_destroy (&(cv->semBlockQueue)) != 0) |
||||
|
{ |
||||
|
result1 = errno; |
||||
|
} |
||||
|
if ((result2 = pthread_mutex_unlock (&(cv->mtxUnblockLock))) == 0) |
||||
|
{ |
||||
|
result2 = pthread_mutex_destroy (&(cv->mtxUnblockLock)); |
||||
|
} |
||||
|
|
||||
|
/* Unlink the CV from the list */ |
||||
|
|
||||
|
if (ptw32_cond_list_head == cv) |
||||
|
{ |
||||
|
ptw32_cond_list_head = cv->next; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
cv->prev->next = cv->next; |
||||
|
} |
||||
|
|
||||
|
if (ptw32_cond_list_tail == cv) |
||||
|
{ |
||||
|
ptw32_cond_list_tail = cv->prev; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
cv->next->prev = cv->prev; |
||||
|
} |
||||
|
|
||||
|
(void) free (cv); |
||||
|
} |
||||
|
|
||||
|
ptw32_mcs_lock_release(&node); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
ptw32_mcs_local_node_t node; |
||||
|
/*
|
||||
|
* See notes in ptw32_cond_check_need_init() above also. |
||||
|
*/ |
||||
|
ptw32_mcs_lock_acquire(&ptw32_cond_test_init_lock, &node); |
||||
|
|
||||
|
/*
|
||||
|
* Check again. |
||||
|
*/ |
||||
|
if (*cond == PTHREAD_COND_INITIALIZER) |
||||
|
{ |
||||
|
/*
|
||||
|
* This is all we need to do to destroy a statically |
||||
|
* initialised cond that has not yet been used (initialised). |
||||
|
* If we get to here, another thread waiting to initialise |
||||
|
* this cond will get an EINVAL. That's OK. |
||||
|
*/ |
||||
|
*cond = NULL; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
/*
|
||||
|
* The cv has been initialised while we were waiting |
||||
|
* so assume it's in use. |
||||
|
*/ |
||||
|
result = EBUSY; |
||||
|
} |
||||
|
|
||||
|
ptw32_mcs_lock_release(&node); |
||||
|
} |
||||
|
|
||||
|
return ((result != 0) ? result : ((result1 != 0) ? result1 : result2)); |
||||
|
} |
@ -0,0 +1,167 @@ |
|||||
|
/*
|
||||
|
* pthread_cond_init.c |
||||
|
* |
||||
|
* Description: |
||||
|
* This translation unit implements condition variables and their primitives. |
||||
|
* |
||||
|
* |
||||
|
* -------------------------------------------------------------------------- |
||||
|
* |
||||
|
* 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 |
||||
|
*/ |
||||
|
|
||||
|
#include "pthread.h" |
||||
|
#include "implement.h" |
||||
|
|
||||
|
|
||||
|
int |
||||
|
pthread_cond_init (pthread_cond_t * cond, const pthread_condattr_t * attr) |
||||
|
/*
|
||||
|
* ------------------------------------------------------ |
||||
|
* DOCPUBLIC |
||||
|
* This function initializes a condition variable. |
||||
|
* |
||||
|
* PARAMETERS |
||||
|
* cond |
||||
|
* pointer to an instance of pthread_cond_t |
||||
|
* |
||||
|
* attr |
||||
|
* specifies optional creation attributes. |
||||
|
* |
||||
|
* |
||||
|
* DESCRIPTION |
||||
|
* This function initializes a condition variable. |
||||
|
* |
||||
|
* RESULTS |
||||
|
* 0 successfully created condition variable, |
||||
|
* EINVAL 'attr' is invalid, |
||||
|
* EAGAIN insufficient resources (other than |
||||
|
* memory, |
||||
|
* ENOMEM insufficient memory, |
||||
|
* EBUSY 'cond' is already initialized, |
||||
|
* |
||||
|
* ------------------------------------------------------ |
||||
|
*/ |
||||
|
{ |
||||
|
int result; |
||||
|
pthread_cond_t cv = NULL; |
||||
|
|
||||
|
if (cond == NULL) |
||||
|
{ |
||||
|
return EINVAL; |
||||
|
} |
||||
|
|
||||
|
if ((attr != NULL && *attr != NULL) && |
||||
|
((*attr)->pshared == PTHREAD_PROCESS_SHARED)) |
||||
|
{ |
||||
|
/*
|
||||
|
* Creating condition variable that can be shared between |
||||
|
* processes. |
||||
|
*/ |
||||
|
result = ENOSYS; |
||||
|
goto DONE; |
||||
|
} |
||||
|
|
||||
|
cv = (pthread_cond_t) calloc (1, sizeof (*cv)); |
||||
|
|
||||
|
if (cv == NULL) |
||||
|
{ |
||||
|
result = ENOMEM; |
||||
|
goto DONE; |
||||
|
} |
||||
|
|
||||
|
cv->nWaitersBlocked = 0; |
||||
|
cv->nWaitersToUnblock = 0; |
||||
|
cv->nWaitersGone = 0; |
||||
|
|
||||
|
if (sem_init (&(cv->semBlockLock), 0, 1) != 0) |
||||
|
{ |
||||
|
result = errno; |
||||
|
goto FAIL0; |
||||
|
} |
||||
|
|
||||
|
if (sem_init (&(cv->semBlockQueue), 0, 0) != 0) |
||||
|
{ |
||||
|
result = errno; |
||||
|
goto FAIL1; |
||||
|
} |
||||
|
|
||||
|
if ((result = pthread_mutex_init (&(cv->mtxUnblockLock), 0)) != 0) |
||||
|
{ |
||||
|
goto FAIL2; |
||||
|
} |
||||
|
|
||||
|
result = 0; |
||||
|
|
||||
|
goto DONE; |
||||
|
|
||||
|
/*
|
||||
|
* ------------- |
||||
|
* Failed... |
||||
|
* ------------- |
||||
|
*/ |
||||
|
FAIL2: |
||||
|
(void) sem_destroy (&(cv->semBlockQueue)); |
||||
|
|
||||
|
FAIL1: |
||||
|
(void) sem_destroy (&(cv->semBlockLock)); |
||||
|
|
||||
|
FAIL0: |
||||
|
(void) free (cv); |
||||
|
cv = NULL; |
||||
|
|
||||
|
DONE: |
||||
|
if (0 == result) |
||||
|
{ |
||||
|
ptw32_mcs_local_node_t node; |
||||
|
|
||||
|
ptw32_mcs_lock_acquire(&ptw32_cond_list_lock, &node); |
||||
|
|
||||
|
cv->next = NULL; |
||||
|
cv->prev = ptw32_cond_list_tail; |
||||
|
|
||||
|
if (ptw32_cond_list_tail != NULL) |
||||
|
{ |
||||
|
ptw32_cond_list_tail->next = cv; |
||||
|
} |
||||
|
|
||||
|
ptw32_cond_list_tail = cv; |
||||
|
|
||||
|
if (ptw32_cond_list_head == NULL) |
||||
|
{ |
||||
|
ptw32_cond_list_head = cv; |
||||
|
} |
||||
|
|
||||
|
ptw32_mcs_lock_release(&node); |
||||
|
} |
||||
|
|
||||
|
*cond = cv; |
||||
|
|
||||
|
return result; |
||||
|
|
||||
|
} /* pthread_cond_init */ |
@ -0,0 +1,231 @@ |
|||||
|
/*
|
||||
|
* pthread_cond_signal.c |
||||
|
* |
||||
|
* Description: |
||||
|
* This translation unit implements condition variables and their primitives. |
||||
|
* |
||||
|
* |
||||
|
* -------------------------------------------------------------------------- |
||||
|
* |
||||
|
* 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 |
||||
|
* |
||||
|
* ------------------------------------------------------------- |
||||
|
* Algorithm: |
||||
|
* See the comments at the top of pthread_cond_wait.c. |
||||
|
*/ |
||||
|
|
||||
|
#include "pthread.h" |
||||
|
#include "implement.h" |
||||
|
|
||||
|
static INLINE int |
||||
|
ptw32_cond_unblock (pthread_cond_t * cond, int unblockAll) |
||||
|
/*
|
||||
|
* Notes. |
||||
|
* |
||||
|
* Does not use the external mutex for synchronisation, |
||||
|
* therefore semBlockLock is needed. |
||||
|
* mtxUnblockLock is for LEVEL-2 synch. LEVEL-2 is the |
||||
|
* state where the external mutex is not necessarily locked by |
||||
|
* any thread, ie. between cond_wait unlocking and re-acquiring |
||||
|
* the lock after having been signaled or a timeout or |
||||
|
* cancellation. |
||||
|
* |
||||
|
* Uses the following CV elements: |
||||
|
* nWaitersBlocked |
||||
|
* nWaitersToUnblock |
||||
|
* nWaitersGone |
||||
|
* mtxUnblockLock |
||||
|
* semBlockLock |
||||
|
* semBlockQueue |
||||
|
*/ |
||||
|
{ |
||||
|
int result; |
||||
|
pthread_cond_t cv; |
||||
|
int nSignalsToIssue; |
||||
|
|
||||
|
if (cond == NULL || *cond == NULL) |
||||
|
{ |
||||
|
return EINVAL; |
||||
|
} |
||||
|
|
||||
|
cv = *cond; |
||||
|
|
||||
|
/*
|
||||
|
* No-op if the CV is static and hasn't been initialised yet. |
||||
|
* Assuming that any race condition is harmless. |
||||
|
*/ |
||||
|
if (cv == PTHREAD_COND_INITIALIZER) |
||||
|
{ |
||||
|
return 0; |
||||
|
} |
||||
|
|
||||
|
if ((result = pthread_mutex_lock (&(cv->mtxUnblockLock))) != 0) |
||||
|
{ |
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
if (0 != cv->nWaitersToUnblock) |
||||
|
{ |
||||
|
if (0 == cv->nWaitersBlocked) |
||||
|
{ |
||||
|
return pthread_mutex_unlock (&(cv->mtxUnblockLock)); |
||||
|
} |
||||
|
if (unblockAll) |
||||
|
{ |
||||
|
cv->nWaitersToUnblock += (nSignalsToIssue = cv->nWaitersBlocked); |
||||
|
cv->nWaitersBlocked = 0; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
nSignalsToIssue = 1; |
||||
|
cv->nWaitersToUnblock++; |
||||
|
cv->nWaitersBlocked--; |
||||
|
} |
||||
|
} |
||||
|
else if (cv->nWaitersBlocked > cv->nWaitersGone) |
||||
|
{ |
||||
|
/* Use the non-cancellable version of sem_wait() */ |
||||
|
if (ptw32_semwait (&(cv->semBlockLock)) != 0) |
||||
|
{ |
||||
|
result = errno; |
||||
|
(void) pthread_mutex_unlock (&(cv->mtxUnblockLock)); |
||||
|
return result; |
||||
|
} |
||||
|
if (0 != cv->nWaitersGone) |
||||
|
{ |
||||
|
cv->nWaitersBlocked -= cv->nWaitersGone; |
||||
|
cv->nWaitersGone = 0; |
||||
|
} |
||||
|
if (unblockAll) |
||||
|
{ |
||||
|
nSignalsToIssue = cv->nWaitersToUnblock = cv->nWaitersBlocked; |
||||
|
cv->nWaitersBlocked = 0; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
nSignalsToIssue = cv->nWaitersToUnblock = 1; |
||||
|
cv->nWaitersBlocked--; |
||||
|
} |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
return pthread_mutex_unlock (&(cv->mtxUnblockLock)); |
||||
|
} |
||||
|
|
||||
|
if ((result = pthread_mutex_unlock (&(cv->mtxUnblockLock))) == 0) |
||||
|
{ |
||||
|
if (sem_post_multiple (&(cv->semBlockQueue), nSignalsToIssue) != 0) |
||||
|
{ |
||||
|
result = errno; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return result; |
||||
|
|
||||
|
} /* ptw32_cond_unblock */ |
||||
|
|
||||
|
int |
||||
|
pthread_cond_signal (pthread_cond_t * cond) |
||||
|
/*
|
||||
|
* ------------------------------------------------------ |
||||
|
* DOCPUBLIC |
||||
|
* This function signals a condition variable, waking |
||||
|
* one waiting thread. |
||||
|
* If SCHED_FIFO or SCHED_RR policy threads are waiting |
||||
|
* the highest priority waiter is awakened; otherwise, |
||||
|
* an unspecified waiter is awakened. |
||||
|
* |
||||
|
* PARAMETERS |
||||
|
* cond |
||||
|
* pointer to an instance of pthread_cond_t |
||||
|
* |
||||
|
* |
||||
|
* DESCRIPTION |
||||
|
* This function signals a condition variable, waking |
||||
|
* one waiting thread. |
||||
|
* If SCHED_FIFO or SCHED_RR policy threads are waiting |
||||
|
* the highest priority waiter is awakened; otherwise, |
||||
|
* an unspecified waiter is awakened. |
||||
|
* |
||||
|
* NOTES: |
||||
|
* |
||||
|
* 1) Use when any waiter can respond and only one need |
||||
|
* respond (all waiters being equal). |
||||
|
* |
||||
|
* RESULTS |
||||
|
* 0 successfully signaled condition, |
||||
|
* EINVAL 'cond' is invalid, |
||||
|
* |
||||
|
* ------------------------------------------------------ |
||||
|
*/ |
||||
|
{ |
||||
|
/*
|
||||
|
* The '0'(FALSE) unblockAll arg means unblock ONE waiter. |
||||
|
*/ |
||||
|
return (ptw32_cond_unblock (cond, 0)); |
||||
|
|
||||
|
} /* pthread_cond_signal */ |
||||
|
|
||||
|
int |
||||
|
pthread_cond_broadcast (pthread_cond_t * cond) |
||||
|
/*
|
||||
|
* ------------------------------------------------------ |
||||
|
* DOCPUBLIC |
||||
|
* This function broadcasts the condition variable, |
||||
|
* waking all current waiters. |
||||
|
* |
||||
|
* PARAMETERS |
||||
|
* cond |
||||
|
* pointer to an instance of pthread_cond_t |
||||
|
* |
||||
|
* |
||||
|
* DESCRIPTION |
||||
|
* This function signals a condition variable, waking |
||||
|
* all waiting threads. |
||||
|
* |
||||
|
* NOTES: |
||||
|
* |
||||
|
* 1) Use when more than one waiter may respond to |
||||
|
* predicate change or if any waiting thread may |
||||
|
* not be able to respond |
||||
|
* |
||||
|
* RESULTS |
||||
|
* 0 successfully signalled condition to all |
||||
|
* waiting threads, |
||||
|
* EINVAL 'cond' is invalid |
||||
|
* ENOSPC a required resource has been exhausted, |
||||
|
* |
||||
|
* ------------------------------------------------------ |
||||
|
*/ |
||||
|
{ |
||||
|
/*
|
||||
|
* The TRUE unblockAll arg means unblock ALL waiters. |
||||
|
*/ |
||||
|
return (ptw32_cond_unblock (cond, PTW32_TRUE)); |
||||
|
|
||||
|
} /* pthread_cond_broadcast */ |
@ -0,0 +1,567 @@ |
|||||
|
/*
|
||||
|
* pthread_cond_wait.c |
||||
|
* |
||||
|
* Description: |
||||
|
* This translation unit implements condition variables and their primitives. |
||||
|
* |
||||
|
* |
||||
|
* -------------------------------------------------------------------------- |
||||
|
* |
||||
|
* 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 |
||||
|
* |
||||
|
* ------------------------------------------------------------- |
||||
|
* Algorithm: |
||||
|
* The algorithm used in this implementation is that developed by |
||||
|
* Alexander Terekhov in colaboration with Louis Thomas. The bulk |
||||
|
* of the discussion is recorded in the file README.CV, which contains |
||||
|
* several generations of both colaborators original algorithms. The final |
||||
|
* algorithm used here is the one referred to as |
||||
|
* |
||||
|
* Algorithm 8a / IMPL_SEM,UNBLOCK_STRATEGY == UNBLOCK_ALL |
||||
|
* |
||||
|
* presented below in pseudo-code as it appeared: |
||||
|
* |
||||
|
* |
||||
|
* given: |
||||
|
* semBlockLock - bin.semaphore |
||||
|
* semBlockQueue - semaphore |
||||
|
* mtxExternal - mutex or CS |
||||
|
* mtxUnblockLock - mutex or CS |
||||
|
* nWaitersGone - int |
||||
|
* nWaitersBlocked - int |
||||
|
* nWaitersToUnblock - int |
||||
|
* |
||||
|
* wait( timeout ) { |
||||
|
* |
||||
|
* [auto: register int result ] // error checking omitted
|
||||
|
* [auto: register int nSignalsWasLeft ] |
||||
|
* [auto: register int nWaitersWasGone ] |
||||
|
* |
||||
|
* sem_wait( semBlockLock ); |
||||
|
* nWaitersBlocked++; |
||||
|
* sem_post( semBlockLock ); |
||||
|
* |
||||
|
* unlock( mtxExternal ); |
||||
|
* bTimedOut = sem_wait( semBlockQueue,timeout ); |
||||
|
* |
||||
|
* lock( mtxUnblockLock ); |
||||
|
* if ( 0 != (nSignalsWasLeft = nWaitersToUnblock) ) { |
||||
|
* if ( bTimeout ) { // timeout (or canceled)
|
||||
|
* if ( 0 != nWaitersBlocked ) { |
||||
|
* nWaitersBlocked--; |
||||
|
* } |
||||
|
* else { |
||||
|
* nWaitersGone++; // count spurious wakeups.
|
||||
|
* } |
||||
|
* } |
||||
|
* if ( 0 == --nWaitersToUnblock ) { |
||||
|
* if ( 0 != nWaitersBlocked ) { |
||||
|
* sem_post( semBlockLock ); // open the gate.
|
||||
|
* nSignalsWasLeft = 0; // do not open the gate
|
||||
|
* // below again.
|
||||
|
* } |
||||
|
* else if ( 0 != (nWaitersWasGone = nWaitersGone) ) { |
||||
|
* nWaitersGone = 0; |
||||
|
* } |
||||
|
* } |
||||
|
* } |
||||
|
* else if ( INT_MAX/2 == ++nWaitersGone ) { // timeout/canceled or
|
||||
|
* // spurious semaphore :-)
|
||||
|
* sem_wait( semBlockLock ); |
||||
|
* nWaitersBlocked -= nWaitersGone; // something is going on here
|
||||
|
* // - test of timeouts? :-)
|
||||
|
* sem_post( semBlockLock ); |
||||
|
* nWaitersGone = 0; |
||||
|
* } |
||||
|
* unlock( mtxUnblockLock ); |
||||
|
* |
||||
|
* if ( 1 == nSignalsWasLeft ) { |
||||
|
* if ( 0 != nWaitersWasGone ) { |
||||
|
* // sem_adjust( semBlockQueue,-nWaitersWasGone );
|
||||
|
* while ( nWaitersWasGone-- ) { |
||||
|
* sem_wait( semBlockQueue ); // better now than spurious later
|
||||
|
* } |
||||
|
* } sem_post( semBlockLock ); // open the gate
|
||||
|
* } |
||||
|
* |
||||
|
* lock( mtxExternal ); |
||||
|
* |
||||
|
* return ( bTimedOut ) ? ETIMEOUT : 0; |
||||
|
* } |
||||
|
* |
||||
|
* signal(bAll) { |
||||
|
* |
||||
|
* [auto: register int result ] |
||||
|
* [auto: register int nSignalsToIssue] |
||||
|
* |
||||
|
* lock( mtxUnblockLock ); |
||||
|
* |
||||
|
* if ( 0 != nWaitersToUnblock ) { // the gate is closed!!!
|
||||
|
* if ( 0 == nWaitersBlocked ) { // NO-OP
|
||||
|
* return unlock( mtxUnblockLock ); |
||||
|
* } |
||||
|
* if (bAll) { |
||||
|
* nWaitersToUnblock += nSignalsToIssue=nWaitersBlocked; |
||||
|
* nWaitersBlocked = 0; |
||||
|
* } |
||||
|
* else { |
||||
|
* nSignalsToIssue = 1; |
||||
|
* nWaitersToUnblock++; |
||||
|
* nWaitersBlocked--; |
||||
|
* } |
||||
|
* } |
||||
|
* else if ( nWaitersBlocked > nWaitersGone ) { // HARMLESS RACE CONDITION!
|
||||
|
* sem_wait( semBlockLock ); // close the gate
|
||||
|
* if ( 0 != nWaitersGone ) { |
||||
|
* nWaitersBlocked -= nWaitersGone; |
||||
|
* nWaitersGone = 0; |
||||
|
* } |
||||
|
* if (bAll) { |
||||
|
* nSignalsToIssue = nWaitersToUnblock = nWaitersBlocked; |
||||
|
* nWaitersBlocked = 0; |
||||
|
* } |
||||
|
* else { |
||||
|
* nSignalsToIssue = nWaitersToUnblock = 1; |
||||
|
* nWaitersBlocked--; |
||||
|
* } |
||||
|
* } |
||||
|
* else { // NO-OP
|
||||
|
* return unlock( mtxUnblockLock ); |
||||
|
* } |
||||
|
* |
||||
|
* unlock( mtxUnblockLock ); |
||||
|
* sem_post( semBlockQueue,nSignalsToIssue ); |
||||
|
* return result; |
||||
|
* } |
||||
|
* ------------------------------------------------------------- |
||||
|
* |
||||
|
* Algorithm 9 / IMPL_SEM,UNBLOCK_STRATEGY == UNBLOCK_ALL |
||||
|
* |
||||
|
* presented below in pseudo-code; basically 8a... |
||||
|
* ...BUT W/O "spurious wakes" prevention: |
||||
|
* |
||||
|
* |
||||
|
* given: |
||||
|
* semBlockLock - bin.semaphore |
||||
|
* semBlockQueue - semaphore |
||||
|
* mtxExternal - mutex or CS |
||||
|
* mtxUnblockLock - mutex or CS |
||||
|
* nWaitersGone - int |
||||
|
* nWaitersBlocked - int |
||||
|
* nWaitersToUnblock - int |
||||
|
* |
||||
|
* wait( timeout ) { |
||||
|
* |
||||
|
* [auto: register int result ] // error checking omitted
|
||||
|
* [auto: register int nSignalsWasLeft ] |
||||
|
* |
||||
|
* sem_wait( semBlockLock ); |
||||
|
* ++nWaitersBlocked; |
||||
|
* sem_post( semBlockLock ); |
||||
|
* |
||||
|
* unlock( mtxExternal ); |
||||
|
* bTimedOut = sem_wait( semBlockQueue,timeout ); |
||||
|
* |
||||
|
* lock( mtxUnblockLock ); |
||||
|
* if ( 0 != (nSignalsWasLeft = nWaitersToUnblock) ) { |
||||
|
* --nWaitersToUnblock; |
||||
|
* } |
||||
|
* else if ( INT_MAX/2 == ++nWaitersGone ) { // timeout/canceled or
|
||||
|
* // spurious semaphore :-)
|
||||
|
* sem_wait( semBlockLock ); |
||||
|
* nWaitersBlocked -= nWaitersGone; // something is going on here
|
||||
|
* // - test of timeouts? :-)
|
||||
|
* sem_post( semBlockLock ); |
||||
|
* nWaitersGone = 0; |
||||
|
* } |
||||
|
* unlock( mtxUnblockLock ); |
||||
|
* |
||||
|
* if ( 1 == nSignalsWasLeft ) { |
||||
|
* sem_post( semBlockLock ); // open the gate
|
||||
|
* } |
||||
|
* |
||||
|
* lock( mtxExternal ); |
||||
|
* |
||||
|
* return ( bTimedOut ) ? ETIMEOUT : 0; |
||||
|
* } |
||||
|
* |
||||
|
* signal(bAll) { |
||||
|
* |
||||
|
* [auto: register int result ] |
||||
|
* [auto: register int nSignalsToIssue] |
||||
|
* |
||||
|
* lock( mtxUnblockLock ); |
||||
|
* |
||||
|
* if ( 0 != nWaitersToUnblock ) { // the gate is closed!!!
|
||||
|
* if ( 0 == nWaitersBlocked ) { // NO-OP
|
||||
|
* return unlock( mtxUnblockLock ); |
||||
|
* } |
||||
|
* if (bAll) { |
||||
|
* nWaitersToUnblock += nSignalsToIssue=nWaitersBlocked; |
||||
|
* nWaitersBlocked = 0; |
||||
|
* } |
||||
|
* else { |
||||
|
* nSignalsToIssue = 1; |
||||
|
* ++nWaitersToUnblock; |
||||
|
* --nWaitersBlocked; |
||||
|
* } |
||||
|
* } |
||||
|
* else if ( nWaitersBlocked > nWaitersGone ) { // HARMLESS RACE CONDITION!
|
||||
|
* sem_wait( semBlockLock ); // close the gate
|
||||
|
* if ( 0 != nWaitersGone ) { |
||||
|
* nWaitersBlocked -= nWaitersGone; |
||||
|
* nWaitersGone = 0; |
||||
|
* } |
||||
|
* if (bAll) { |
||||
|
* nSignalsToIssue = nWaitersToUnblock = nWaitersBlocked; |
||||
|
* nWaitersBlocked = 0; |
||||
|
* } |
||||
|
* else { |
||||
|
* nSignalsToIssue = nWaitersToUnblock = 1; |
||||
|
* --nWaitersBlocked; |
||||
|
* } |
||||
|
* } |
||||
|
* else { // NO-OP
|
||||
|
* return unlock( mtxUnblockLock ); |
||||
|
* } |
||||
|
* |
||||
|
* unlock( mtxUnblockLock ); |
||||
|
* sem_post( semBlockQueue,nSignalsToIssue ); |
||||
|
* return result; |
||||
|
* } |
||||
|
* ------------------------------------------------------------- |
||||
|
* |
||||
|
*/ |
||||
|
|
||||
|
#include "pthread.h" |
||||
|
#include "implement.h" |
||||
|
|
||||
|
/*
|
||||
|
* Arguments for cond_wait_cleanup, since we can only pass a |
||||
|
* single void * to it. |
||||
|
*/ |
||||
|
typedef struct |
||||
|
{ |
||||
|
pthread_mutex_t *mutexPtr; |
||||
|
pthread_cond_t cv; |
||||
|
int *resultPtr; |
||||
|
} ptw32_cond_wait_cleanup_args_t; |
||||
|
|
||||
|
static void PTW32_CDECL |
||||
|
ptw32_cond_wait_cleanup (void *args) |
||||
|
{ |
||||
|
ptw32_cond_wait_cleanup_args_t *cleanup_args = |
||||
|
(ptw32_cond_wait_cleanup_args_t *) args; |
||||
|
pthread_cond_t cv = cleanup_args->cv; |
||||
|
int *resultPtr = cleanup_args->resultPtr; |
||||
|
int nSignalsWasLeft; |
||||
|
int result; |
||||
|
|
||||
|
/*
|
||||
|
* Whether we got here as a result of signal/broadcast or because of |
||||
|
* timeout on wait or thread cancellation we indicate that we are no |
||||
|
* longer waiting. The waiter is responsible for adjusting waiters |
||||
|
* (to)unblock(ed) counts (protected by unblock lock). |
||||
|
*/ |
||||
|
if ((result = pthread_mutex_lock (&(cv->mtxUnblockLock))) != 0) |
||||
|
{ |
||||
|
*resultPtr = result; |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
if (0 != (nSignalsWasLeft = cv->nWaitersToUnblock)) |
||||
|
{ |
||||
|
--(cv->nWaitersToUnblock); |
||||
|
} |
||||
|
else if (INT_MAX / 2 == ++(cv->nWaitersGone)) |
||||
|
{ |
||||
|
/* Use the non-cancellable version of sem_wait() */ |
||||
|
if (ptw32_semwait (&(cv->semBlockLock)) != 0) |
||||
|
{ |
||||
|
*resultPtr = errno; |
||||
|
/*
|
||||
|
* This is a fatal error for this CV, |
||||
|
* so we deliberately don't unlock |
||||
|
* cv->mtxUnblockLock before returning. |
||||
|
*/ |
||||
|
return; |
||||
|
} |
||||
|
cv->nWaitersBlocked -= cv->nWaitersGone; |
||||
|
if (sem_post (&(cv->semBlockLock)) != 0) |
||||
|
{ |
||||
|
*resultPtr = errno; |
||||
|
/*
|
||||
|
* This is a fatal error for this CV, |
||||
|
* so we deliberately don't unlock |
||||
|
* cv->mtxUnblockLock before returning. |
||||
|
*/ |
||||
|
return; |
||||
|
} |
||||
|
cv->nWaitersGone = 0; |
||||
|
} |
||||
|
|
||||
|
if ((result = pthread_mutex_unlock (&(cv->mtxUnblockLock))) != 0) |
||||
|
{ |
||||
|
*resultPtr = result; |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
if (1 == nSignalsWasLeft) |
||||
|
{ |
||||
|
if (sem_post (&(cv->semBlockLock)) != 0) |
||||
|
{ |
||||
|
*resultPtr = errno; |
||||
|
return; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/*
|
||||
|
* XSH: Upon successful return, the mutex has been locked and is owned |
||||
|
* by the calling thread. |
||||
|
*/ |
||||
|
if ((result = pthread_mutex_lock (cleanup_args->mutexPtr)) != 0) |
||||
|
{ |
||||
|
*resultPtr = result; |
||||
|
} |
||||
|
} /* ptw32_cond_wait_cleanup */ |
||||
|
|
||||
|
static INLINE int |
||||
|
ptw32_cond_timedwait (pthread_cond_t * cond, |
||||
|
pthread_mutex_t * mutex, const struct timespec *abstime) |
||||
|
{ |
||||
|
int result = 0; |
||||
|
pthread_cond_t cv; |
||||
|
ptw32_cond_wait_cleanup_args_t cleanup_args; |
||||
|
|
||||
|
if (cond == NULL || *cond == NULL) |
||||
|
{ |
||||
|
return EINVAL; |
||||
|
} |
||||
|
|
||||
|
/*
|
||||
|
* We do a quick check to see if we need to do more work |
||||
|
* to initialise a static condition variable. We check |
||||
|
* again inside the guarded section of ptw32_cond_check_need_init() |
||||
|
* to avoid race conditions. |
||||
|
*/ |
||||
|
if (*cond == PTHREAD_COND_INITIALIZER) |
||||
|
{ |
||||
|
result = ptw32_cond_check_need_init (cond); |
||||
|
} |
||||
|
|
||||
|
if (result != 0 && result != EBUSY) |
||||
|
{ |
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
cv = *cond; |
||||
|
|
||||
|
/* Thread can be cancelled in sem_wait() but this is OK */ |
||||
|
if (sem_wait (&(cv->semBlockLock)) != 0) |
||||
|
{ |
||||
|
return errno; |
||||
|
} |
||||
|
|
||||
|
++(cv->nWaitersBlocked); |
||||
|
|
||||
|
if (sem_post (&(cv->semBlockLock)) != 0) |
||||
|
{ |
||||
|
return errno; |
||||
|
} |
||||
|
|
||||
|
/*
|
||||
|
* Setup this waiter cleanup handler |
||||
|
*/ |
||||
|
cleanup_args.mutexPtr = mutex; |
||||
|
cleanup_args.cv = cv; |
||||
|
cleanup_args.resultPtr = &result; |
||||
|
|
||||
|
#if defined(_MSC_VER) && _MSC_VER < 1400 |
||||
|
#pragma inline_depth(0) |
||||
|
#endif |
||||
|
pthread_cleanup_push (ptw32_cond_wait_cleanup, (void *) &cleanup_args); |
||||
|
|
||||
|
/*
|
||||
|
* Now we can release 'mutex' and... |
||||
|
*/ |
||||
|
if ((result = pthread_mutex_unlock (mutex)) == 0) |
||||
|
{ |
||||
|
|
||||
|
/*
|
||||
|
* ...wait to be awakened by |
||||
|
* pthread_cond_signal, or |
||||
|
* pthread_cond_broadcast, or |
||||
|
* timeout, or |
||||
|
* thread cancellation |
||||
|
* |
||||
|
* Note: |
||||
|
* |
||||
|
* sem_timedwait is a cancellation point, |
||||
|
* hence providing the mechanism for making |
||||
|
* pthread_cond_wait a cancellation point. |
||||
|
* We use the cleanup mechanism to ensure we |
||||
|
* re-lock the mutex and adjust (to)unblock(ed) waiters |
||||
|
* counts if we are cancelled, timed out or signalled. |
||||
|
*/ |
||||
|
if (sem_timedwait (&(cv->semBlockQueue), abstime) != 0) |
||||
|
{ |
||||
|
result = errno; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/*
|
||||
|
* Always cleanup |
||||
|
*/ |
||||
|
pthread_cleanup_pop (1); |
||||
|
#if defined(_MSC_VER) && _MSC_VER < 1400 |
||||
|
#pragma inline_depth() |
||||
|
#endif |
||||
|
|
||||
|
/*
|
||||
|
* "result" can be modified by the cleanup handler. |
||||
|
*/ |
||||
|
return result; |
||||
|
|
||||
|
} /* ptw32_cond_timedwait */ |
||||
|
|
||||
|
|
||||
|
int |
||||
|
pthread_cond_wait (pthread_cond_t * cond, pthread_mutex_t * mutex) |
||||
|
/*
|
||||
|
* ------------------------------------------------------ |
||||
|
* DOCPUBLIC |
||||
|
* This function waits on a condition variable until |
||||
|
* awakened by a signal or broadcast. |
||||
|
* |
||||
|
* Caller MUST be holding the mutex lock; the |
||||
|
* lock is released and the caller is blocked waiting |
||||
|
* on 'cond'. When 'cond' is signaled, the mutex |
||||
|
* is re-acquired before returning to the caller. |
||||
|
* |
||||
|
* PARAMETERS |
||||
|
* cond |
||||
|
* pointer to an instance of pthread_cond_t |
||||
|
* |
||||
|
* mutex |
||||
|
* pointer to an instance of pthread_mutex_t |
||||
|
* |
||||
|
* |
||||
|
* DESCRIPTION |
||||
|
* This function waits on a condition variable until |
||||
|
* awakened by a signal or broadcast. |
||||
|
* |
||||
|
* NOTES: |
||||
|
* |
||||
|
* 1) The function must be called with 'mutex' LOCKED |
||||
|
* by the calling thread, or undefined behaviour |
||||
|
* will result. |
||||
|
* |
||||
|
* 2) This routine atomically releases 'mutex' and causes |
||||
|
* the calling thread to block on the condition variable. |
||||
|
* The blocked thread may be awakened by |
||||
|
* pthread_cond_signal or |
||||
|
* pthread_cond_broadcast. |
||||
|
* |
||||
|
* Upon successful completion, the 'mutex' has been locked and |
||||
|
* is owned by the calling thread. |
||||
|
* |
||||
|
* |
||||
|
* RESULTS |
||||
|
* 0 caught condition; mutex released, |
||||
|
* EINVAL 'cond' or 'mutex' is invalid, |
||||
|
* EINVAL different mutexes for concurrent waits, |
||||
|
* EINVAL mutex is not held by the calling thread, |
||||
|
* |
||||
|
* ------------------------------------------------------ |
||||
|
*/ |
||||
|
{ |
||||
|
/*
|
||||
|
* The NULL abstime arg means INFINITE waiting. |
||||
|
*/ |
||||
|
return (ptw32_cond_timedwait (cond, mutex, NULL)); |
||||
|
|
||||
|
} /* pthread_cond_wait */ |
||||
|
|
||||
|
|
||||
|
int |
||||
|
pthread_cond_timedwait (pthread_cond_t * cond, |
||||
|
pthread_mutex_t * mutex, |
||||
|
const struct timespec *abstime) |
||||
|
/*
|
||||
|
* ------------------------------------------------------ |
||||
|
* DOCPUBLIC |
||||
|
* This function waits on a condition variable either until |
||||
|
* awakened by a signal or broadcast; or until the time |
||||
|
* specified by abstime passes. |
||||
|
* |
||||
|
* PARAMETERS |
||||
|
* cond |
||||
|
* pointer to an instance of pthread_cond_t |
||||
|
* |
||||
|
* mutex |
||||
|
* pointer to an instance of pthread_mutex_t |
||||
|
* |
||||
|
* abstime |
||||
|
* pointer to an instance of (const struct timespec) |
||||
|
* |
||||
|
* |
||||
|
* DESCRIPTION |
||||
|
* This function waits on a condition variable either until |
||||
|
* awakened by a signal or broadcast; or until the time |
||||
|
* specified by abstime passes. |
||||
|
* |
||||
|
* NOTES: |
||||
|
* 1) The function must be called with 'mutex' LOCKED |
||||
|
* by the calling thread, or undefined behaviour |
||||
|
* will result. |
||||
|
* |
||||
|
* 2) This routine atomically releases 'mutex' and causes |
||||
|
* the calling thread to block on the condition variable. |
||||
|
* The blocked thread may be awakened by |
||||
|
* pthread_cond_signal or |
||||
|
* pthread_cond_broadcast. |
||||
|
* |
||||
|
* |
||||
|
* RESULTS |
||||
|
* 0 caught condition; mutex released, |
||||
|
* EINVAL 'cond', 'mutex', or abstime is invalid, |
||||
|
* EINVAL different mutexes for concurrent waits, |
||||
|
* EINVAL mutex is not held by the calling thread, |
||||
|
* ETIMEDOUT abstime ellapsed before cond was signaled. |
||||
|
* |
||||
|
* ------------------------------------------------------ |
||||
|
*/ |
||||
|
{ |
||||
|
if (abstime == NULL) |
||||
|
{ |
||||
|
return EINVAL; |
||||
|
} |
||||
|
|
||||
|
return (ptw32_cond_timedwait (cond, mutex, abstime)); |
||||
|
|
||||
|
} /* pthread_cond_timedwait */ |
@ -0,0 +1,86 @@ |
|||||
|
/*
|
||||
|
* condvar_attr_destroy.c |
||||
|
* |
||||
|
* Description: |
||||
|
* This translation unit implements condition variables and their primitives. |
||||
|
* |
||||
|
* |
||||
|
* -------------------------------------------------------------------------- |
||||
|
* |
||||
|
* 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 |
||||
|
*/ |
||||
|
|
||||
|
#include "pthread.h" |
||||
|
#include "implement.h" |
||||
|
|
||||
|
|
||||
|
int |
||||
|
pthread_condattr_destroy (pthread_condattr_t * attr) |
||||
|
/*
|
||||
|
* ------------------------------------------------------ |
||||
|
* DOCPUBLIC |
||||
|
* Destroys a condition variable attributes object. |
||||
|
* The object can no longer be used. |
||||
|
* |
||||
|
* PARAMETERS |
||||
|
* attr |
||||
|
* pointer to an instance of pthread_condattr_t |
||||
|
* |
||||
|
* |
||||
|
* DESCRIPTION |
||||
|
* Destroys a condition variable attributes object. |
||||
|
* The object can no longer be used. |
||||
|
* |
||||
|
* NOTES: |
||||
|
* 1) Does not affect condition variables created |
||||
|
* using 'attr' |
||||
|
* |
||||
|
* RESULTS |
||||
|
* 0 successfully released attr, |
||||
|
* EINVAL 'attr' is invalid. |
||||
|
* |
||||
|
* ------------------------------------------------------ |
||||
|
*/ |
||||
|
{ |
||||
|
int result = 0; |
||||
|
|
||||
|
if (attr == NULL || *attr == NULL) |
||||
|
{ |
||||
|
result = EINVAL; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
(void) free (*attr); |
||||
|
|
||||
|
*attr = NULL; |
||||
|
result = 0; |
||||
|
} |
||||
|
|
||||
|
return result; |
||||
|
|
||||
|
} /* pthread_condattr_destroy */ |
@ -0,0 +1,97 @@ |
|||||
|
/*
|
||||
|
* pthread_condattr_getpshared.c |
||||
|
* |
||||
|
* Description: |
||||
|
* This translation unit implements condition variables and their primitives. |
||||
|
* |
||||
|
* |
||||
|
* -------------------------------------------------------------------------- |
||||
|
* |
||||
|
* 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 |
||||
|
*/ |
||||
|
|
||||
|
#include "pthread.h" |
||||
|
#include "implement.h" |
||||
|
|
||||
|
|
||||
|
int |
||||
|
pthread_condattr_getpshared (const pthread_condattr_t * attr, int *pshared) |
||||
|
/*
|
||||
|
* ------------------------------------------------------ |
||||
|
* DOCPUBLIC |
||||
|
* Determine whether condition variables created with 'attr' |
||||
|
* can be shared between processes. |
||||
|
* |
||||
|
* PARAMETERS |
||||
|
* attr |
||||
|
* pointer to an instance of pthread_condattr_t |
||||
|
* |
||||
|
* pshared |
||||
|
* will be set to one of: |
||||
|
* |
||||
|
* PTHREAD_PROCESS_SHARED |
||||
|
* May be shared if in shared memory |
||||
|
* |
||||
|
* PTHREAD_PROCESS_PRIVATE |
||||
|
* Cannot be shared. |
||||
|
* |
||||
|
* |
||||
|
* DESCRIPTION |
||||
|
* Condition Variables created with 'attr' can be shared |
||||
|
* between processes if pthread_cond_t variable is allocated |
||||
|
* in memory shared by these processes. |
||||
|
* NOTES: |
||||
|
* 1) pshared condition variables MUST be allocated in |
||||
|
* shared memory. |
||||
|
* |
||||
|
* 2) The following macro is defined if shared mutexes |
||||
|
* are supported: |
||||
|
* _POSIX_THREAD_PROCESS_SHARED |
||||
|
* |
||||
|
* RESULTS |
||||
|
* 0 successfully retrieved attribute, |
||||
|
* EINVAL 'attr' or 'pshared' is invalid, |
||||
|
* |
||||
|
* ------------------------------------------------------ |
||||
|
*/ |
||||
|
{ |
||||
|
int result; |
||||
|
|
||||
|
if ((attr != NULL && *attr != NULL) && (pshared != NULL)) |
||||
|
{ |
||||
|
*pshared = (*attr)->pshared; |
||||
|
result = 0; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
result = EINVAL; |
||||
|
} |
||||
|
|
||||
|
return result; |
||||
|
|
||||
|
} /* pthread_condattr_getpshared */ |
@ -0,0 +1,87 @@ |
|||||
|
/*
|
||||
|
* pthread_condattr_init.c |
||||
|
* |
||||
|
* Description: |
||||
|
* This translation unit implements condition variables and their primitives. |
||||
|
* |
||||
|
* |
||||
|
* -------------------------------------------------------------------------- |
||||
|
* |
||||
|
* 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 |
||||
|
*/ |
||||
|
|
||||
|
#include "pthread.h" |
||||
|
#include "implement.h" |
||||
|
|
||||
|
|
||||
|
int |
||||
|
pthread_condattr_init (pthread_condattr_t * attr) |
||||
|
/*
|
||||
|
* ------------------------------------------------------ |
||||
|
* DOCPUBLIC |
||||
|
* Initializes a condition variable attributes object |
||||
|
* with default attributes. |
||||
|
* |
||||
|
* PARAMETERS |
||||
|
* attr |
||||
|
* pointer to an instance of pthread_condattr_t |
||||
|
* |
||||
|
* |
||||
|
* DESCRIPTION |
||||
|
* Initializes a condition variable attributes object |
||||
|
* with default attributes. |
||||
|
* |
||||
|
* NOTES: |
||||
|
* 1) Use to define condition variable types |
||||
|
* 2) It is up to the application to ensure |
||||
|
* that it doesn't re-init an attribute |
||||
|
* without destroying it first. Otherwise |
||||
|
* a memory leak is created. |
||||
|
* |
||||
|
* RESULTS |
||||
|
* 0 successfully initialized attr, |
||||
|
* ENOMEM insufficient memory for attr. |
||||
|
* |
||||
|
* ------------------------------------------------------ |
||||
|
*/ |
||||
|
{ |
||||
|
pthread_condattr_t attr_result; |
||||
|
int result = 0; |
||||
|
|
||||
|
attr_result = (pthread_condattr_t) calloc (1, sizeof (*attr_result)); |
||||
|
|
||||
|
if (attr_result == NULL) |
||||
|
{ |
||||
|
result = ENOMEM; |
||||
|
} |
||||
|
|
||||
|
*attr = attr_result; |
||||
|
|
||||
|
return result; |
||||
|
|
||||
|
} /* pthread_condattr_init */ |
@ -0,0 +1,117 @@ |
|||||
|
/*
|
||||
|
* pthread_condattr_setpshared.c |
||||
|
* |
||||
|
* Description: |
||||
|
* This translation unit implements condition variables and their primitives. |
||||
|
* |
||||
|
* |
||||
|
* -------------------------------------------------------------------------- |
||||
|
* |
||||
|
* 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 |
||||
|
*/ |
||||
|
|
||||
|
#include "pthread.h" |
||||
|
#include "implement.h" |
||||
|
|
||||
|
|
||||
|
int |
||||
|
pthread_condattr_setpshared (pthread_condattr_t * attr, int pshared) |
||||
|
/*
|
||||
|
* ------------------------------------------------------ |
||||
|
* DOCPUBLIC |
||||
|
* Mutexes created with 'attr' can be shared between |
||||
|
* processes if pthread_mutex_t variable is allocated |
||||
|
* in memory shared by these processes. |
||||
|
* |
||||
|
* PARAMETERS |
||||
|
* attr |
||||
|
* pointer to an instance of pthread_mutexattr_t |
||||
|
* |
||||
|
* pshared |
||||
|
* must be one of: |
||||
|
* |
||||
|
* PTHREAD_PROCESS_SHARED |
||||
|
* May be shared if in shared memory |
||||
|
* |
||||
|
* PTHREAD_PROCESS_PRIVATE |
||||
|
* Cannot be shared. |
||||
|
* |
||||
|
* DESCRIPTION |
||||
|
* Mutexes creatd with 'attr' can be shared between |
||||
|
* processes if pthread_mutex_t variable is allocated |
||||
|
* in memory shared by these processes. |
||||
|
* |
||||
|
* NOTES: |
||||
|
* 1) pshared mutexes MUST be allocated in shared |
||||
|
* memory. |
||||
|
* |
||||
|
* 2) The following macro is defined if shared mutexes |
||||
|
* are supported: |
||||
|
* _POSIX_THREAD_PROCESS_SHARED |
||||
|
* |
||||
|
* RESULTS |
||||
|
* 0 successfully set attribute, |
||||
|
* EINVAL 'attr' or pshared is invalid, |
||||
|
* ENOSYS PTHREAD_PROCESS_SHARED not supported, |
||||
|
* |
||||
|
* ------------------------------------------------------ |
||||
|
*/ |
||||
|
{ |
||||
|
int result; |
||||
|
|
||||
|
if ((attr != NULL && *attr != NULL) |
||||
|
&& ((pshared == PTHREAD_PROCESS_SHARED) |
||||
|
|| (pshared == PTHREAD_PROCESS_PRIVATE))) |
||||
|
{ |
||||
|
if (pshared == PTHREAD_PROCESS_SHARED) |
||||
|
{ |
||||
|
|
||||
|
#if !defined( _POSIX_THREAD_PROCESS_SHARED ) |
||||
|
result = ENOSYS; |
||||
|
pshared = PTHREAD_PROCESS_PRIVATE; |
||||
|
#else |
||||
|
result = 0; |
||||
|
|
||||
|
#endif /* _POSIX_THREAD_PROCESS_SHARED */ |
||||
|
|
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
result = 0; |
||||
|
} |
||||
|
|
||||
|
(*attr)->pshared = pshared; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
result = EINVAL; |
||||
|
} |
||||
|
|
||||
|
return result; |
||||
|
|
||||
|
} /* pthread_condattr_setpshared */ |
@ -0,0 +1,172 @@ |
|||||
|
/*
|
||||
|
* pthreads_delay_np.c |
||||
|
* |
||||
|
* Description: |
||||
|
* This translation unit implements non-portable thread functions. |
||||
|
* |
||||
|
* -------------------------------------------------------------------------- |
||||
|
* |
||||
|
* 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 |
||||
|
*/ |
||||
|
|
||||
|
#include "pthread.h" |
||||
|
#include "implement.h" |
||||
|
|
||||
|
/*
|
||||
|
* pthread_delay_np |
||||
|
* |
||||
|
* DESCRIPTION |
||||
|
* |
||||
|
* This routine causes a thread to delay execution for a specific period of time. |
||||
|
* This period ends at the current time plus the specified interval. The routine |
||||
|
* will not return before the end of the period is reached, but may return an |
||||
|
* arbitrary amount of time after the period has gone by. This can be due to |
||||
|
* system load, thread priorities, and system timer granularity. |
||||
|
* |
||||
|
* Specifying an interval of zero (0) seconds and zero (0) nanoseconds is |
||||
|
* allowed and can be used to force the thread to give up the processor or to |
||||
|
* deliver a pending cancelation request. |
||||
|
* |
||||
|
* The timespec structure contains the following two fields: |
||||
|
* |
||||
|
* tv_sec is an integer number of seconds. |
||||
|
* tv_nsec is an integer number of nanoseconds. |
||||
|
* |
||||
|
* Return Values |
||||
|
* |
||||
|
* If an error condition occurs, this routine returns an integer value indicating |
||||
|
* the type of error. Possible return values are as follows: |
||||
|
* |
||||
|
* 0 |
||||
|
* Successful completion. |
||||
|
* [EINVAL] |
||||
|
* The value specified by interval is invalid. |
||||
|
* |
||||
|
* Example |
||||
|
* |
||||
|
* The following code segment would wait for 5 and 1/2 seconds |
||||
|
* |
||||
|
* struct timespec tsWait; |
||||
|
* int intRC; |
||||
|
* |
||||
|
* tsWait.tv_sec = 5; |
||||
|
* tsWait.tv_nsec = 500000000L; |
||||
|
* intRC = pthread_delay_np(&tsWait); |
||||
|
*/ |
||||
|
int |
||||
|
pthread_delay_np (struct timespec *interval) |
||||
|
{ |
||||
|
DWORD wait_time; |
||||
|
DWORD secs_in_millisecs; |
||||
|
DWORD millisecs; |
||||
|
DWORD status; |
||||
|
pthread_t self; |
||||
|
ptw32_thread_t * sp; |
||||
|
|
||||
|
if (interval == NULL) |
||||
|
{ |
||||
|
return EINVAL; |
||||
|
} |
||||
|
|
||||
|
if (interval->tv_sec == 0L && interval->tv_nsec == 0L) |
||||
|
{ |
||||
|
pthread_testcancel (); |
||||
|
Sleep (0); |
||||
|
pthread_testcancel (); |
||||
|
return (0); |
||||
|
} |
||||
|
|
||||
|
/* convert secs to millisecs */ |
||||
|
secs_in_millisecs = (DWORD)interval->tv_sec * 1000L; |
||||
|
|
||||
|
/* convert nanosecs to millisecs (rounding up) */ |
||||
|
millisecs = (interval->tv_nsec + 999999L) / 1000000L; |
||||
|
|
||||
|
#if defined(__WATCOMC__) |
||||
|
#pragma disable_message (124) |
||||
|
#endif |
||||
|
|
||||
|
/*
|
||||
|
* Most compilers will issue a warning 'comparison always 0' |
||||
|
* because the variable type is unsigned, but we need to keep this |
||||
|
* for some reason I can't recall now. |
||||
|
*/ |
||||
|
if (0 > (wait_time = secs_in_millisecs + millisecs)) |
||||
|
{ |
||||
|
return EINVAL; |
||||
|
} |
||||
|
|
||||
|
#if defined(__WATCOMC__) |
||||
|
#pragma enable_message (124) |
||||
|
#endif |
||||
|
|
||||
|
if (NULL == (self = pthread_self ()).p) |
||||
|
{ |
||||
|
return ENOMEM; |
||||
|
} |
||||
|
|
||||
|
sp = (ptw32_thread_t *) self.p; |
||||
|
|
||||
|
if (sp->cancelState == PTHREAD_CANCEL_ENABLE) |
||||
|
{ |
||||
|
/*
|
||||
|
* Async cancelation won't catch us until wait_time is up. |
||||
|
* Deferred cancelation will cancel us immediately. |
||||
|
*/ |
||||
|
if (WAIT_OBJECT_0 == |
||||
|
(status = WaitForSingleObject (sp->cancelEvent, wait_time))) |
||||
|
{ |
||||
|
ptw32_mcs_local_node_t stateLock; |
||||
|
/*
|
||||
|
* Canceling! |
||||
|
*/ |
||||
|
ptw32_mcs_lock_acquire (&sp->stateLock, &stateLock); |
||||
|
if (sp->state < PThreadStateCanceling) |
||||
|
{ |
||||
|
sp->state = PThreadStateCanceling; |
||||
|
sp->cancelState = PTHREAD_CANCEL_DISABLE; |
||||
|
ptw32_mcs_lock_release (&stateLock); |
||||
|
|
||||
|
ptw32_throw (PTW32_EPS_CANCEL); |
||||
|
} |
||||
|
|
||||
|
ptw32_mcs_lock_release (&stateLock); |
||||
|
return ESRCH; |
||||
|
} |
||||
|
else if (status != WAIT_TIMEOUT) |
||||
|
{ |
||||
|
return EINVAL; |
||||
|
} |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
Sleep (wait_time); |
||||
|
} |
||||
|
|
||||
|
return (0); |
||||
|
} |
@ -0,0 +1,136 @@ |
|||||
|
/*
|
||||
|
* pthread_detach.c |
||||
|
* |
||||
|
* Description: |
||||
|
* This translation unit implements functions related to thread |
||||
|
* synchronisation. |
||||
|
* |
||||
|
* -------------------------------------------------------------------------- |
||||
|
* |
||||
|
* 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 |
||||
|
*/ |
||||
|
|
||||
|
#include "pthread.h" |
||||
|
#include "implement.h" |
||||
|
|
||||
|
/*
|
||||
|
* Not needed yet, but defining it should indicate clashes with build target |
||||
|
* environment that should be fixed. |
||||
|
*/ |
||||
|
#if !defined(WINCE) |
||||
|
# include <signal.h> |
||||
|
#endif |
||||
|
|
||||
|
|
||||
|
int |
||||
|
pthread_detach (pthread_t thread) |
||||
|
/*
|
||||
|
* ------------------------------------------------------ |
||||
|
* DOCPUBLIC |
||||
|
* This function detaches the given thread. |
||||
|
* |
||||
|
* PARAMETERS |
||||
|
* thread |
||||
|
* an instance of a pthread_t |
||||
|
* |
||||
|
* |
||||
|
* DESCRIPTION |
||||
|
* This function detaches the given thread. You may use it to |
||||
|
* detach the main thread or to detach a joinable thread. |
||||
|
* NOTE: detached threads cannot be joined; |
||||
|
* storage is freed immediately on termination. |
||||
|
* |
||||
|
* RESULTS |
||||
|
* 0 successfully detached the thread, |
||||
|
* EINVAL thread is not a joinable thread, |
||||
|
* ENOSPC a required resource has been exhausted, |
||||
|
* ESRCH no thread could be found for 'thread', |
||||
|
* |
||||
|
* ------------------------------------------------------ |
||||
|
*/ |
||||
|
{ |
||||
|
int result; |
||||
|
BOOL destroyIt = PTW32_FALSE; |
||||
|
ptw32_thread_t * tp = (ptw32_thread_t *) thread.p; |
||||
|
ptw32_mcs_local_node_t node; |
||||
|
|
||||
|
ptw32_mcs_lock_acquire(&ptw32_thread_reuse_lock, &node); |
||||
|
|
||||
|
if (NULL == tp |
||||
|
|| thread.x != tp->ptHandle.x) |
||||
|
{ |
||||
|
result = ESRCH; |
||||
|
} |
||||
|
else if (PTHREAD_CREATE_DETACHED == tp->detachState) |
||||
|
{ |
||||
|
result = EINVAL; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
ptw32_mcs_local_node_t stateLock; |
||||
|
/*
|
||||
|
* Joinable ptw32_thread_t structs are not scavenged until |
||||
|
* a join or detach is done. The thread may have exited already, |
||||
|
* but all of the state and locks etc are still there. |
||||
|
*/ |
||||
|
result = 0; |
||||
|
|
||||
|
ptw32_mcs_lock_acquire (&tp->stateLock, &stateLock); |
||||
|
if (tp->state != PThreadStateLast) |
||||
|
{ |
||||
|
tp->detachState = PTHREAD_CREATE_DETACHED; |
||||
|
} |
||||
|
else if (tp->detachState != PTHREAD_CREATE_DETACHED) |
||||
|
{ |
||||
|
/*
|
||||
|
* Thread is joinable and has exited or is exiting. |
||||
|
*/ |
||||
|
destroyIt = PTW32_TRUE; |
||||
|
} |
||||
|
ptw32_mcs_lock_release (&stateLock); |
||||
|
} |
||||
|
|
||||
|
ptw32_mcs_lock_release(&node); |
||||
|
|
||||
|
if (result == 0) |
||||
|
{ |
||||
|
/* Thread is joinable */ |
||||
|
|
||||
|
if (destroyIt) |
||||
|
{ |
||||
|
/* The thread has exited or is exiting but has not been joined or
|
||||
|
* detached. Need to wait in case it's still exiting. |
||||
|
*/ |
||||
|
(void) WaitForSingleObject(tp->threadH, INFINITE); |
||||
|
ptw32_threadDestroy (thread); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return (result); |
||||
|
|
||||
|
} /* pthread_detach */ |
@ -0,0 +1,76 @@ |
|||||
|
/*
|
||||
|
* pthread_equal.c |
||||
|
* |
||||
|
* Description: |
||||
|
* This translation unit implements miscellaneous thread functions. |
||||
|
* |
||||
|
* -------------------------------------------------------------------------- |
||||
|
* |
||||
|
* 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 |
||||
|
*/ |
||||
|
|
||||
|
#include "pthread.h" |
||||
|
#include "implement.h" |
||||
|
|
||||
|
|
||||
|
int |
||||
|
pthread_equal (pthread_t t1, pthread_t t2) |
||||
|
/*
|
||||
|
* ------------------------------------------------------ |
||||
|
* DOCPUBLIC |
||||
|
* This function returns nonzero if t1 and t2 are equal, else |
||||
|
* returns zero |
||||
|
* |
||||
|
* PARAMETERS |
||||
|
* t1, |
||||
|
* t2 |
||||
|
* thread IDs |
||||
|
* |
||||
|
* |
||||
|
* DESCRIPTION |
||||
|
* This function returns nonzero if t1 and t2 are equal, else |
||||
|
* returns zero. |
||||
|
* |
||||
|
* RESULTS |
||||
|
* non-zero if t1 and t2 refer to the same thread, |
||||
|
* 0 t1 and t2 do not refer to the same thread |
||||
|
* |
||||
|
* ------------------------------------------------------ |
||||
|
*/ |
||||
|
{ |
||||
|
int result; |
||||
|
|
||||
|
/*
|
||||
|
* We also accept NULL == NULL - treating NULL as a thread |
||||
|
* for this special case, because there is no error that we can return. |
||||
|
*/ |
||||
|
result = ( t1.p == t2.p && t1.x == t2.x ); |
||||
|
|
||||
|
return (result); |
||||
|
|
||||
|
} /* pthread_equal */ |
@ -0,0 +1,106 @@ |
|||||
|
/*
|
||||
|
* pthread_exit.c |
||||
|
* |
||||
|
* Description: |
||||
|
* This translation unit implements routines associated with exiting from |
||||
|
* a thread. |
||||
|
* |
||||
|
* -------------------------------------------------------------------------- |
||||
|
* |
||||
|
* 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 |
||||
|
*/ |
||||
|
|
||||
|
#include "pthread.h" |
||||
|
#include "implement.h" |
||||
|
#if !defined(_UWIN) |
||||
|
/*# include <process.h> */ |
||||
|
#endif |
||||
|
|
||||
|
void |
||||
|
pthread_exit (void *value_ptr) |
||||
|
/*
|
||||
|
* ------------------------------------------------------ |
||||
|
* DOCPUBLIC |
||||
|
* This function terminates the calling thread, returning |
||||
|
* the value 'value_ptr' to any joining thread. |
||||
|
* |
||||
|
* PARAMETERS |
||||
|
* value_ptr |
||||
|
* a generic data value (i.e. not the address of a value) |
||||
|
* |
||||
|
* |
||||
|
* DESCRIPTION |
||||
|
* This function terminates the calling thread, returning |
||||
|
* the value 'value_ptr' to any joining thread. |
||||
|
* NOTE: thread should be joinable. |
||||
|
* |
||||
|
* RESULTS |
||||
|
* N/A |
||||
|
* |
||||
|
* ------------------------------------------------------ |
||||
|
*/ |
||||
|
{ |
||||
|
ptw32_thread_t * sp; |
||||
|
|
||||
|
/*
|
||||
|
* Don't use pthread_self() to avoid creating an implicit POSIX thread handle |
||||
|
* unnecessarily. |
||||
|
*/ |
||||
|
sp = (ptw32_thread_t *) pthread_getspecific (ptw32_selfThreadKey); |
||||
|
|
||||
|
#if defined(_UWIN) |
||||
|
if (--pthread_count <= 0) |
||||
|
exit ((int) value_ptr); |
||||
|
#endif |
||||
|
|
||||
|
if (NULL == sp) |
||||
|
{ |
||||
|
/*
|
||||
|
* A POSIX thread handle was never created. I.e. this is a |
||||
|
* Win32 thread that has never called a pthreads-win32 routine that |
||||
|
* required a POSIX handle. |
||||
|
* |
||||
|
* Implicit POSIX handles are cleaned up in ptw32_throw() now. |
||||
|
*/ |
||||
|
|
||||
|
#if ! (defined (__MINGW64__) || defined(__MINGW32__)) || defined (__MSVCRT__) || defined (__DMC__) |
||||
|
_endthreadex ((unsigned) (size_t) value_ptr); |
||||
|
#else |
||||
|
_endthread (); |
||||
|
#endif |
||||
|
|
||||
|
/* Never reached */ |
||||
|
} |
||||
|
|
||||
|
sp->exitStatus = value_ptr; |
||||
|
|
||||
|
ptw32_throw (PTW32_EPS_EXIT); |
||||
|
|
||||
|
/* Never reached. */ |
||||
|
|
||||
|
} |
@ -0,0 +1,45 @@ |
|||||
|
/*
|
||||
|
* pthread_getconcurrency.c |
||||
|
* |
||||
|
* Description: |
||||
|
* This translation unit implements miscellaneous thread functions. |
||||
|
* |
||||
|
* -------------------------------------------------------------------------- |
||||
|
* |
||||
|
* 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 |
||||
|
*/ |
||||
|
|
||||
|
#include "pthread.h" |
||||
|
#include "implement.h" |
||||
|
|
||||
|
|
||||
|
int |
||||
|
pthread_getconcurrency (void) |
||||
|
{ |
||||
|
return ptw32_concurrency; |
||||
|
} |
@ -0,0 +1,75 @@ |
|||||
|
/*
|
||||
|
* sched_getschedparam.c |
||||
|
* |
||||
|
* Description: |
||||
|
* POSIX thread functions that deal with thread scheduling. |
||||
|
* |
||||
|
* -------------------------------------------------------------------------- |
||||
|
* |
||||
|
* 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 |
||||
|
*/ |
||||
|
|
||||
|
#include "pthread.h" |
||||
|
#include "implement.h" |
||||
|
#include "sched.h" |
||||
|
|
||||
|
int |
||||
|
pthread_getschedparam (pthread_t thread, int *policy, |
||||
|
struct sched_param *param) |
||||
|
{ |
||||
|
int result; |
||||
|
|
||||
|
/* Validate the thread id. */ |
||||
|
result = pthread_kill (thread, 0); |
||||
|
if (0 != result) |
||||
|
{ |
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
/*
|
||||
|
* Validate the policy and param args. |
||||
|
* Check that a policy constant wasn't passed rather than &policy. |
||||
|
*/ |
||||
|
if (policy <= (int *) SCHED_MAX || param == NULL) |
||||
|
{ |
||||
|
return EINVAL; |
||||
|
} |
||||
|
|
||||
|
/* Fill out the policy. */ |
||||
|
*policy = SCHED_OTHER; |
||||
|
|
||||
|
/*
|
||||
|
* This function must return the priority value set by |
||||
|
* the most recent pthread_setschedparam() or pthread_create() |
||||
|
* for the target thread. It must not return the actual thread |
||||
|
* priority as altered by any system priority adjustments etc. |
||||
|
*/ |
||||
|
param->sched_priority = ((ptw32_thread_t *)thread.p)->sched_priority; |
||||
|
|
||||
|
return 0; |
||||
|
} |
@ -0,0 +1,87 @@ |
|||||
|
/*
|
||||
|
* pthread_getspecific.c |
||||
|
* |
||||
|
* Description: |
||||
|
* POSIX thread functions which implement thread-specific data (TSD). |
||||
|
* |
||||
|
* -------------------------------------------------------------------------- |
||||
|
* |
||||
|
* 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 |
||||
|
*/ |
||||
|
|
||||
|
#include "pthread.h" |
||||
|
#include "implement.h" |
||||
|
|
||||
|
|
||||
|
void * |
||||
|
pthread_getspecific (pthread_key_t key) |
||||
|
/*
|
||||
|
* ------------------------------------------------------ |
||||
|
* DOCPUBLIC |
||||
|
* This function returns the current value of key in the |
||||
|
* calling thread. If no value has been set for 'key' in |
||||
|
* the thread, NULL is returned. |
||||
|
* |
||||
|
* PARAMETERS |
||||
|
* key |
||||
|
* an instance of pthread_key_t |
||||
|
* |
||||
|
* |
||||
|
* DESCRIPTION |
||||
|
* This function returns the current value of key in the |
||||
|
* calling thread. If no value has been set for 'key' in |
||||
|
* the thread, NULL is returned. |
||||
|
* |
||||
|
* RESULTS |
||||
|
* key value or NULL on failure |
||||
|
* |
||||
|
* ------------------------------------------------------ |
||||
|
*/ |
||||
|
{ |
||||
|
void * ptr; |
||||
|
|
||||
|
if (key == NULL) |
||||
|
{ |
||||
|
ptr = NULL; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
int lasterror = GetLastError (); |
||||
|
#if defined(RETAIN_WSALASTERROR) |
||||
|
int lastWSAerror = WSAGetLastError (); |
||||
|
#endif |
||||
|
ptr = TlsGetValue (key->key); |
||||
|
|
||||
|
SetLastError (lasterror); |
||||
|
#if defined(RETAIN_WSALASTERROR) |
||||
|
WSASetLastError (lastWSAerror); |
||||
|
#endif |
||||
|
} |
||||
|
|
||||
|
return ptr; |
||||
|
} |
@ -0,0 +1,47 @@ |
|||||
|
/*
|
||||
|
* pthread_getunique_np.c |
||||
|
* |
||||
|
* Description: |
||||
|
* This translation unit implements non-portable thread functions. |
||||
|
* |
||||
|
* -------------------------------------------------------------------------- |
||||
|
* |
||||
|
* 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 |
||||
|
*/ |
||||
|
|
||||
|
#include "pthread.h" |
||||
|
#include "implement.h" |
||||
|
|
||||
|
/*
|
||||
|
* |
||||
|
*/ |
||||
|
unsigned __int64 |
||||
|
pthread_getunique_np (pthread_t thread) |
||||
|
{ |
||||
|
return ((ptw32_thread_t*)thread.p)->seqNumber; |
||||
|
} |
@ -0,0 +1,65 @@ |
|||||
|
/*
|
||||
|
* pthread_getw32threadhandle_np.c |
||||
|
* |
||||
|
* Description: |
||||
|
* This translation unit implements non-portable thread functions. |
||||
|
* |
||||
|
* -------------------------------------------------------------------------- |
||||
|
* |
||||
|
* 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 |
||||
|
*/ |
||||
|
|
||||
|
#include "pthread.h" |
||||
|
#include "implement.h" |
||||
|
|
||||
|
/*
|
||||
|
* pthread_getw32threadhandle_np() |
||||
|
* |
||||
|
* Returns the win32 thread handle that the POSIX |
||||
|
* thread "thread" is running as. |
||||
|
* |
||||
|
* Applications can use the win32 handle to set |
||||
|
* win32 specific attributes of the thread. |
||||
|
*/ |
||||
|
HANDLE |
||||
|
pthread_getw32threadhandle_np (pthread_t thread) |
||||
|
{ |
||||
|
return ((ptw32_thread_t *)thread.p)->threadH; |
||||
|
} |
||||
|
|
||||
|
/*
|
||||
|
* pthread_getw32threadid_np() |
||||
|
* |
||||
|
* Returns the win32 thread id that the POSIX |
||||
|
* thread "thread" is running as. |
||||
|
*/ |
||||
|
DWORD |
||||
|
pthread_getw32threadid_np (pthread_t thread) |
||||
|
{ |
||||
|
return ((ptw32_thread_t *)thread.p)->thread; |
||||
|
} |
@ -0,0 +1,157 @@ |
|||||
|
/*
|
||||
|
* pthread_join.c |
||||
|
* |
||||
|
* Description: |
||||
|
* This translation unit implements functions related to thread |
||||
|
* synchronisation. |
||||
|
* |
||||
|
* -------------------------------------------------------------------------- |
||||
|
* |
||||
|
* 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 |
||||
|
*/ |
||||
|
|
||||
|
#include "pthread.h" |
||||
|
#include "implement.h" |
||||
|
|
||||
|
/*
|
||||
|
* Not needed yet, but defining it should indicate clashes with build target |
||||
|
* environment that should be fixed. |
||||
|
*/ |
||||
|
#if !defined(WINCE) |
||||
|
# include <signal.h> |
||||
|
#endif |
||||
|
|
||||
|
|
||||
|
int |
||||
|
pthread_join (pthread_t thread, void **value_ptr) |
||||
|
/*
|
||||
|
* ------------------------------------------------------ |
||||
|
* DOCPUBLIC |
||||
|
* This function waits for 'thread' to terminate and |
||||
|
* returns the thread's exit value if 'value_ptr' is not |
||||
|
* NULL. This also detaches the thread on successful |
||||
|
* completion. |
||||
|
* |
||||
|
* PARAMETERS |
||||
|
* thread |
||||
|
* an instance of pthread_t |
||||
|
* |
||||
|
* value_ptr |
||||
|
* pointer to an instance of pointer to void |
||||
|
* |
||||
|
* |
||||
|
* DESCRIPTION |
||||
|
* This function waits for 'thread' to terminate and |
||||
|
* returns the thread's exit value if 'value_ptr' is not |
||||
|
* NULL. This also detaches the thread on successful |
||||
|
* completion. |
||||
|
* NOTE: detached threads cannot be joined or canceled |
||||
|
* |
||||
|
* RESULTS |
||||
|
* 0 'thread' has completed |
||||
|
* EINVAL thread is not a joinable thread, |
||||
|
* ESRCH no thread could be found with ID 'thread', |
||||
|
* ENOENT thread couldn't find it's own valid handle, |
||||
|
* EDEADLK attempt to join thread with self |
||||
|
* |
||||
|
* ------------------------------------------------------ |
||||
|
*/ |
||||
|
{ |
||||
|
int result; |
||||
|
pthread_t self; |
||||
|
ptw32_thread_t * tp = (ptw32_thread_t *) thread.p; |
||||
|
ptw32_mcs_local_node_t node; |
||||
|
|
||||
|
ptw32_mcs_lock_acquire(&ptw32_thread_reuse_lock, &node); |
||||
|
|
||||
|
if (NULL == tp |
||||
|
|| thread.x != tp->ptHandle.x) |
||||
|
{ |
||||
|
result = ESRCH; |
||||
|
} |
||||
|
else if (PTHREAD_CREATE_DETACHED == tp->detachState) |
||||
|
{ |
||||
|
result = EINVAL; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
result = 0; |
||||
|
} |
||||
|
|
||||
|
ptw32_mcs_lock_release(&node); |
||||
|
|
||||
|
if (result == 0) |
||||
|
{ |
||||
|
/*
|
||||
|
* The target thread is joinable and can't be reused before we join it. |
||||
|
*/ |
||||
|
self = pthread_self(); |
||||
|
|
||||
|
if (NULL == self.p) |
||||
|
{ |
||||
|
result = ENOENT; |
||||
|
} |
||||
|
else if (pthread_equal (self, thread)) |
||||
|
{ |
||||
|
result = EDEADLK; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
/*
|
||||
|
* Pthread_join is a cancelation point. |
||||
|
* If we are canceled then our target thread must not be |
||||
|
* detached (destroyed). This is guarranteed because |
||||
|
* pthreadCancelableWait will not return if we |
||||
|
* are canceled. |
||||
|
*/ |
||||
|
result = pthreadCancelableWait (tp->threadH); |
||||
|
|
||||
|
if (0 == result) |
||||
|
{ |
||||
|
if (value_ptr != NULL) |
||||
|
{ |
||||
|
*value_ptr = tp->exitStatus; |
||||
|
} |
||||
|
|
||||
|
/*
|
||||
|
* The result of making multiple simultaneous calls to |
||||
|
* pthread_join() or pthread_detach() specifying the same |
||||
|
* target is undefined. |
||||
|
*/ |
||||
|
result = pthread_detach (thread); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
result = ESRCH; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return (result); |
||||
|
|
||||
|
} /* pthread_join */ |
@ -0,0 +1,108 @@ |
|||||
|
/*
|
||||
|
* pthread_key_create.c |
||||
|
* |
||||
|
* Description: |
||||
|
* POSIX thread functions which implement thread-specific data (TSD). |
||||
|
* |
||||
|
* -------------------------------------------------------------------------- |
||||
|
* |
||||
|
* 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 |
||||
|
*/ |
||||
|
|
||||
|
#include "pthread.h" |
||||
|
#include "implement.h" |
||||
|
|
||||
|
|
||||
|
/* TLS_OUT_OF_INDEXES not defined on WinCE */ |
||||
|
#if !defined(TLS_OUT_OF_INDEXES) |
||||
|
#define TLS_OUT_OF_INDEXES 0xffffffff |
||||
|
#endif |
||||
|
|
||||
|
int |
||||
|
pthread_key_create (pthread_key_t * key, void (*destructor) (void *)) |
||||
|
/*
|
||||
|
* ------------------------------------------------------ |
||||
|
* DOCPUBLIC |
||||
|
* This function creates a thread-specific data key visible |
||||
|
* to all threads. All existing and new threads have a value |
||||
|
* NULL for key until set using pthread_setspecific. When any |
||||
|
* thread with a non-NULL value for key terminates, 'destructor' |
||||
|
* is called with key's current value for that thread. |
||||
|
* |
||||
|
* PARAMETERS |
||||
|
* key |
||||
|
* pointer to an instance of pthread_key_t |
||||
|
* |
||||
|
* |
||||
|
* DESCRIPTION |
||||
|
* This function creates a thread-specific data key visible |
||||
|
* to all threads. All existing and new threads have a value |
||||
|
* NULL for key until set using pthread_setspecific. When any |
||||
|
* thread with a non-NULL value for key terminates, 'destructor' |
||||
|
* is called with key's current value for that thread. |
||||
|
* |
||||
|
* RESULTS |
||||
|
* 0 successfully created semaphore, |
||||
|
* EAGAIN insufficient resources or PTHREAD_KEYS_MAX |
||||
|
* exceeded, |
||||
|
* ENOMEM insufficient memory to create the key, |
||||
|
* |
||||
|
* ------------------------------------------------------ |
||||
|
*/ |
||||
|
{ |
||||
|
int result = 0; |
||||
|
pthread_key_t newkey; |
||||
|
|
||||
|
if ((newkey = (pthread_key_t) calloc (1, sizeof (*newkey))) == NULL) |
||||
|
{ |
||||
|
result = ENOMEM; |
||||
|
} |
||||
|
else if ((newkey->key = TlsAlloc ()) == TLS_OUT_OF_INDEXES) |
||||
|
{ |
||||
|
result = EAGAIN; |
||||
|
|
||||
|
free (newkey); |
||||
|
newkey = NULL; |
||||
|
} |
||||
|
else if (destructor != NULL) |
||||
|
{ |
||||
|
/*
|
||||
|
* Have to manage associations between thread and key; |
||||
|
* Therefore, need a lock that allows competing threads |
||||
|
* to gain exclusive access to the key->threads list. |
||||
|
* |
||||
|
* The mutex will only be created when it is first locked. |
||||
|
*/ |
||||
|
newkey->keyLock = 0; |
||||
|
newkey->destructor = destructor; |
||||
|
} |
||||
|
|
||||
|
*key = newkey; |
||||
|
|
||||
|
return (result); |
||||
|
} |
@ -0,0 +1,125 @@ |
|||||
|
/*
|
||||
|
* pthread_key_delete.c |
||||
|
* |
||||
|
* Description: |
||||
|
* POSIX thread functions which implement thread-specific data (TSD). |
||||
|
* |
||||
|
* -------------------------------------------------------------------------- |
||||
|
* |
||||
|
* 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 |
||||
|
*/ |
||||
|
|
||||
|
#include "pthread.h" |
||||
|
#include "implement.h" |
||||
|
|
||||
|
|
||||
|
int |
||||
|
pthread_key_delete (pthread_key_t key) |
||||
|
/*
|
||||
|
* ------------------------------------------------------ |
||||
|
* DOCPUBLIC |
||||
|
* This function deletes a thread-specific data key. This |
||||
|
* does not change the value of the thread specific data key |
||||
|
* for any thread and does not run the key's destructor |
||||
|
* in any thread so it should be used with caution. |
||||
|
* |
||||
|
* PARAMETERS |
||||
|
* key |
||||
|
* pointer to an instance of pthread_key_t |
||||
|
* |
||||
|
* |
||||
|
* DESCRIPTION |
||||
|
* This function deletes a thread-specific data key. This |
||||
|
* does not change the value of the thread specific data key |
||||
|
* for any thread and does not run the key's destructor |
||||
|
* in any thread so it should be used with caution. |
||||
|
* |
||||
|
* RESULTS |
||||
|
* 0 successfully deleted the key, |
||||
|
* EINVAL key is invalid, |
||||
|
* |
||||
|
* ------------------------------------------------------ |
||||
|
*/ |
||||
|
{ |
||||
|
ptw32_mcs_local_node_t keyLock; |
||||
|
int result = 0; |
||||
|
|
||||
|
if (key != NULL) |
||||
|
{ |
||||
|
if (key->threads != NULL && key->destructor != NULL) |
||||
|
{ |
||||
|
ThreadKeyAssoc *assoc; |
||||
|
ptw32_mcs_lock_acquire (&(key->keyLock), &keyLock); |
||||
|
/*
|
||||
|
* Run through all Thread<-->Key associations |
||||
|
* for this key. |
||||
|
* |
||||
|
* While we hold at least one of the locks guarding |
||||
|
* the assoc, we know that the assoc pointed to by |
||||
|
* key->threads is valid. |
||||
|
*/ |
||||
|
while ((assoc = (ThreadKeyAssoc *) key->threads) != NULL) |
||||
|
{ |
||||
|
ptw32_mcs_local_node_t threadLock; |
||||
|
ptw32_thread_t * thread = assoc->thread; |
||||
|
|
||||
|
if (assoc == NULL) |
||||
|
{ |
||||
|
/* Finished */ |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
ptw32_mcs_lock_acquire (&(thread->threadLock), &threadLock); |
||||
|
/*
|
||||
|
* Since we are starting at the head of the key's threads |
||||
|
* chain, this will also point key->threads at the next assoc. |
||||
|
* While we hold key->keyLock, no other thread can insert |
||||
|
* a new assoc via pthread_setspecific. |
||||
|
*/ |
||||
|
ptw32_tkAssocDestroy (assoc); |
||||
|
ptw32_mcs_lock_release (&threadLock); |
||||
|
ptw32_mcs_lock_release (&keyLock); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
TlsFree (key->key); |
||||
|
if (key->destructor != NULL) |
||||
|
{ |
||||
|
/* A thread could be holding the keyLock */ |
||||
|
ptw32_mcs_lock_acquire (&(key->keyLock), &keyLock); |
||||
|
ptw32_mcs_lock_release (&keyLock); |
||||
|
} |
||||
|
|
||||
|
#if defined( _DEBUG ) |
||||
|
memset ((char *) key, 0, sizeof (*key)); |
||||
|
#endif |
||||
|
free (key); |
||||
|
} |
||||
|
|
||||
|
return (result); |
||||
|
} |
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue