952726c121
This now passes the loop test, and so we believe it resolves the random hangs in finalize. Changes in PMIx master that are included here: * Fixed a bug in the PMIx_Get logic * Fixed self-notification procedure * Made pmix_output functions thread safe * Fixed a number of thread safety issues * Updated configury to use 'uname -n' when hostname is unavailable Work on cleaning up the event handler thread safety problem Rarely used functions, but protect them anyway Fix the last part of the intercomm problem Ensure we don't cover any PMIx calls with the framework-level lock. Protect against NULL argv comm_spawn Signed-off-by: Ralph Castain <rhc@open-mpi.org>
160 строки
6.6 KiB
C
160 строки
6.6 KiB
C
/*
|
|
* Copyright (c) 2017 Intel, Inc. All rights reserved.
|
|
* $COPYRIGHT$
|
|
*
|
|
* Additional copyrights may follow
|
|
*
|
|
* $HEADER$
|
|
*/
|
|
|
|
#ifndef ORTE_THREADS_H
|
|
#define ORTE_THREADS_H
|
|
|
|
#include "orte_config.h"
|
|
|
|
#include "opal/sys/atomic.h"
|
|
#include "opal/threads/threads.h"
|
|
|
|
/* provide macros for forward-proofing the shifting
|
|
* of objects between threads - at some point, we
|
|
* may revamp our threading model */
|
|
|
|
/* post an object to another thread - for now, we
|
|
* only have a memory barrier */
|
|
#define ORTE_POST_OBJECT(o) opal_atomic_wmb()
|
|
|
|
/* acquire an object from another thread - for now,
|
|
* we only have a memory barrier */
|
|
#define ORTE_ACQUIRE_OBJECT(o) opal_atomic_rmb()
|
|
|
|
#define orte_condition_wait(a,b) pthread_cond_wait(a, &(b)->m_lock_pthread)
|
|
typedef pthread_cond_t orte_condition_t;
|
|
#define orte_condition_broadcast(a) pthread_cond_broadcast(a)
|
|
#define orte_condition_signal(a) pthread_cond_signal(a)
|
|
#define ORTE_CONDITION_STATIC_INIT PTHREAD_COND_INITIALIZER
|
|
|
|
/* define a threadshift macro */
|
|
#define ORTE_THREADSHIFT(x, eb, f, p) \
|
|
do { \
|
|
opal_event_set((eb), &((x)->ev), -1, OPAL_EV_WRITE, (f), (x)); \
|
|
opal_event_set_priority(&((x)->ev), (p)); \
|
|
ORTE_POST_OBJECT((x)); \
|
|
opal_event_active(&((x)->ev), OPAL_EV_WRITE, 1); \
|
|
} while(0)
|
|
|
|
typedef struct {
|
|
opal_mutex_t mutex;
|
|
orte_condition_t cond;
|
|
volatile bool active;
|
|
} orte_lock_t;
|
|
|
|
#define ORTE_CONSTRUCT_LOCK(l) \
|
|
do { \
|
|
OBJ_CONSTRUCT(&(l)->mutex, opal_mutex_t); \
|
|
pthread_cond_init(&(l)->cond, NULL); \
|
|
(l)->active = true; \
|
|
} while(0)
|
|
|
|
#define ORTE_DESTRUCT_LOCK(l) \
|
|
do { \
|
|
OBJ_DESTRUCT(&(l)->mutex); \
|
|
pthread_cond_destroy(&(l)->cond); \
|
|
} while(0)
|
|
|
|
|
|
#if OPAL_ENABLE_DEBUG
|
|
#define ORTE_ACQUIRE_THREAD(lck) \
|
|
do { \
|
|
opal_mutex_lock(&(lck)->mutex); \
|
|
if (opal_debug_threads) { \
|
|
opal_output(0, "Waiting for thread %s:%d", \
|
|
__FILE__, __LINE__); \
|
|
} \
|
|
while ((lck)->active) { \
|
|
orte_condition_wait(&(lck)->cond, &(lck)->mutex); \
|
|
} \
|
|
if (opal_debug_threads) { \
|
|
opal_output(0, "Thread obtained %s:%d", \
|
|
__FILE__, __LINE__); \
|
|
} \
|
|
(lck)->active = true; \
|
|
OPAL_ACQUIRE_OBJECT(lck); \
|
|
} while(0)
|
|
#else
|
|
#define ORTE_ACQUIRE_THREAD(lck) \
|
|
do { \
|
|
opal_mutex_lock(&(lck)->mutex); \
|
|
while ((lck)->active) { \
|
|
orte_condition_wait(&(lck)->cond, &(lck)->mutex); \
|
|
} \
|
|
(lck)->active = true; \
|
|
OPAL_ACQUIRE_OBJECT(lck); \
|
|
} while(0)
|
|
#endif
|
|
|
|
|
|
#if OPAL_ENABLE_DEBUG
|
|
#define ORTE_WAIT_THREAD(lck) \
|
|
do { \
|
|
opal_mutex_lock(&(lck)->mutex); \
|
|
if (opal_debug_threads) { \
|
|
opal_output(0, "Waiting for thread %s:%d", \
|
|
__FILE__, __LINE__); \
|
|
} \
|
|
while ((lck)->active) { \
|
|
orte_condition_wait(&(lck)->cond, &(lck)->mutex); \
|
|
} \
|
|
if (opal_debug_threads) { \
|
|
opal_output(0, "Thread obtained %s:%d", \
|
|
__FILE__, __LINE__); \
|
|
} \
|
|
OPAL_ACQUIRE_OBJECT(&lck); \
|
|
opal_mutex_unlock(&(lck)->mutex); \
|
|
} while(0)
|
|
#else
|
|
#define ORTE_WAIT_THREAD(lck) \
|
|
do { \
|
|
opal_mutex_lock(&(lck)->mutex); \
|
|
while ((lck)->active) { \
|
|
orte_condition_wait(&(lck)->cond, &(lck)->mutex); \
|
|
} \
|
|
OPAL_ACQUIRE_OBJECT(lck); \
|
|
opal_mutex_unlock(&(lck)->mutex); \
|
|
} while(0)
|
|
#endif
|
|
|
|
|
|
#if OPAL_ENABLE_DEBUG
|
|
#define ORTE_RELEASE_THREAD(lck) \
|
|
do { \
|
|
if (opal_debug_threads) { \
|
|
opal_output(0, "Releasing thread %s:%d", \
|
|
__FILE__, __LINE__); \
|
|
} \
|
|
(lck)->active = false; \
|
|
OPAL_POST_OBJECT(lck); \
|
|
orte_condition_broadcast(&(lck)->cond); \
|
|
opal_mutex_unlock(&(lck)->mutex); \
|
|
} while(0)
|
|
#else
|
|
#define ORTE_RELEASE_THREAD(lck) \
|
|
do { \
|
|
(lck)->active = false; \
|
|
OPAL_POST_OBJECT(lck); \
|
|
orte_condition_broadcast(&(lck)->cond); \
|
|
opal_mutex_unlock(&(lck)->mutex); \
|
|
} while(0)
|
|
#endif
|
|
|
|
|
|
#define ORTE_WAKEUP_THREAD(lck) \
|
|
do { \
|
|
opal_mutex_lock(&(lck)->mutex); \
|
|
(lck)->active = false; \
|
|
OPAL_POST_OBJECT(lck); \
|
|
orte_condition_broadcast(&(lck)->cond); \
|
|
opal_mutex_unlock(&(lck)->mutex); \
|
|
} while(0)
|
|
|
|
#endif /* ORTE_THREADS_H */
|