2 This source code file is part of thread_mpi.
3 Written by Sander Pronk, Erik Lindahl, and possibly others.
5 Copyright (c) 2009, Sander Pronk, Erik Lindahl.
8 Redistribution and use in source and binary forms, with or without
9 modification, are permitted provided that the following conditions are met:
10 1) Redistributions of source code must retain the above copyright
11 notice, this list of conditions and the following disclaimer.
12 2) Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
15 3) Neither the name of the copyright holders nor the
16 names of its contributors may be used to endorse or promote products
17 derived from this software without specific prior written permission.
19 THIS SOFTWARE IS PROVIDED BY US ''AS IS'' AND ANY
20 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 DISCLAIMED. IN NO EVENT SHALL WE BE LIABLE FOR ANY
23 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 If you want to redistribute modifications, please consider that
31 scientific software is very special. Version control is crucial -
32 bugs must be traceable. We will be happy to consider code for
33 inclusion in the official distribution, but derived work should not
34 be called official thread_mpi. Details are found in the README & COPYING
40 /*! \file winthreads.h
42 * @brief Windows threads specific data structures
44 * For use of Windows threads in thread_mpi/threads.h
46 * \sa thread_mpi/threads.h for documentation.
52 /* we need this for all the data types. We use WIN32_LEAN_AND_MEAN to avoid
53 polluting the global namespace. */
54 #define WIN32_LEAN_AND_MEAN
56 #undef WIN32_LEAN_AND_MEAN
59 /*! \brief Status for one-time initialization of thread stuff.
63 * This is used both for the static initialization, and as
64 * a safeguard to catch errors where the user
65 * is sloppy and fails to initialize various things in the
66 * thread system. It is only defined here to enable static
67 * initialization - don't use it outside the thread code.
69 enum tMPI_Thread_once_status
71 TMPI_THREAD_ONCE_STATUS_NOTCALLED
= 0, /*!< Not yet initialized */
72 TMPI_THREAD_ONCE_STATUS_PROGRESS
= 1, /*!< Somebody working on it */
73 TMPI_THREAD_ONCE_STATUS_READY
= 2 /*!< Everything completed */
80 /*! \brief win32 implementation of the abstract tMPI_Thread type
82 * The contents of this structure depends on the actual threads
83 * implementation used.
85 typedef HANDLE tMPI_Thread_t
;
88 /*! \brief Opaque mutex datatype
90 * This type is only defined in the header to enable static
91 * initialization with TMPI_THREAD_MUTEX_INITIALIZER.
92 * You should _never_ touch the contents or create a variable
93 * with automatic storage class without calling tMPI_Thread_mutex_init().
97 volatile enum tMPI_Thread_once_status init_state
;
99 } tMPI_Thread_mutex_t
;
100 /*! \brief Static initializer for tMPI_Thread_mutex_t
102 * See the description of the tMPI_Thread_mutex_t datatype for instructions
103 * on how to use this. Note that any variables initialized with this value
104 * MUST have static storage allocation.
106 #define TMPI_THREAD_MUTEX_INITIALIZER { TMPI_THREAD_ONCE_STATUS_NOTCALLED }
109 /*! \brief Pthread implementation of the abstract tMPI_Thread_key type
111 * The contents of this structure depends on the actual threads
112 * implementation used. */
113 typedef DWORD tMPI_Thread_key_t
;
116 /*! \brief One-time initialization data for thread
118 * This is an opaque datatype which is necessary for tMPI_Thread_once(),
119 * but since it needs to be initialized statically it must be defined
120 * in the header. You will be sorry if you touch the contents.
121 * Variables of this type should always be initialized statically to
122 * TMPI_THREAD_ONCE_INIT.
124 * This type is used as control data for single-time initialization.
125 * The most common example is a mutex at file scope used when calling
126 * a non-threadsafe function, e.g. the FFTW initialization routines.
130 /* use this once Vista is the oldest supported Windows version: */
131 typedef INIT_ONCE tMPI_Thread_once_t
;
133 typedef volatile int tMPI_Thread_once_t
;
135 /*! \brief Static initializer for tMPI_Thread_once_t
137 * See the description of the tMPI_Thread_once_t datatype for instructions
138 * on how to use this. Normally, all variables of that type should be
139 * initialized statically to this value.
141 #define TMPI_THREAD_ONCE_INIT 0
144 /*! \brief Condition variable handle for threads
146 * Condition variables are useful for synchronization together
147 * with a mutex: Lock the mutex and check if our thread is the last
148 * to the barrier. If no, wait for the condition to be signaled.
149 * If yes, reset whatever data you want and then signal the condition.
151 * This should be considered an opaque structure, but since it is sometimes
152 * useful to initialize it statically it must go in the header.
153 * You will be sorry if you touch the contents.
155 * There are two alternatives: Either initialize it as a static variable
156 * with TMPI_THREAD_COND_INITIALIZER, or call tMPI_Thread_cond_init()
161 volatile enum tMPI_Thread_once_status init_state
;
165 /* this works since Windows Vista: */
166 CONDITION_VARIABLE cv
;
168 /* this data structure and its algorithms are based on
169 'Strategies for Implementing POSIX Condition Variables on Win32'
171 Douglas C. Schmidt and Irfan Pyarali
172 Department of Computer Science
173 Washington University, St. Louis, Missouri
174 http://www.cs.wustl.edu/~schmidt/win32-cv-1.html */
175 int Nwaiters
; /* number of waiting threads */
176 CRITICAL_SECTION wtr_lock
; /* lock for Nwaiters */
177 int Nrelease
; /* number of threads to release in broadcast/signal */
178 int cycle
; /* cycle number so threads can't steal signals */
179 HANDLE ev
; /* the event used to trigger WaitForSingleObject.
180 Is a manual reset event. */
182 } tMPI_Thread_cond_t
;
184 /*typedef pthread_cond_t tMPI_Thread_cond_t;*/
187 /*! \brief Static initializer for tMPI_Thread_cond_t
189 * See the description of the tMPI_Thread_cond_t datatype for instructions
190 * on how to use this. Note that any variables initialized with this value
191 * MUST have static storage allocation.
193 #define TMPI_THREAD_COND_INITIALIZER { TMPI_THREAD_ONCE_STATUS_NOTCALLED }
198 /*! \brief Read-write lock for threads
200 Windows implementation of the read-write lock (a lock that allows
201 multiple readers, but only a single writer).
203 typedef SRWLOCK tMPI_Thread_rwlock_t
;
206 /*! \brief Pthread implementation of barrier type.
208 * The contents of this structure depends on the actual threads
209 * implementation used.
211 typedef struct tMPI_Thread_pthread_barrier
213 volatile enum tMPI_Thread_once_status init_state
;
214 int init_threshold
; /* < N */
215 int threshold
; /*!< Total number of members in barrier */
216 int count
; /*!< Remaining count before completion */
217 int cycle
; /*!< Alternating 0/1 to indicate round */
220 /* use this once Vista is the oldest supported windows version: */
221 CRITICAL_SECTION cs
; /*!< Lock for the barrier contents */
222 CONDITION_VARIABLE cv
; /*!< Condition to signal barrier completion */
224 tMPI_Thread_mutex_t cs
; /*!< Lock for the barrier contents */
225 tMPI_Thread_cond_t cv
; /*!< Condition to signal barrier completion */
227 }tMPI_Thread_barrier_t
;
229 /*! \brief Static initializer for tMPI_Thread_barrier_t
231 * See the description of the tMPI_Thread_barrier_t datatype for instructions
232 * on how to use this. Note that variables initialized with this value
233 * MUST have static storage allocation.
235 * \param count Threshold for barrier
237 #define TMPI_THREAD_BARRIER_INITIALIZER(count) { \
238 TMPI_THREAD_ONCE_STATUS_NOTCALLED, \