Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-22 10:47:27

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-2022 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         pthread_cond_init(&(l)->cond, NULL);       \
0087         /* coverity[missing_lock : FALSE] */       \
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 /* provide a macro for forward-proofing the shifting
0184  * of objects between threads - at some point, we
0185  * may revamp our threading model */
0186 
0187 /* post an object to another thread - for now, we
0188  * only have a memory barrier */
0189 #define PMIX_POST_OBJECT(o) pmix_atomic_wmb()
0190 
0191 /* acquire an object from another thread - for now,
0192  * we only have a memory barrier */
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 /* PMIX_THREAD_H */