diff --git a/opal/mca/threads/configure.m4 b/opal/mca/threads/configure.m4 index d051dbb8b43..dd10a05edf8 100644 --- a/opal/mca/threads/configure.m4 +++ b/opal/mca/threads/configure.m4 @@ -25,19 +25,23 @@ m4_define(MCA_opal_threads_CONFIGURE_MODE, STOP_AT_FIRST) AC_DEFINE_UNQUOTED([OPAL_ENABLE_MULTI_THREADS], [1], [Whether we should enable thread support within the OPAL code base]) AC_DEFUN([MCA_opal_threads_CONFIG],[ - threads_base_include= - # All components look at this value AC_ARG_WITH([threads], [AC_HELP_STRING([--with-threads=TYPE], - [Build high resolution threads component TYPE])]) + [Build high resolution threads component TYPE])], + [], + [with_threads=pthreads]) + + thread_type=$with_threads # first, compile all the components MCA_CONFIGURE_FRAMEWORK($1, $2, 1) - if test "$mutex_base_include" = "" ; then - mutex_base_include="pthreads/mutex_unix.h" - fi + threads_base_include="${thread_type}/threads_${thread_type}_threads.h" + mutex_base_include="${thread_type}/threads_${thread_type}_mutex.h" + tsd_base_include="${thread_type}/threads_${thread_type}_tsd.h" + wait_sync_base_include="${thread_type}/threads_${thread_type}_wait_sync.h" + AC_DEFINE_UNQUOTED([MCA_threads_IMPLEMENTATION_HEADER], ["opal/mca/threads/$threads_base_include"], [Header to include for threads implementation]) @@ -45,6 +49,12 @@ AC_DEFUN([MCA_opal_threads_CONFIG],[ AC_DEFINE_UNQUOTED([MCA_mutex_IMPLEMENTATION_HEADER], ["opal/mca/threads/$mutex_base_include"], [Header to include for mutex implementation]) -]) + AC_DEFINE_UNQUOTED([MCA_tsd_IMPLEMENTATION_HEADER], + ["opal/mca/threads/$tsd_base_include"], + [Header to include for tsd implementation]) + AC_DEFINE_UNQUOTED([MCA_wait_sync_IMPLEMENTATION_HEADER], + ["opal/mca/threads/$wait_sync_base_include"], + [Header to include for wait_sync implementation]) +]) diff --git a/opal/mca/threads/mutex.h b/opal/mca/threads/mutex.h index e28265941d4..d0228c98dfb 100644 --- a/opal/mca/threads/mutex.h +++ b/opal/mca/threads/mutex.h @@ -29,6 +29,8 @@ #include "opal_config.h" +BEGIN_C_DECLS + /** * @file: * @@ -37,7 +39,6 @@ * Functions for locking of critical sections. */ - /** * Opaque mutex object */ @@ -45,9 +46,7 @@ typedef struct opal_mutex_t opal_mutex_t; typedef struct opal_mutex_t opal_recursive_mutex_t; -BEGIN_C_DECLS #include MCA_mutex_IMPLEMENTATION_HEADER -END_C_DECLS OBJ_CLASS_DECLARATION(opal_mutex_t); OBJ_CLASS_DECLARATION(opal_recursive_mutex_t); diff --git a/opal/mca/threads/pthreads/Makefile.am b/opal/mca/threads/pthreads/Makefile.am index 7cd56b60242..833950d5e17 100644 --- a/opal/mca/threads/pthreads/Makefile.am +++ b/opal/mca/threads/pthreads/Makefile.am @@ -21,9 +21,12 @@ noinst_LTLIBRARIES = libmca_threads_pthreads.la libmca_threads_pthreads_la_SOURCES = \ - threads_pthreads.h \ threads_pthreads_component.c \ - threads_pthreads_mutex.c \ threads_pthreads_condition.c \ + threads_pthreads_module.c \ + threads_pthreads_mutex.c \ + threads_pthreads_mutex.h \ + threads_pthreads_threads.h \ + threads_pthreads_tsd.h \ threads_pthreads_wait_sync.c \ - threads_pthreads_module.c + threads_pthreads_wait_sync.h diff --git a/opal/mca/threads/pthreads/configure.m4 b/opal/mca/threads/pthreads/configure.m4 index 023faac62ad..cb66096e492 100644 --- a/opal/mca/threads/pthreads/configure.m4 +++ b/opal/mca/threads/pthreads/configure.m4 @@ -30,11 +30,19 @@ AC_DEFUN([MCA_opal_threads_pthreads_COMPILE_MODE], [ ]) AC_DEFUN([MCA_opal_threads_pthreads_POST_CONFIG],[ - AS_IF([test "$1" = "1"], [threads_base_include="pthreads/threads_pthreads.h"]) + AS_IF([test "$1" = "1"], [threads_base_include="pthreads/threads_pthreads_threads.h"]) ])dnl AC_DEFUN([MCA_opal_mutex_pthreads_POST_CONFIG],[ - AS_IF([test "$1" = "1"], [mutex_base_include="pthreads/mutex_unix.h"]) + AS_IF([test "$1" = "1"], [mutex_base_include="pthreads/threads_pthreads_mutex.h"]) +])dnl + +AC_DEFUN([MCA_opal_tsd_pthreads_POST_CONFIG],[ + AS_IF([test "$1" = "1"], [threads_base_include="pthreads/threads_pthreads_tsd.h"]) +])dnl + +AC_DEFUN([MCA_opal_wait_sync_pthreads_POST_CONFIG],[ + AS_IF([test "$1" = "1"], [mutex_base_include="pthreads/threads_pthreads_wait_sync.h"]) ])dnl # MCA_threads_pthreads_CONFIG(action-if-can-compile, diff --git a/opal/mca/threads/pthreads/threads_pthreads.h b/opal/mca/threads/pthreads/threads_pthreads.h deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/opal/mca/threads/pthreads/threads_pthreads_component.c b/opal/mca/threads/pthreads/threads_pthreads_component.c index 2f8f963ba03..938497c02d1 100644 --- a/opal/mca/threads/pthreads/threads_pthreads_component.c +++ b/opal/mca/threads/pthreads/threads_pthreads_component.c @@ -25,7 +25,6 @@ #include "opal/mca/threads/thread.h" #include "opal/mca/threads/threads.h" -#include "opal/mca/threads/pthreads/threads_pthreads.h" #include "opal/constants.h" static int opal_threads_pthreads_open(void); diff --git a/opal/mca/threads/pthreads/mutex_unix.h b/opal/mca/threads/pthreads/threads_pthreads_mutex.h similarity index 97% rename from opal/mca/threads/pthreads/mutex_unix.h rename to opal/mca/threads/pthreads/threads_pthreads_mutex.h index 9d5f0bfa213..3e333843d9b 100644 --- a/opal/mca/threads/pthreads/mutex_unix.h +++ b/opal/mca/threads/pthreads/threads_pthreads_mutex.h @@ -23,8 +23,8 @@ * $HEADER$ */ -#ifndef OPAL_MUTEX_UNIX_H -#define OPAL_MUTEX_UNIX_H 1 +#ifndef OPAL_MCA_THREADS_PTHREADS_THREADS_PTHREADS_MUTEX_H +#define OPAL_MCA_THREADS_PTHREADS_THREADS_PTHREADS_MUTEX_H 1 /** * @file: @@ -213,4 +213,4 @@ static inline void opal_mutex_atomic_unlock(opal_mutex_t *m) END_C_DECLS -#endif /* OPAL_MUTEX_UNIX_H */ +#endif /* OPAL_MCA_THREADS_PTHREADS_THREADS_PTHREADS_MUTEX_H */ diff --git a/opal/mca/threads/pthreads/threads_pthreads_threads.h b/opal/mca/threads/pthreads/threads_pthreads_threads.h new file mode 100644 index 00000000000..ed0166e4dab --- /dev/null +++ b/opal/mca/threads/pthreads/threads_pthreads_threads.h @@ -0,0 +1,15 @@ + +#ifndef OPAL_MCA_THREADS_PTHREADS_THREADS_PTHREADS_THREADS_H +#define OPAL_MCA_THREADS_PTHREADS_THREADS_PTHREADS_THREADS_H 1 + +#include +#include + +struct opal_thread_t { + opal_object_t super; + opal_thread_fn_t t_run; + void* t_arg; + pthread_t t_handle; +}; + +#endif /* OPAL_MCA_THREADS_PTHREADS_THREADS_PTHREADS_THREADS_H */ diff --git a/opal/mca/threads/pthreads/threads_pthreads_tsd.h b/opal/mca/threads/pthreads/threads_pthreads_tsd.h new file mode 100644 index 00000000000..f3696f7df3d --- /dev/null +++ b/opal/mca/threads/pthreads/threads_pthreads_tsd.h @@ -0,0 +1,29 @@ + +#ifndef OPAL_MCA_THREADS_PTHREADS_THREADS_PTHREADS_TSD_H +#define OPAL_MCA_THREADS_PTHREADS_THREADS_PTHREADS_TSD_H 1 + +#include +#include + +typedef pthread_key_t opal_tsd_key_t; + +static inline int +opal_tsd_key_delete(opal_tsd_key_t key) +{ + return pthread_key_delete(key); +} + +static inline int +opal_tsd_setspecific(opal_tsd_key_t key, void *value) +{ + return pthread_setspecific(key, value); +} + +static inline int +opal_tsd_getspecific(opal_tsd_key_t key, void **valuep) +{ + *valuep = pthread_getspecific(key); + return OPAL_SUCCESS; +} + +#endif /* OPAL_MCA_THREADS_PTHREADS_THREADS_PTHREADS_TSD_H */ diff --git a/opal/mca/threads/pthreads/threads_pthreads_wait_sync.h b/opal/mca/threads/pthreads/threads_pthreads_wait_sync.h new file mode 100644 index 00000000000..0b43a51fd62 --- /dev/null +++ b/opal/mca/threads/pthreads/threads_pthreads_wait_sync.h @@ -0,0 +1,77 @@ + +#ifndef OPAL_MCA_THREADS_PTHREADS_THREADS_PTHREADS_WAIT_SYNC_H +#define OPAL_MCA_THREADS_PTHREADS_THREADS_PTHREADS_WAIT_SYNC_H 1 + +typedef struct ompi_wait_sync_t { + opal_atomic_int32_t count; + int32_t status; + pthread_cond_t condition; + pthread_mutex_t lock; + struct ompi_wait_sync_t *next; + struct ompi_wait_sync_t *prev; + volatile bool signaling; +} ompi_wait_sync_t; + +#define SYNC_WAIT(sync) (opal_using_threads() ? ompi_sync_wait_mt (sync) : sync_wait_st (sync)) + +/* The loop in release handles a race condition between the signaling + * thread and the destruction of the condition variable. The signaling + * member will be set to false after the final signaling thread has + * finished operating on the sync object. This is done to avoid + * extra atomics in the signalling function and keep it as fast + * as possible. Note that the race window is small so spinning here + * is more optimal than sleeping since this macro is called in + * the critical path. */ +#define WAIT_SYNC_RELEASE(sync) \ + if (opal_using_threads()) { \ + while ((sync)->signaling) { \ + continue; \ + } \ + pthread_cond_destroy(&(sync)->condition); \ + pthread_mutex_destroy(&(sync)->lock); \ + } + +#define WAIT_SYNC_RELEASE_NOWAIT(sync) \ + if (opal_using_threads()) { \ + pthread_cond_destroy(&(sync)->condition); \ + pthread_mutex_destroy(&(sync)->lock); \ + } + + +#define WAIT_SYNC_SIGNAL(sync) \ + if (opal_using_threads()) { \ + pthread_mutex_lock(&(sync->lock)); \ + pthread_cond_signal(&sync->condition); \ + pthread_mutex_unlock(&(sync->lock)); \ + sync->signaling = false; \ + } + +#define WAIT_SYNC_SIGNALLED(sync){ \ + (sync)->signaling = false; \ +} + +OPAL_DECLSPEC int ompi_sync_wait_mt(ompi_wait_sync_t *sync); +static inline int sync_wait_st (ompi_wait_sync_t *sync) +{ + while (sync->count > 0) { + opal_progress(); + } + + return sync->status; +} + + +#define WAIT_SYNC_INIT(sync,c) \ + do { \ + (sync)->count = (c); \ + (sync)->next = NULL; \ + (sync)->prev = NULL; \ + (sync)->status = 0; \ + (sync)->signaling = (0 != (c)); \ + if (opal_using_threads()) { \ + pthread_cond_init (&(sync)->condition, NULL); \ + pthread_mutex_init (&(sync)->lock, NULL); \ + } \ + } while(0) + +#endif /* OPAL_MCA_THREADS_PTHREADS_THREADS_PTHREADS_WAIT_SYNC_H */ diff --git a/opal/mca/threads/qthreads/threads_qthreads.htmp b/opal/mca/threads/qthreads/threads_qthreads.htmp deleted file mode 100644 index f1ab4c81c0f..00000000000 --- a/opal/mca/threads/qthreads/threads_qthreads.htmp +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana - * University Research and Technology - * Corporation. All rights reserved. - * Copyright (c) 2004-2014 The University of Tennessee and The University - * of Tennessee Research Foundation. All rights - * reserved. - * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, - * University of Stuttgart. All rights reserved. - * Copyright (c) 2004-2005 The Regents of the University of California. - * All rights reserved. - * $COPYRIGHT$ - * - * Additional copyrights may follow - * - * $HEADER$ - */ - -#ifndef OPAL_MCA_TIMER_DARWIN_TIMER_DARWIN_H -#define OPAL_MCA_TIMER_DARWIN_TIMER_DARWIN_H - -#include "opal_config.h" -#include - -typedef uint64_t opal_threadss_t; - -/* frequency in mhz */ -OPAL_DECLSPEC extern opal_threadss_t opal_threadss_darwin_freq; -OPAL_DECLSPEC extern mach_timebase_info_data_t opal_threadss_darwin_info; -OPAL_DECLSPEC extern opal_threadss_t opal_threadss_darwin_bias; - -/** - * Use the pragmatic solution proposed at - * http://stackoverflow.com/questions/23378063/how-can-i-use-mach-absolute-time-without-overflowing/23378064#23378064 - */ -static inline opal_threadss_t -opal_threadss_base_get_cycles(void) -{ - uint64_t now = mach_absolute_time(); - - if( opal_threadss_darwin_info.denom == 0 ) { - (void)mach_timebase_info(&opal_threadss_darwin_info); - if( opal_threadss_darwin_info.denom > 1024 ) { - double frac = (double)opal_threadss_darwin_info.numer/opal_threadss_darwin_info.denom; - opal_threadss_darwin_info.denom = 1024; - opal_threadss_darwin_info.numer = opal_threadss_darwin_info.denom * frac + 0.5; - } - opal_threadss_darwin_bias = now; - } - /* this is basically a wrapper around the "right" assembly to convert - the tick counter off the PowerPC Time Base into nanos. */ - return (now - opal_threadss_darwin_bias) * opal_threadss_darwin_info.numer / opal_threadss_darwin_info.denom; -} - - -static inline opal_threadss_t -opal_threadss_base_get_usec(void) -{ - /* freq is in Hz, so this gives usec */ - return opal_threadss_base_get_cycles() / 1000; -} - - -static inline opal_threadss_t -opal_threadss_base_get_freq(void) -{ - return opal_threadss_darwin_freq; -} - -typedef pthread_key_t opal_tsd_key_t; - -static inline int -opal_tsd_key_delete(opal_tsd_key_t key) -{ - return pthread_key_delete(key); -} - -static inline int -opal_tsd_setspecific(opal_tsd_key_t key, void *value) -{ - return pthread_setspecific(key, value); -} - -static inline int -opal_tsd_getspecific(opal_tsd_key_t key, void **valuep) -{ - *valuep = pthread_getspecific(key); - return OPAL_SUCCESS; -} - -#define OPAL_TIMER_CYCLE_NATIVE 0 -#define OPAL_TIMER_CYCLE_SUPPORTED 1 -#define OPAL_TIMER_USEC_NATIVE 1 -#define OPAL_TIMER_USEC_SUPPORTED 1 - -#endif diff --git a/opal/mca/threads/threads.h b/opal/mca/threads/threads.h index 5f63b677498..c69de3f774d 100644 --- a/opal/mca/threads/threads.h +++ b/opal/mca/threads/threads.h @@ -27,9 +27,6 @@ #include "opal_config.h" -#include -#include - #include "opal/class/opal_object.h" #if OPAL_ENABLE_DEBUG #include "opal/util/output.h" @@ -44,12 +41,7 @@ typedef void *(*opal_thread_fn_t) (opal_object_t *); #define OPAL_THREAD_CANCELLED ((void*)1); -struct opal_thread_t { - opal_object_t super; - opal_thread_fn_t t_run; - void* t_arg; - pthread_t t_handle; -}; +#include MCA_threads_IMPLEMENTATION_HEADER typedef struct opal_thread_t opal_thread_t; @@ -140,7 +132,6 @@ OPAL_DECLSPEC void opal_thread_kill(opal_thread_t *, int sig); OPAL_DECLSPEC void opal_thread_set_main(void); OPAL_DECLSPEC void opal_event_use_threads(void); - END_C_DECLS #endif /* OPAL_MCA_THREAD_H */ diff --git a/opal/mca/threads/tsd.h b/opal/mca/threads/tsd.h index a9ff4d06684..5f5a7ffd625 100644 --- a/opal/mca/threads/tsd.h +++ b/opal/mca/threads/tsd.h @@ -108,26 +108,7 @@ OPAL_DECLSPEC int opal_tsd_getspecific(opal_tsd_key_t key, void **valuep); #else -typedef pthread_key_t opal_tsd_key_t; - -static inline int -opal_tsd_key_delete(opal_tsd_key_t key) -{ - return pthread_key_delete(key); -} - -static inline int -opal_tsd_setspecific(opal_tsd_key_t key, void *value) -{ - return pthread_setspecific(key, value); -} - -static inline int -opal_tsd_getspecific(opal_tsd_key_t key, void **valuep) -{ - *valuep = pthread_getspecific(key); - return OPAL_SUCCESS; -} +#include MCA_tsd_IMPLEMENTATION_HEADER #endif diff --git a/opal/mca/threads/wait_sync.h b/opal/mca/threads/wait_sync.h index 316ef5a394a..4dc9f9ecb07 100644 --- a/opal/mca/threads/wait_sync.h +++ b/opal/mca/threads/wait_sync.h @@ -22,87 +22,16 @@ #include "opal/sys/atomic.h" #include "opal/threads/condition.h" -//#include BEGIN_C_DECLS extern int opal_max_thread_in_progress; -typedef struct ompi_wait_sync_t { - opal_atomic_int32_t count; - int32_t status; - pthread_cond_t condition; - pthread_mutex_t lock; - struct ompi_wait_sync_t *next; - struct ompi_wait_sync_t *prev; - volatile bool signaling; -} ompi_wait_sync_t; +#include MCA_wait_sync_IMPLEMENTATION_HEADER #define REQUEST_PENDING (void*)0L #define REQUEST_COMPLETED (void*)1L -#define SYNC_WAIT(sync) (opal_using_threads() ? ompi_sync_wait_mt (sync) : sync_wait_st (sync)) - -/* The loop in release handles a race condition between the signaling - * thread and the destruction of the condition variable. The signaling - * member will be set to false after the final signaling thread has - * finished operating on the sync object. This is done to avoid - * extra atomics in the signalling function and keep it as fast - * as possible. Note that the race window is small so spinning here - * is more optimal than sleeping since this macro is called in - * the critical path. */ -#define WAIT_SYNC_RELEASE(sync) \ - if (opal_using_threads()) { \ - while ((sync)->signaling) { \ - continue; \ - } \ - pthread_cond_destroy(&(sync)->condition); \ - pthread_mutex_destroy(&(sync)->lock); \ - } - -#define WAIT_SYNC_RELEASE_NOWAIT(sync) \ - if (opal_using_threads()) { \ - pthread_cond_destroy(&(sync)->condition); \ - pthread_mutex_destroy(&(sync)->lock); \ - } - - -#define WAIT_SYNC_SIGNAL(sync) \ - if (opal_using_threads()) { \ - pthread_mutex_lock(&(sync->lock)); \ - pthread_cond_signal(&sync->condition); \ - pthread_mutex_unlock(&(sync->lock)); \ - sync->signaling = false; \ - } - -#define WAIT_SYNC_SIGNALLED(sync){ \ - (sync)->signaling = false; \ -} - -OPAL_DECLSPEC int ompi_sync_wait_mt(ompi_wait_sync_t *sync); -static inline int sync_wait_st (ompi_wait_sync_t *sync) -{ - while (sync->count > 0) { - opal_progress(); - } - - return sync->status; -} - - -#define WAIT_SYNC_INIT(sync,c) \ - do { \ - (sync)->count = (c); \ - (sync)->next = NULL; \ - (sync)->prev = NULL; \ - (sync)->status = 0; \ - (sync)->signaling = (0 != (c)); \ - if (opal_using_threads()) { \ - pthread_cond_init (&(sync)->condition, NULL); \ - pthread_mutex_init (&(sync)->lock, NULL); \ - } \ - } while(0) - /** * Update the status of the synchronization primitive. If an error is * reported the synchronization is completed and the signal