root/opal/threads/thread_usage.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. opal_set_using_threads

   1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
   2 /*
   3  * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
   4  *                         University Research and Technology
   5  *                         Corporation.  All rights reserved.
   6  * Copyright (c) 2004-2007 The University of Tennessee and The University
   7  *                         of Tennessee Research Foundation.  All rights
   8  *                         reserved.
   9  * Copyright (c) 2004-2006 High Performance Computing Center Stuttgart, 
  10  *                         University of Stuttgart.  All rights reserved.
  11  * Copyright (c) 2004-2005 The Regents of the University of California.
  12  *                         All rights reserved.
  13  * Copyright (c) 2007-2014 Cisco Systems, Inc.  All rights reserved.
  14  * Copyright (c) 2014-2016 Research Organization for Information Science
  15  *                         and Technology (RIST). All rights reserved.
  16  * Copyright (c) 2015-2018 Los Alamos National Security, LLC. All rights
  17  *                         reserved.
  18  * $COPYRIGHT$
  19  * 
  20  * Additional copyrights may follow
  21  * 
  22  * $HEADER$
  23  */
  24 
  25 #if !defined(OPAL_THREAD_USAGE_H)
  26 #define OPAL_THREAD_USAGE_H
  27 
  28 #include "opal_config.h"
  29 
  30 #include "opal/sys/atomic.h"
  31 #include "opal/prefetch.h"
  32 
  33 OPAL_DECLSPEC extern bool opal_uses_threads;
  34 
  35 /**
  36  * Check and see if the process is using multiple threads.
  37  *
  38  * @retval true If the process may have more than one thread.
  39  * @retval false If the process only has a single thread.
  40  *
  41  * The value that this function returns is influenced by:
  42  *
  43  * - how MPI_INIT or MPI_INIT_THREAD was invoked,
  44  * - what the final MPI thread level was determined to be,
  45  * - whether the OMPI or MPI libraries are multi-threaded
  46  *
  47  * MPI_INIT and MPI_INIT_THREAD (specifically, back-end OMPI startup
  48  * functions) invoke opal_set_using_threads() to influence the value of
  49  * this function, depending on their situation. Some examples:
  50  *
  51  * - if MPI_INIT is invoked, and the ompi components in use are
  52  * single-threaded, this value will be false.
  53  *
  54  * - if MPI_INIT_THREAD is invoked with MPI_THREAD_MULTIPLE, we have
  55  * thread support, and the final thread level is determined to be
  56  * MPI_THREAD_MULTIPLE, this value will be true.
  57  *
  58  * - if the process is a single-threaded OMPI executable (e.g., mpicc),
  59  * this value will be false.
  60  *
  61  * Hence, this function will return false if there is guaranteed to
  62  * only be one thread in the process.  If there is even the
  63  * possibility that we may have multiple threads, true will be
  64  * returned.
  65  */
  66 #define opal_using_threads()  opal_uses_threads
  67 
  68 /**
  69  * Set whether the process is using multiple threads or not.
  70  *
  71  * @param have Boolean indicating whether the process is using
  72  * multiple threads or not.
  73  *
  74  * @retval opal_using_threads The new return value from
  75  * opal_using_threads().
  76  *
  77  * This function is used to influence the return value of
  78  * opal_using_threads().  If configure detected that we have thread
  79  * support, the return value of future invocations of
  80  * opal_using_threads() will be the parameter's value.  If configure
  81  * detected that we have no thread support, then the retuen from
  82  * opal_using_threads() will always be false.
  83  */
  84 static inline bool opal_set_using_threads(bool have)
  85 {
  86     opal_uses_threads = have;
  87     return opal_using_threads();
  88 }
  89 
  90 
  91 /**
  92  * Use an atomic operation for increment/decrement if opal_using_threads()
  93  * indicates that threads are in use by the application or library.
  94  */
  95 
  96 #define OPAL_THREAD_DEFINE_ATOMIC_OP(type, name, operator, suffix)      \
  97 static inline type opal_thread_ ## name ## _fetch_ ## suffix (opal_atomic_ ## type *addr, type delta) \
  98 {                                                                       \
  99     if (OPAL_UNLIKELY(opal_using_threads())) {                          \
 100         return opal_atomic_ ## name ## _fetch_ ## suffix (addr, delta); \
 101     }                                                                   \
 102                                                                         \
 103     *addr = *addr operator delta;                                       \
 104     return *addr;                                                       \
 105 }                                                                       \
 106                                                                         \
 107 static inline type opal_thread_fetch_ ## name ## _ ## suffix (opal_atomic_ ## type *addr, type delta) \
 108 {                                                                       \
 109     if (OPAL_UNLIKELY(opal_using_threads())) {                          \
 110         return opal_atomic_fetch_ ## name ## _ ## suffix (addr, delta); \
 111     }                                                                   \
 112                                                                         \
 113     type old = *addr;                                                   \
 114     *addr = old operator delta;                                         \
 115     return old;                                                         \
 116 }
 117 
 118 #define OPAL_THREAD_DEFINE_ATOMIC_COMPARE_EXCHANGE(type, addr_type, suffix)       \
 119 static inline bool opal_thread_compare_exchange_strong_ ## suffix (opal_atomic_ ## addr_type *addr, type *compare, type value) \
 120 {                                                                       \
 121     if (OPAL_UNLIKELY(opal_using_threads())) {                          \
 122         return opal_atomic_compare_exchange_strong_ ## suffix (addr, (addr_type *) compare, (addr_type) value); \
 123     }                                                                   \
 124                                                                         \
 125     if ((type) *addr == *compare) {                                     \
 126         ((type *) addr)[0] = value;                                     \
 127         return true;                                                    \
 128     }                                                                   \
 129                                                                         \
 130     *compare = ((type *) addr)[0];                                      \
 131                                                                         \
 132     return false;                                                       \
 133 }
 134 
 135 #define OPAL_THREAD_DEFINE_ATOMIC_SWAP(type, addr_type, suffix)         \
 136 static inline type opal_thread_swap_ ## suffix (opal_atomic_ ## addr_type *ptr, type newvalue) \
 137 {                                                                       \
 138     if (opal_using_threads ()) {                                        \
 139         return (type) opal_atomic_swap_ ## suffix (ptr, (addr_type) newvalue); \
 140     }                                                                   \
 141                                                                         \
 142     type old = ((type *) ptr)[0];                                       \
 143     ((type *) ptr)[0] = newvalue;                                       \
 144                                                                         \
 145     return old;                                                         \
 146 }
 147 
 148 OPAL_THREAD_DEFINE_ATOMIC_OP(int32_t, add, +, 32)
 149 OPAL_THREAD_DEFINE_ATOMIC_OP(size_t, add, +, size_t)
 150 OPAL_THREAD_DEFINE_ATOMIC_OP(int32_t, and, &, 32)
 151 OPAL_THREAD_DEFINE_ATOMIC_OP(int32_t, or, |, 32)
 152 OPAL_THREAD_DEFINE_ATOMIC_OP(int32_t, xor, ^, 32)
 153 OPAL_THREAD_DEFINE_ATOMIC_OP(int32_t, sub, -, 32)
 154 OPAL_THREAD_DEFINE_ATOMIC_OP(size_t, sub, -, size_t)
 155 
 156 OPAL_THREAD_DEFINE_ATOMIC_COMPARE_EXCHANGE(int32_t, int32_t, 32)
 157 OPAL_THREAD_DEFINE_ATOMIC_COMPARE_EXCHANGE(intptr_t, intptr_t, ptr)
 158 OPAL_THREAD_DEFINE_ATOMIC_SWAP(int32_t, int32_t, 32)
 159 OPAL_THREAD_DEFINE_ATOMIC_SWAP(intptr_t, intptr_t, ptr)
 160 
 161 #define OPAL_THREAD_ADD_FETCH32 opal_thread_add_fetch_32
 162 #define OPAL_ATOMIC_ADD_FETCH32 opal_thread_add_fetch_32
 163 
 164 #define OPAL_THREAD_AND_FETCH32 opal_thread_and_fetch_32
 165 #define OPAL_ATOMIC_AND_FETCH32 opal_thread_and_fetch_32
 166 
 167 #define OPAL_THREAD_OR_FETCH32 opal_thread_or_fetch_32
 168 #define OPAL_ATOMIC_OR_FETCH32 opal_thread_or_fetch_32
 169 
 170 #define OPAL_THREAD_XOR_FETCH32 opal_thread_xor_fetch_32
 171 #define OPAL_ATOMIC_XOR_FETCH32 opal_thread_xor_fetch_32
 172 
 173 #define OPAL_THREAD_ADD_FETCH_SIZE_T opal_thread_add_fetch_size_t
 174 #define OPAL_ATOMIC_ADD_FETCH_SIZE_T opal_thread_add_fetch_size_t
 175 
 176 #define OPAL_THREAD_SUB_FETCH_SIZE_T opal_thread_sub_fetch_size_t
 177 #define OPAL_ATOMIC_SUB_FETCH_SIZE_T opal_thread_sub_fetch_size_t
 178 
 179 #define OPAL_THREAD_FETCH_ADD32 opal_thread_fetch_add_32
 180 #define OPAL_ATOMIC_FETCH_ADD32 opal_thread_fetch_add_32
 181 
 182 #define OPAL_THREAD_FETCH_AND32 opal_thread_fetch_and_32
 183 #define OPAL_ATOMIC_FETCH_AND32 opal_thread_fetch_and_32
 184 
 185 #define OPAL_THREAD_FETCH_OR32 opal_thread_fetch_or_32
 186 #define OPAL_ATOMIC_FETCH_OR32 opal_thread_fetch_or_32
 187 
 188 #define OPAL_THREAD_FETCH_XOR32 opal_thread_fetch_xor_32
 189 #define OPAL_ATOMIC_FETCH_XOR32 opal_thread_fetch_xor_32
 190 
 191 #define OPAL_THREAD_FETCH_ADD_SIZE_T opal_thread_fetch_add_size_t
 192 #define OPAL_ATOMIC_FETCH_ADD_SIZE_T opal_thread_fetch_add_size_t
 193 
 194 #define OPAL_THREAD_FETCH_SUB_SIZE_T opal_thread_fetch_sub_size_t
 195 #define OPAL_ATOMIC_FETCH_SUB_SIZE_T opal_thread_fetch_sub_size_t
 196 
 197 #define OPAL_THREAD_COMPARE_EXCHANGE_STRONG_32 opal_thread_compare_exchange_strong_32
 198 #define OPAL_ATOMIC_COMPARE_EXCHANGE_STRONG_32 opal_thread_compare_exchange_strong_32
 199 
 200 #define OPAL_THREAD_COMPARE_EXCHANGE_STRONG_PTR(x, y, z) opal_thread_compare_exchange_strong_ptr ((opal_atomic_intptr_t *) x, (intptr_t *) y, (intptr_t) z)
 201 #define OPAL_ATOMIC_COMPARE_EXCHANGE_STRONG_PTR OPAL_THREAD_COMPARE_EXCHANGE_STRONG_PTR
 202 
 203 #define OPAL_THREAD_SWAP_32 opal_thread_swap_32
 204 #define OPAL_ATOMIC_SWAP_32 opal_thread_swap_32
 205 
 206 #define OPAL_THREAD_SWAP_PTR(x, y) opal_thread_swap_ptr ((opal_atomic_intptr_t *) x, (intptr_t) y)
 207 #define OPAL_ATOMIC_SWAP_PTR OPAL_THREAD_SWAP_PTR
 208 
 209 /* define 64-bit macros is 64-bit atomic math is available */
 210 #if OPAL_HAVE_ATOMIC_MATH_64
 211 
 212 OPAL_THREAD_DEFINE_ATOMIC_OP(int64_t, add, +, 64)
 213 OPAL_THREAD_DEFINE_ATOMIC_OP(int64_t, and, &, 64)
 214 OPAL_THREAD_DEFINE_ATOMIC_OP(int64_t, or, |, 64)
 215 OPAL_THREAD_DEFINE_ATOMIC_OP(int64_t, xor, ^, 64)
 216 OPAL_THREAD_DEFINE_ATOMIC_OP(int64_t, sub, -, 64)
 217 OPAL_THREAD_DEFINE_ATOMIC_COMPARE_EXCHANGE(int64_t, int64_t, 64)
 218 OPAL_THREAD_DEFINE_ATOMIC_SWAP(int64_t, int64_t, 64)
 219 
 220 #define OPAL_THREAD_ADD_FETCH64 opal_thread_add_fetch_64
 221 #define OPAL_ATOMIC_ADD_FETCH64 opal_thread_add_fetch_64
 222 
 223 #define OPAL_THREAD_AND_FETCH64 opal_thread_and_fetch_64
 224 #define OPAL_ATOMIC_AND_FETCH64 opal_thread_and_fetch_64
 225 
 226 #define OPAL_THREAD_OR_FETCH64 opal_thread_or_fetch_64
 227 #define OPAL_ATOMIC_OR_FETCH64 opal_thread_or_fetch_64
 228 
 229 #define OPAL_THREAD_XOR_FETCH64 opal_thread_xor_fetch_64
 230 #define OPAL_ATOMIC_XOR_FETCH64 opal_thread_xor_fetch_64
 231 
 232 #define OPAL_THREAD_FETCH_ADD64 opal_thread_fetch_add_64
 233 #define OPAL_ATOMIC_FETCH_ADD64 opal_thread_fetch_add_64
 234 
 235 #define OPAL_THREAD_FETCH_AND64 opal_thread_fetch_and_64
 236 #define OPAL_ATOMIC_FETCH_AND64 opal_thread_fetch_and_64
 237 
 238 #define OPAL_THREAD_FETCH_OR64 opal_thread_fetch_or_64
 239 #define OPAL_ATOMIC_FETCH_OR64 opal_thread_fetch_or_64
 240 
 241 #define OPAL_THREAD_FETCH_XOR64 opal_thread_fetch_xor_64
 242 #define OPAL_ATOMIC_FETCH_XOR64 opal_thread_fetch_xor_64
 243 
 244 #define OPAL_THREAD_COMPARE_EXCHANGE_STRONG_64 opal_thread_compare_exchange_strong_64
 245 #define OPAL_ATOMIC_COMPARE_EXCHANGE_STRONG_64 opal_thread_compare_exchange_strong_64
 246 
 247 #define OPAL_THREAD_SWAP_64 opal_thread_swap_64
 248 #define OPAL_ATOMIC_SWAP_64 opal_thread_swap_64
 249 
 250 #endif
 251 
 252 /* thread local storage */
 253 #if OPAL_C_HAVE__THREAD_LOCAL
 254 #define opal_thread_local _Thread_local
 255 #define OPAL_HAVE_THREAD_LOCAL 1
 256 
 257 #elif OPAL_C_HAVE___THREAD /* OPAL_C_HAVE__THREAD_LOCAL */
 258 #define opal_thread_local __thread
 259 #define OPAL_HAVE_THREAD_LOCAL 1
 260 #endif /* OPAL_C_HAVE___THREAD */
 261 
 262 #if !defined(OPAL_HAVE_THREAD_LOCAL)
 263 #define OPAL_HAVE_THREAD_LOCAL 0
 264 #endif /* !defined(OPAL_HAVE_THREAD_LOCAL) */
 265 
 266 #endif /* !defined(OPAL_THREAD_USAGE_H) */

/* [<][>][^][v][top][bottom][index][help] */