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