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
39 #ifndef TMPI_THREADS_H_
40 #define TMPI_THREADS_H_
44 * \brief Platform-independent multithreading support.
46 * This file provides an portable thread interface very similar to POSIX
47 * threads, as a thin wrapper around the threads provided operating system
48 * (whether they be POSIX threads or something else).
50 * In other words, while the naming conventions are very similar to
51 * pthreads, you should NOT assume that a thread_mpi thread type
52 * (thread,mutex,key, etc) is the same as the Pthreads equivalent,
53 * even on platforms where we are using pthreads.
55 * Because the synchronization functions here are similar to the basic
56 * mutexes/conditions/barriers provided by the operating system,
57 * performance will most likely be worse than when using the atomic
58 * synchronization functions of atomic.h. On the other hand, because the
59 * operating system can schedule out waiting threads using these functions,
60 * they are the appropriate ones for I/O and initialization.
62 * Since this module is merely intended to be a transparent wrapper around
63 * a system-dependent thread implementation, we simply echo errors to stderr.
64 * The user should check the return codes\] and take appropriate action
65 * when using these functions (fat chance, but errors are rare).
72 #include "visibility.h"
81 } /* Avoids screwing up auto-indentation */
88 /*! \brief Thread ID: abstract tMPI_Thread type
90 * The contents of this structure depends on the actual threads
91 * implementation used.
93 typedef struct tMPI_Thread* tMPI_Thread_t;
97 /*! \brief Opaque mutex datatype
99 * This type is only defined in the header to enable static
100 * initialization with TMPI_THREAD_MUTEX_INITIALIZER.
101 * You should _never_ touch the contents or create a variable
102 * with automatic storage class without calling tMPI_Thread_mutex_init().
106 tMPI_Atomic_t initialized; /*!< Whether \a mutex has been
108 struct tMPI_Mutex* mutex; /*!< Actual mutex data structure. */
109 } tMPI_Thread_mutex_t;
110 /*! \brief Static initializer for tMPI_Thread_mutex_t
112 * See the description of the tMPI_Thread_mutex_t datatype for instructions
113 * on how to use this. Note that any variables initialized with this value
114 * MUST have static storage allocation.
116 #define TMPI_THREAD_MUTEX_INITIALIZER { {0}, NULL }
122 /*! \brief Pthread implementation of the abstract tMPI_Thread_key type
124 * The contents of this structure depends on the actual threads
125 * implementation used.
129 tMPI_Atomic_t initialized; /*!< Whether \a key has been
131 struct tMPI_Thread_key *key; /*!< Actual key data structure. */
138 /*! \brief One-time initialization data for thread
140 * This is an opaque datatype which is necessary for tMPI_Thread_once(),
141 * but since it needs to be initialized statically it must be defined
142 * in the header. You will be sorry if you touch the contents.
143 * Variables of this type should always be initialized statically to
144 * TMPI_THREAD_ONCE_INIT.
146 * This type is used as control data for single-time initialization.
147 * The most common example is a mutex at file scope used when calling
148 * a non-threadsafe function, e.g. the FFTW initialization routines.
153 tMPI_Atomic_t once; /*!< Whether the operation has been performed. */
154 } tMPI_Thread_once_t;
155 /*! \brief Static initializer for tMPI_Thread_once_t
157 * See the description of the tMPI_Thread_once_t datatype for instructions
158 * on how to use this. Normally, all variables of that type should be
159 * initialized statically to this value.
161 #define TMPI_THREAD_ONCE_INIT { {0} }
166 /*! \brief Condition variable handle for threads
168 * Condition variables are useful for synchronization together
169 * with a mutex: Lock the mutex and check if our thread is the last
170 * to the barrier. If no, wait for the condition to be signaled.
171 * If yes, reset whatever data you want and then signal the condition.
173 * This should be considered an opaque structure, but since it is sometimes
174 * useful to initialize it statically it must go in the header.
175 * You will be sorry if you touch the contents.
177 * There are two alternatives: Either initialize it as a static variable
178 * with TMPI_THREAD_COND_INITIALIZER, or call tMPI_Thread_cond_init()
183 tMPI_Atomic_t initialized; /*!< Whether \a condp has been
185 struct tMPI_Thread_cond* condp; /*!< Actual condition variable data
187 } tMPI_Thread_cond_t;
188 /*! \brief Static initializer for tMPI_Thread_cond_t
190 * See the description of the tMPI_Thread_cond_t datatype for instructions
191 * on how to use this. Note that any variables initialized with this value
192 * MUST have static storage allocation.
194 #define TMPI_THREAD_COND_INITIALIZER { {0}, NULL}
201 /*! \brief Pthread implementation of barrier type.
203 * The contents of this structure depends on the actual threads
204 * implementation used.
208 tMPI_Atomic_t initialized; /*!< Whether \a barrierp has been initialized. */
209 struct tMPI_Thread_barrier* barrierp; /*!< Actual barrier data structure. */
210 volatile int threshold; /*!< Total number of members in barrier */
211 volatile int count; /*!< Remaining count before completion */
212 volatile int cycle; /*!< Alternating 0/1 to indicate round */
213 }tMPI_Thread_barrier_t;
214 /*! \brief Static initializer for tMPI_Thread_barrier_t
216 * See the description of the tMPI_Thread_barrier_t datatype for instructions
217 * on how to use this. Note that variables initialized with this value
218 * MUST have static storage allocation.
220 * \param count Threshold for barrier
222 #define TMPI_THREAD_BARRIER_INITIALIZER(count) { \
223 NULL, count, count, 0 \
231 /** Thread support status enumeration */
232 enum tMPI_Thread_support
234 TMPI_THREAD_SUPPORT_NO = 0, /*!< Starting threads will fail */
235 TMPI_THREAD_SUPPORT_YES = 1 /*!< Thread support available */
239 /** Thread setaffinity support status enumeration */
240 enum tMPI_Thread_setaffinity_support
242 TMPI_SETAFFINITY_SUPPORT_NO = 0, /*!< Setting thread affinity not
244 TMPI_SETAFFINITY_SUPPORT_YES = 1 /*!< Setting thread affinity supported */
250 /** handle a fatal error.
252 \param file source code file name of error.
253 \param line source code line number of error.
254 \param message format string for error message.
257 void tMPI_Fatal_error(const char *file, int line, const char *message, ...);
258 /** Convenience macro for the first two arguments to tMPI_Fatal_error(). */
259 #define TMPI_FARGS __FILE__, __LINE__
263 /*! \name Thread creation, destruction, and inspection
265 /** Check if threads are supported
267 * This routine provides a cleaner way to check if threads are supported
268 * instead of sprinkling your code with preprocessor conditionals.
270 * All thread functions are still available even without thread support,
271 * but some of them might return failure error codes, for instance if you try
274 * \return 1 if threads are supported, 0 if not.
277 enum tMPI_Thread_support tMPI_Thread_support(void);
280 /** Get the number of hardware threads that can be run simultaneously.
282 Returns the total number of cores and SMT threads that can run.
284 \returns The maximum number of threads that can run simulataneously.
285 If this number cannot be determined for the current architecture,
289 int tMPI_Thread_get_hw_number(void);
292 /** Create a new thread
294 * The new thread will call start_routine() with the argument arg.
296 * Please be careful not to change arg after calling this function.
298 * \param[out] thread Pointer to thread ID
299 * \param[in] start_routine The function to call in the new thread
300 * \param[in] arg Argument to call with
302 * \return Status - 0 on success, or an error code.
305 int tMPI_Thread_create(tMPI_Thread_t *thread,
306 void * (*start_routine)(void *),
312 /** Wait for a specific thread to finish executing
314 * If the thread has already finished the routine returns immediately.
316 * \param[in] thread Pointer to thread ID
317 * \param[out] value_ptr Pointer to location where to store pointer to
318 * exit value from threads that called
319 * tMPI_Thread_exit().
321 * \return 0 if the join went ok, or a non-zero error code.
324 int tMPI_Thread_join(tMPI_Thread_t thread, void **value_ptr);
327 /** Terminate calling thread
331 * \param value_ptr Pointer to a return value. Threads waiting for us to
332 * join them can read this value if they try.
336 void tMPI_Thread_exit(void *value_ptr);
340 /** Ask a thread to exit
342 * This routine tries to end the execution of another thread, but there are
343 * no guarantees it will succeed.
345 * \param thread Handle to thread we want to see dead.
346 * \return 0 or a non-zero error message.
349 int tMPI_Thread_cancel(tMPI_Thread_t thread);
354 /** Get a thread ID of the calling thread.
356 * This function also works on threads not started with tMPI_Thread_create,
357 * or any other function in thread_mpi. This makes it possible to, for
358 * example assign thread affinities to any thread.
360 * \return A thread ID of the calling thread */
362 tMPI_Thread_t tMPI_Thread_self(void);
366 /** Check whether two thread pointers point to the same thread
368 * \param[in] t1 Thread ID 1
369 * \param[in] t2 Thread ID 2
370 * \return non-zero if the thread structs refer to the same thread,
371 0 if the threads are different*/
373 int tMPI_Thread_equal(tMPI_Thread_t t1, tMPI_Thread_t t2);
376 /** Check whether this platform supports setting of thread affinity
378 * This function returns TMPI_SETAFFINITY_SUPPORT_YES if setting thread
379 * affinity is supported by the platform, and TMPI_SETAFFINITY_SUPPORT_NO
380 * if not. If this function returns 0, the function
381 * tMPI_Thread_setaffinity_single will simply return 0 itself, effectively
382 * ignoring the request.
384 * \return TMPI_SETAFFINITY_SUPPORT_YES if setting affinity is supported,
385 TMPI_SETAFFINITY_SUPPORT_NO otherwise */
387 enum tMPI_Thread_setaffinity_support tMPI_Thread_setaffinity_support(void);
390 /** Set thread affinity to a single core
392 * This function sets the thread affinity of a thread to a a specific
393 * numbered processor. This only works if the underlying operating system
394 * supports it. The processor number must be between 0 and the number returned
395 * by tMPI_Thread_get_hw_number().
397 * \param[in] thread Thread ID of the thread to set affinity for
398 * \param[in] nr Processor number to set affinity to
399 * \return zero on success, non-zero on error */
401 int tMPI_Thread_setaffinity_single(tMPI_Thread_t thread, unsigned int nr);
409 /** Initialize a new mutex
411 * This routine must be called before using any mutex not initialized
412 * with static storage class and TMPI_THREAD_MUTEX_INITIALIZER.
414 * \param mtx Pointer to a mutex opaque type.
415 * \return 0 or an error code.
418 int tMPI_Thread_mutex_init(tMPI_Thread_mutex_t *mtx);
423 /** Kill a mutex you no longer need
425 * Note that this call only frees resources allocated inside the mutex. It
426 * does not free the tMPI_Thread_mutex_t memory area itself if you created it
427 * with dynamic memory allocation.
429 * \param mtx Pointer to a mutex variable to get rid of.
430 * \return 0 or a non-zero error code.
433 int tMPI_Thread_mutex_destroy(tMPI_Thread_mutex_t *mtx);
438 /** Wait for exclusive access to a mutex
440 * This routine does not return until the mutex has been acquired.
442 * \param mtx Pointer to the mutex to lock
443 * \return 0 or a non-zero error code.
446 int tMPI_Thread_mutex_lock(tMPI_Thread_mutex_t *mtx);
451 /** Try to lock a mutex, return if busy
453 * This routine always return directly. If the mutex was available and
454 * we successfully locked it we return 0, otherwise a non-zero
455 * return code (usually meaning the mutex was already locked).
457 * \param mtx Pointer to the mutex to try and lock
458 * \return 0 if locked, non-zero if not locked or an error occurred.
461 int tMPI_Thread_mutex_trylock(tMPI_Thread_mutex_t *mtx);
466 /** Release the exclusive access to a mutex
468 * \param mtx Pointer to the mutex to release
469 * \return 0 or a non-zero error code.
472 int tMPI_Thread_mutex_unlock(tMPI_Thread_mutex_t *mtx);
477 /*! \name Thread-specific storage
481 /** Initialize thread-specific-storage handle
483 * The tMPI_Thread_key_t handle must always be initialized dynamically with
484 * this routine. If you need to initialize it statically in a file, use the
485 * tMPI_Thread_once() routine and corresponding data to initialize the
486 * thread-specific-storage key the first time you access it.
488 * \param key Pointer to opaque thread key type.
489 * \param destructor Routine to call (to free memory of key) when we quit
491 * \return status - 0 on sucess or a standard error code.
495 int tMPI_Thread_key_create(tMPI_Thread_key_t *key, void (*destructor)(void *));
500 /** Delete thread-specific-storage handle
502 * Calling this routine will kill the handle, and invoke the automatic
503 * destructor routine for each non-NULL value pointed to by key.
505 * \param key Opaque key type to destroy
506 * \return 0 or a non-zero error message.
509 int tMPI_Thread_key_delete(tMPI_Thread_key_t key);
514 /** Get value for thread-specific-storage in this thread
516 * If it has not yet been set, NULL is returned.
518 * \param key Thread-specific-storage handle.
519 * \return Pointer-to-void, the value of the data in this thread.
522 void * tMPI_Thread_getspecific(tMPI_Thread_key_t key);
526 /** Set value for thread-specific-storage in this thread
528 * \param key Thread-specific-storage handle.
529 * \param value What to set the data to (pointer-to-void).
530 * \return 0 or a non-zero error message.
533 int tMPI_Thread_setspecific(tMPI_Thread_key_t key, void *value);
541 /** Run the provided routine exactly once
543 * The control data must have been initialized before calling this routine,
544 * but you can do it with the static initialzer TMPI_THREAD_ONCE_INIT.
546 * tMPI_Thread_once() will not return to any of the calling routines until
547 * the initialization function has been completed.
549 * \param once_data Initialized one-time execution data
550 * \param init_routine Function to call exactly once
551 * \return 0 or a non-zero error message.
554 int tMPI_Thread_once(tMPI_Thread_once_t *once_data,
555 void (*init_routine)(void));
559 /*! \name Condition variables
562 /** Initialize condition variable
564 * This routine must be called before using any condition variable
565 * not initialized with static storage class and TMPI_THREAD_COND_INITIALIZER.
567 * \param cond Pointer to previously allocated condition variable
568 * \return 0 or a non-zero error message.
571 int tMPI_Thread_cond_init(tMPI_Thread_cond_t *cond);
575 /** Destroy condition variable
577 * This routine should be called when you are done with a condition variable.
578 * Note that it only releases memory allocated internally, not the
579 * tMPI_Thread_cond_t structure you provide a pointer to.
581 * \param cond Pointer to condition variable.
582 * \return 0 or a non-zero error message.
585 int tMPI_Thread_cond_destroy(tMPI_Thread_cond_t *cond);
589 /** Wait for a condition to be signaled
591 * This routine releases the mutex, and waits for the condition to be
592 * signaled by another thread before it returns.
594 * Note that threads waiting for conditions with tMPI_Thread_cond_wait
595 * may be subject to spurious wakeups: use this function in a while loop
596 * and check the state of a predicate associated with the wakeup
597 * before leaving the loop.
599 * \param cond condition variable
600 * \param mtx Mutex protecting the condition variable
602 * \return 0 or a non-zero error message.
605 int tMPI_Thread_cond_wait(tMPI_Thread_cond_t *cond,
606 tMPI_Thread_mutex_t *mtx);
611 /** Unblock one waiting thread
613 * This routine signals a condition variable to one
614 * thread (if any) waiting for it after calling
615 * tMPI_Thread_cond_wait().
617 * \param cond condition variable
619 * \return 0 or a non-zero error message.
622 int tMPI_Thread_cond_signal(tMPI_Thread_cond_t *cond);
625 /** Unblock all waiting threads
627 * This routine signals a condition variable to all
628 * (if any) threads that are waiting for it after calling
629 * tMPI_Thread_cond_wait().
631 * \param cond condition variable
633 * \return 0 or a non-zero error message.
636 int tMPI_Thread_cond_broadcast(tMPI_Thread_cond_t *cond);
645 /** Initialize a synchronization barrier type
647 * You only need to initialize a barrier once. They cycle
648 * automatically, so after release it is immediately ready
649 * to accept waiting threads again.
651 * \param barrier Pointer to previously allocated barrier type
652 * \param count Number of threads to synchronize. All threads
653 * will be released after \a count calls to
654 * tMPI_Thread_barrier_wait().
657 int tMPI_Thread_barrier_init(tMPI_Thread_barrier_t *barrier, int count);
661 /** Release data in a barrier datatype
663 * \param barrier Pointer to previously
664 * initialized barrier.
667 int tMPI_Thread_barrier_destroy(tMPI_Thread_barrier_t *barrier);
670 /** Perform barrier synchronization
672 * This routine blocks until it has been called N times,
673 * where N is the count value the barrier was initialized with.
674 * After N total calls all threads return. The barrier automatically
675 * cycles, and thus requires another N calls to unblock another time.
677 * \param barrier Pointer to previously create barrier.
679 * \return The last thread returns -1, all the others 0.
682 int tMPI_Thread_barrier_wait(tMPI_Thread_barrier_t *barrier);
691 #endif /* TMPI_THREADS_H_ */