File indexing completed on 2025-02-22 10:47:27
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025 #ifndef PMIX_THREAD_H
0026 #define PMIX_THREAD_H 1
0027
0028 #include "src/include/pmix_config.h"
0029
0030 #include <pthread.h>
0031 #include <signal.h>
0032
0033 #include "src/class/pmix_object.h"
0034 #include "src/include/pmix_atomic.h"
0035 #if PMIX_ENABLE_DEBUG
0036 # include "src/util/pmix_output.h"
0037 #endif
0038
0039 #include "pmix_mutex.h"
0040
0041 BEGIN_C_DECLS
0042
0043 typedef void *(*pmix_thread_fn_t)(pmix_object_t *);
0044
0045 #define PMIX_THREAD_CANCELLED ((void *) 1);
0046
0047 struct pmix_thread_t {
0048 pmix_object_t super;
0049 pmix_thread_fn_t t_run;
0050 void *t_arg;
0051 pthread_t t_handle;
0052 };
0053
0054 typedef struct pmix_thread_t pmix_thread_t;
0055
0056 #if PMIX_ENABLE_DEBUG
0057 PMIX_EXPORT extern bool pmix_debug_threads;
0058 #endif
0059
0060 PMIX_EXPORT PMIX_CLASS_DECLARATION(pmix_thread_t);
0061
0062 #define pmix_condition_wait(a, b) pthread_cond_wait(a, &(b)->m_lock_pthread)
0063 typedef pthread_cond_t pmix_condition_t;
0064 #define pmix_condition_broadcast(a) pthread_cond_broadcast(a)
0065 #define pmix_condition_signal(a) pthread_cond_signal(a)
0066 #define PMIX_CONDITION_STATIC_INIT PTHREAD_COND_INITIALIZER
0067
0068 typedef struct {
0069 pmix_status_t status;
0070 pmix_mutex_t mutex;
0071 pmix_condition_t cond;
0072 volatile bool active;
0073 } pmix_lock_t;
0074
0075 #define PMIX_LOCK_STATIC_INIT \
0076 { \
0077 .status = PMIX_SUCCESS, \
0078 .mutex = PMIX_MUTEX_STATIC_INIT, \
0079 .cond = PMIX_CONDITION_STATIC_INIT, \
0080 .active = false \
0081 }
0082
0083 #define PMIX_CONSTRUCT_LOCK(l) \
0084 do { \
0085 PMIX_CONSTRUCT(&(l)->mutex, pmix_mutex_t); \
0086 pthread_cond_init(&(l)->cond, NULL); \
0087 \
0088 (l)->active = true; \
0089 } while (0)
0090
0091 #define PMIX_DESTRUCT_LOCK(l) \
0092 do { \
0093 PMIX_DESTRUCT(&(l)->mutex); \
0094 pthread_cond_destroy(&(l)->cond); \
0095 } while (0)
0096
0097 #if PMIX_ENABLE_DEBUG
0098 # define PMIX_ACQUIRE_THREAD(lck) \
0099 do { \
0100 pmix_mutex_lock(&(lck)->mutex); \
0101 if (pmix_debug_threads) { \
0102 pmix_output(0, "Waiting for thread %s:%d", __FILE__, __LINE__); \
0103 } \
0104 while ((lck)->active) { \
0105 pmix_condition_wait(&(lck)->cond, &(lck)->mutex); \
0106 } \
0107 if (pmix_debug_threads) { \
0108 pmix_output(0, "Thread obtained %s:%d", __FILE__, __LINE__); \
0109 } \
0110 PMIX_ACQUIRE_OBJECT(lck); \
0111 (lck)->active = true; \
0112 } while (0)
0113 #else
0114 # define PMIX_ACQUIRE_THREAD(lck) \
0115 do { \
0116 pmix_mutex_lock(&(lck)->mutex); \
0117 while ((lck)->active) { \
0118 pmix_condition_wait(&(lck)->cond, &(lck)->mutex); \
0119 } \
0120 PMIX_ACQUIRE_OBJECT(lck); \
0121 (lck)->active = true; \
0122 } while (0)
0123 #endif
0124
0125 #if PMIX_ENABLE_DEBUG
0126 # define PMIX_WAIT_THREAD(lck) \
0127 do { \
0128 pmix_mutex_lock(&(lck)->mutex); \
0129 if (pmix_debug_threads) { \
0130 pmix_output(0, "Waiting for thread %s:%d", __FILE__, __LINE__); \
0131 } \
0132 while ((lck)->active) { \
0133 pmix_condition_wait(&(lck)->cond, &(lck)->mutex); \
0134 } \
0135 if (pmix_debug_threads) { \
0136 pmix_output(0, "Thread obtained %s:%d", __FILE__, __LINE__); \
0137 } \
0138 PMIX_ACQUIRE_OBJECT(lck); \
0139 pmix_mutex_unlock(&(lck)->mutex); \
0140 } while (0)
0141 #else
0142 # define PMIX_WAIT_THREAD(lck) \
0143 do { \
0144 pmix_mutex_lock(&(lck)->mutex); \
0145 while ((lck)->active) { \
0146 pmix_condition_wait(&(lck)->cond, &(lck)->mutex); \
0147 } \
0148 PMIX_ACQUIRE_OBJECT(lck); \
0149 pmix_mutex_unlock(&(lck)->mutex); \
0150 } while (0)
0151 #endif
0152
0153 #if PMIX_ENABLE_DEBUG
0154 # define PMIX_RELEASE_THREAD(lck) \
0155 do { \
0156 if (pmix_debug_threads) { \
0157 pmix_output(0, "Releasing thread %s:%d", __FILE__, __LINE__); \
0158 } \
0159 (lck)->active = false; \
0160 PMIX_POST_OBJECT(lck); \
0161 pmix_condition_broadcast(&(lck)->cond); \
0162 pmix_mutex_unlock(&(lck)->mutex); \
0163 } while (0)
0164 #else
0165 # define PMIX_RELEASE_THREAD(lck) \
0166 do { \
0167 (lck)->active = false; \
0168 PMIX_POST_OBJECT(lck); \
0169 pmix_condition_broadcast(&(lck)->cond); \
0170 pmix_mutex_unlock(&(lck)->mutex); \
0171 } while (0)
0172 #endif
0173
0174 #define PMIX_WAKEUP_THREAD(lck) \
0175 do { \
0176 pmix_mutex_lock(&(lck)->mutex); \
0177 (lck)->active = false; \
0178 PMIX_POST_OBJECT(lck); \
0179 pmix_condition_broadcast(&(lck)->cond); \
0180 pmix_mutex_unlock(&(lck)->mutex); \
0181 } while (0)
0182
0183
0184
0185
0186
0187
0188
0189 #define PMIX_POST_OBJECT(o) pmix_atomic_wmb()
0190
0191
0192
0193 #define PMIX_ACQUIRE_OBJECT(o) pmix_atomic_rmb()
0194
0195 PMIX_EXPORT int pmix_thread_start(pmix_thread_t *);
0196 PMIX_EXPORT int pmix_thread_join(pmix_thread_t *, void **thread_return);
0197 PMIX_EXPORT bool pmix_thread_self_compare(pmix_thread_t *);
0198 PMIX_EXPORT pmix_thread_t *pmix_thread_get_self(void);
0199 PMIX_EXPORT void pmix_thread_kill(pmix_thread_t *, int sig);
0200 PMIX_EXPORT void pmix_thread_set_main(void);
0201
0202 END_C_DECLS
0203
0204 #endif