File indexing completed on 2026-09-22 09:00:46
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 \
0087 pmix_mutex_lock(&(l)->mutex); \
0088 pthread_cond_init(&(l)->cond, NULL); \
0089 (l)->active = true; \
0090 pmix_mutex_unlock(&(l)->mutex); \
0091 } while (0)
0092
0093 #define PMIX_DESTRUCT_LOCK(l) \
0094 do { \
0095 PMIX_DESTRUCT(&(l)->mutex); \
0096 pthread_cond_destroy(&(l)->cond); \
0097 } while (0)
0098
0099 #if PMIX_ENABLE_DEBUG
0100 # define PMIX_ACQUIRE_THREAD(lck) \
0101 do { \
0102 pmix_mutex_lock(&(lck)->mutex); \
0103 if (pmix_debug_threads) { \
0104 pmix_output(0, "Waiting for thread %s:%d", __FILE__, __LINE__); \
0105 } \
0106 while ((lck)->active) { \
0107 pmix_condition_wait(&(lck)->cond, &(lck)->mutex); \
0108 } \
0109 if (pmix_debug_threads) { \
0110 pmix_output(0, "Thread obtained %s:%d", __FILE__, __LINE__); \
0111 } \
0112 PMIX_ACQUIRE_OBJECT(lck); \
0113 (lck)->active = true; \
0114 } while (0)
0115 #else
0116 # define PMIX_ACQUIRE_THREAD(lck) \
0117 do { \
0118 pmix_mutex_lock(&(lck)->mutex); \
0119 while ((lck)->active) { \
0120 pmix_condition_wait(&(lck)->cond, &(lck)->mutex); \
0121 } \
0122 PMIX_ACQUIRE_OBJECT(lck); \
0123 (lck)->active = true; \
0124 } while (0)
0125 #endif
0126
0127 #if PMIX_ENABLE_DEBUG
0128 # define PMIX_WAIT_THREAD(lck) \
0129 do { \
0130 pmix_mutex_lock(&(lck)->mutex); \
0131 if (pmix_debug_threads) { \
0132 pmix_output(0, "Waiting for thread %s:%d", __FILE__, __LINE__); \
0133 } \
0134 while ((lck)->active) { \
0135 pmix_condition_wait(&(lck)->cond, &(lck)->mutex); \
0136 } \
0137 if (pmix_debug_threads) { \
0138 pmix_output(0, "Thread obtained %s:%d", __FILE__, __LINE__); \
0139 } \
0140 PMIX_ACQUIRE_OBJECT(lck); \
0141 pmix_mutex_unlock(&(lck)->mutex); \
0142 } while (0)
0143 #else
0144 # define PMIX_WAIT_THREAD(lck) \
0145 do { \
0146 pmix_mutex_lock(&(lck)->mutex); \
0147 while ((lck)->active) { \
0148 pmix_condition_wait(&(lck)->cond, &(lck)->mutex); \
0149 } \
0150 PMIX_ACQUIRE_OBJECT(lck); \
0151 pmix_mutex_unlock(&(lck)->mutex); \
0152 } while (0)
0153 #endif
0154
0155 #if PMIX_ENABLE_DEBUG
0156 # define PMIX_RELEASE_THREAD(lck) \
0157 do { \
0158 if (pmix_debug_threads) { \
0159 pmix_output(0, "Releasing thread %s:%d", __FILE__, __LINE__); \
0160 } \
0161 (lck)->active = false; \
0162 PMIX_POST_OBJECT(lck); \
0163 pmix_condition_signal(&(lck)->cond); \
0164 pmix_mutex_unlock(&(lck)->mutex); \
0165 } while (0)
0166 #else
0167 # define PMIX_RELEASE_THREAD(lck) \
0168 do { \
0169 (lck)->active = false; \
0170 PMIX_POST_OBJECT(lck); \
0171 pmix_condition_signal(&(lck)->cond); \
0172 pmix_mutex_unlock(&(lck)->mutex); \
0173 } while (0)
0174 #endif
0175
0176 #define PMIX_WAKEUP_THREAD(lck) \
0177 do { \
0178 pmix_mutex_lock(&(lck)->mutex); \
0179 (lck)->active = false; \
0180 PMIX_POST_OBJECT(lck); \
0181 pmix_condition_signal(&(lck)->cond); \
0182 pmix_mutex_unlock(&(lck)->mutex); \
0183 } while (0)
0184
0185
0186
0187
0188
0189
0190
0191 #define PMIX_POST_OBJECT(o) pmix_atomic_wmb()
0192
0193
0194
0195 #define PMIX_ACQUIRE_OBJECT(o) pmix_atomic_rmb()
0196
0197 PMIX_EXPORT int pmix_thread_start(pmix_thread_t *);
0198 PMIX_EXPORT int pmix_thread_join(pmix_thread_t *, void **thread_return);
0199 PMIX_EXPORT bool pmix_thread_self_compare(pmix_thread_t *);
0200 PMIX_EXPORT pmix_thread_t *pmix_thread_get_self(void);
0201 PMIX_EXPORT void pmix_thread_kill(pmix_thread_t *, int sig);
0202 PMIX_EXPORT void pmix_thread_set_main(void);
0203
0204 END_C_DECLS
0205
0206 #endif