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
37 To help us fund development, we humbly ask that you cite
38 any papers on the package - you can find them in the top README file.
44 /*! \file tmpi_thread.h
46 * @brief Windows threads specific data structures
51 /* we need this for all the data types. We use WIN32_LEAN_AND_MEAN to avoid
52 polluting the global namespace. */
53 #define WIN32_LEAN_AND_MEAN
55 #undef WIN32_LEAN_AND_MEAN
57 /*! \brief Status for one-time initialization of thread stuff.
61 * This is used both for the static initialization, and as
62 * a safeguard to catch errors where the user
63 * is sloppy and fails to initialize various things in the
64 * thread system. It is only defined here to enable static
65 * initialization - don't use it outside the thread code.
67 enum tMPI_Thread_once_status
69 TMPI_THREAD_ONCE_STATUS_NOTCALLED = 0, /*!< Not yet initialized */
70 TMPI_THREAD_ONCE_STATUS_PROGRESS = 1, /*!< Somebody working on it */
71 TMPI_THREAD_ONCE_STATUS_READY = 2 /*!< Everything completed */
78 /*! \brief win32 implementation of the abstract tMPI_Thread type
80 * The contents of this structure depends on the actual threads
81 * implementation used.
83 typedef HANDLE tMPI_Thread_t;
86 /*! \brief Opaque mutex datatype
88 * This type is only defined in the header to enable static
89 * initialization with TMPI_THREAD_MUTEX_INITIALIZER.
90 * You should _never_ touch the contents or create a variable
91 * with automatic storage class without calling tMPI_Thread_mutex_init().
95 volatile enum tMPI_Thread_once_status init_state;
97 } tMPI_Thread_mutex_t;
98 /*! \brief Statical initializer for tMPI_Thread_mutex_t
100 * See the description of the tMPI_Thread_mutex_t datatype for instructions
101 * on how to use this. Note that any variables initialized with this value
102 * MUST have static storage allocation.
104 #define TMPI_THREAD_MUTEX_INITIALIZER { TMPI_THREAD_ONCE_STATUS_NOTCALLED }
107 /*! \brief Pthread implementation of the abstract tMPI_Thread_key type
109 * The contents of this structure depends on the actual threads
110 * implementation used. */
111 typedef DWORD tMPI_Thread_key_t;
114 /*! \brief One-time initialization data for thread
116 * This is an opaque datatype which is necessary for tMPI_Thread_once(),
117 * but since it needs to be initialized statically it must be defined
118 * in the header. You will be sorry if you touch the contents.
119 * Variables of this type should always be initialized statically to
120 * TMPI_THREAD_ONCE_INIT.
122 * This type is used as control data for single-time initialization.
123 * The most common example is a mutex at file scope used when calling
124 * a non-threadsafe function, e.g. the FFTW initialization routines.
127 typedef INIT_ONCE tMPI_Thread_once_t;
128 /*! \brief Statical initializer for tMPI_Thread_once_t
130 * See the description of the tMPI_Thread_once_t datatype for instructions
131 * on how to use this. Normally, all variables of that type should be
132 * initialized statically to this value.
134 #define TMPI_THREAD_ONCE_INIT NULL
137 /*! \brief Condition variable handle for threads
139 * Condition variables are useful for synchronization together
140 * with a mutex: Lock the mutex and check if our thread is the last
141 * to the barrier. If no, wait for the condition to be signaled.
142 * If yes, reset whatever data you want and then signal the condition.
144 * This should be considered an opaque structure, but since it is sometimes
145 * useful to initialize it statically it must go in the header.
146 * You will be sorry if you touch the contents.
148 * There are two alternatives: Either initialize it as a static variable
149 * with TMPI_THREAD_COND_INITIALIZER, or call tMPI_Thread_cond_init()
154 volatile enum tMPI_Thread_once_status init_state;
155 CONDITION_VARIABLE cv;
156 } tMPI_Thread_cond_t;
158 /*typedef pthread_cond_t tMPI_Thread_cond_t;*/
161 /*! \brief Statical initializer for tMPI_Thread_cond_t
163 * See the description of the tMPI_Thread_cond_t datatype for instructions
164 * on how to use this. Note that any variables initialized with this value
165 * MUST have static storage allocation.
167 #define TMPI_THREAD_COND_INITIALIZER { TMPI_THREAD_ONCE_STATUS_NOTCALLED }
173 /*! \brief Pthread implementation of barrier type.
175 * The contents of this structure depends on the actual threads
176 * implementation used.
178 typedef struct tMPI_Thread_pthread_barrier
180 volatile enum tMPI_Thread_once_status init_state;
181 int init_threshold; /* < N */
182 int threshold; /*!< Total number of members in barrier */
183 int count; /*!< Remaining count before completion */
184 int cycle; /*!< Alternating 0/1 to indicate round */
185 CRITICAL_SECTION cs; /*!< Lock for the barrier contents */
186 CONDITION_VARIABLE cv; /*!< Condition to signal barrier completion */
187 }tMPI_Thread_barrier_t;
190 /*! \brief Statical initializer for tMPI_Thread_barrier_t
192 * See the description of the tMPI_Thread_barrier_t datatype for instructions
193 * on how to use this. Note that variables initialized with this value
194 * MUST have static storage allocation.
196 * \param count Threshold for barrier
198 #define TMPI_THREAD_BARRIER_INITIALIZER(count) { \
199 TMPI_THREAD_ONCE_STATUS_NOTCALLED, \