root/opal/mca/pmix/pmix4x/pmix/src/threads/wait_sync.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. pmix_sync_wait_st
  2. pmix_wait_sync_update

   1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
   2 /*
   3  * Copyright (c) 2014-2016 The University of Tennessee and The University
   4  *                         of Tennessee Research Foundation.  All rights
   5  *                         reserved.
   6  * Copyright (c) 2016      Los Alamos National Security, LLC. All rights
   7  *                         reserved.
   8  * Copyright (c) 2016      Mellanox Technologies. All rights reserved.
   9  * Copyright (c) 2016      Research Organization for Information Science
  10  *                         and Technology (RIST). All rights reserved.
  11  * Copyright (c) 2017-2018 Intel, Inc. All rights reserved.
  12  * $COPYRIGHT$
  13  *
  14  * Additional copyrights may follow
  15  *
  16  * $HEADER$
  17  */
  18 
  19 #if !defined(PMIX_THREADS_WAIT_SYNC_H)
  20 #define PMIX_THREADS_WAIT_SYNC_H
  21 
  22 #include "src/include/prefetch.h"
  23 #include "src/atomics/sys/atomic.h"
  24 #include "src/threads/threads.h"
  25 #include "src/util/error.h"
  26 #include <pthread.h>
  27 
  28 BEGIN_C_DECLS
  29 
  30 typedef struct pmix_wait_sync_t {
  31     pmix_atomic_int32_t count;
  32     int32_t status;
  33     pthread_cond_t condition;
  34     pthread_mutex_t lock;
  35     struct pmix_wait_sync_t *next;
  36     struct pmix_wait_sync_t *prev;
  37     volatile bool signaling;
  38 } pmix_wait_sync_t;
  39 
  40 #define REQUEST_PENDING        (void*)0L
  41 #define REQUEST_COMPLETED      (void*)1L
  42 
  43 #define PMIX_SYNC_WAIT(sync)    pmix_sync_wait_mt (sync)
  44 
  45 /* The loop in release handles a race condition between the signaling
  46  * thread and the destruction of the condition variable. The signaling
  47  * member will be set to false after the final signaling thread has
  48  * finished operating on the sync object. This is done to avoid
  49  * extra atomics in the signalling function and keep it as fast
  50  * as possible. Note that the race window is small so spinning here
  51  * is more optimal than sleeping since this macro is called in
  52  * the critical path. */
  53 #define PMIX_WAIT_SYNC_RELEASE(sync)                  \
  54         while ((sync)->signaling) {                   \
  55             continue;                                 \
  56         }                                             \
  57         pthread_cond_destroy(&(sync)->condition);     \
  58         pthread_mutex_destroy(&(sync)->lock);
  59 
  60 #define PMIX_WAIT_SYNC_RELEASE_NOWAIT(sync)           \
  61         pthread_cond_destroy(&(sync)->condition);     \
  62         pthread_mutex_destroy(&(sync)->lock);
  63 
  64 
  65 #define PMIX_WAIT_SYNC_SIGNAL(sync)                   \
  66         pthread_mutex_lock(&(sync->lock));            \
  67         pthread_cond_signal(&sync->condition);        \
  68         pthread_mutex_unlock(&(sync->lock));          \
  69         sync->signaling = false;
  70 
  71 #define PMIX_WAIT_SYNC_SIGNALLED(sync){               \
  72         (sync)->signaling = false;                    \
  73 }
  74 
  75 PMIX_EXPORT int pmix_sync_wait_mt(pmix_wait_sync_t *sync);
  76 static inline int pmix_sync_wait_st (pmix_wait_sync_t *sync)
  77 {
  78     while (sync->count > 0) {
  79     }
  80 
  81     return sync->status;
  82 }
  83 
  84 
  85 #define PMIX_WAIT_SYNC_INIT(sync,c)                             \
  86     do {                                                        \
  87         (sync)->count = (c);                                    \
  88         (sync)->next = NULL;                                    \
  89         (sync)->prev = NULL;                                    \
  90         (sync)->status = 0;                                     \
  91         (sync)->signaling = (0 != (c));                         \
  92         pthread_cond_init (&(sync)->condition, NULL);           \
  93         pthread_mutex_init (&(sync)->lock, NULL);               \
  94     } while(0)
  95 
  96 /**
  97  * Update the status of the synchronization primitive. If an error is
  98  * reported the synchronization is completed and the signal
  99  * triggered. The status of the synchronization will be reported to
 100  * the waiting threads.
 101  */
 102 static inline void pmix_wait_sync_update(pmix_wait_sync_t *sync,
 103                                          int updates, int status)
 104 {
 105     if( PMIX_LIKELY(PMIX_SUCCESS == status) ) {
 106         if( 0 != (PMIX_THREAD_ADD_FETCH32(&sync->count, -updates)) ) {
 107             return;
 108         }
 109     } else {
 110         /* this is an error path so just use the atomic */
 111         sync->status = PMIX_ERROR;
 112         pmix_atomic_wmb ();
 113         pmix_atomic_swap_32 (&sync->count, 0);
 114     }
 115     PMIX_WAIT_SYNC_SIGNAL(sync);
 116 }
 117 
 118 END_C_DECLS
 119 
 120 #endif /* defined(PMIX_THREADS_WAIT_SYNC_H) */

/* [<][>][^][v][top][bottom][index][help] */