Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-22 09:00:46

0001 /*
0002  * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
0003  *                         University Research and Technology
0004  *                         Corporation.  All rights reserved.
0005  * Copyright (c) 2004-2006 The University of Tennessee and The University
0006  *                         of Tennessee Research Foundation.  All rights
0007  *                         reserved.
0008  * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
0009  *                         University of Stuttgart.  All rights reserved.
0010  * Copyright (c) 2004-2005 The Regents of the University of California.
0011  *                         All rights reserved.
0012  * Copyright (c) 2010      Cisco Systems, Inc. All rights reserved.
0013  * Copyright (c) 2010      Oracle and/or its affiliates.  All rights reserved.
0014  * Copyright (c) 2015-2017 Research Organization for Information Science
0015  *                         and Technology (RIST). All rights reserved.
0016  * Copyright (c) 2017-2019 Intel, Inc.  All rights reserved.
0017  * Copyright (c) 2021-2025 Nanook Consulting  All rights reserved.
0018  * $COPYRIGHT$
0019  *
0020  * Additional copyrights may follow
0021  *
0022  * $HEADER$
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         /* take the lock */                         \
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 /* provide a macro for forward-proofing the shifting
0186  * of objects between threads - at some point, we
0187  * may revamp our threading model */
0188 
0189 /* post an object to another thread - for now, we
0190  * only have a memory barrier */
0191 #define PMIX_POST_OBJECT(o) pmix_atomic_wmb()
0192 
0193 /* acquire an object from another thread - for now,
0194  * we only have a memory barrier */
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 /* PMIX_THREAD_H */