"Fossies" - the Fresh Open Source Software Archive

Member "openpa-1.0.4/src/primitives/opa_by_lock.h" (5 Dec 2012, 5964 Bytes) of package /linux/misc/openpa-1.0.4.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "opa_by_lock.h" see the Fossies "Dox" file reference documentation.

    1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
    2 /*
    3  *  (C) 2008 by Argonne National Laboratory.
    4  *      See COPYRIGHT in top-level directory.
    5  */
    6 
    7 #ifndef OPA_BY_LOCK_H_INCLUDED
    8 #define OPA_BY_LOCK_H_INCLUDED
    9 
   10 /* FIXME For now we rely on pthreads for our IPC locks.  This is fairly
   11    portable, although it is obviously not 100% portable.  Some day when we
   12    refactor the OPA_Process_locks code we should be able to use that again. */
   13 #if defined(OPA_HAVE_PTHREAD_H)
   14 #include <pthread.h>
   15 
   16 /* defined in opa_primitives.c */
   17 extern pthread_mutex_t *OPA_emulation_lock;
   18 
   19 /* FIXME these make less sense now that OPA is not inside of MPICH2.  Is there a
   20    simpler name/scheme that could be used here instead? [goodell@ 2009-02-19] */
   21 #define OPA_IPC_SINGLE_CS_ENTER(msg)          \
   22     do {                                        \
   23         OPA_assert(OPA_emulation_lock);    \
   24         pthread_mutex_lock(OPA_emulation_lock);     \
   25     } while (0)
   26 
   27 #define OPA_IPC_SINGLE_CS_EXIT(msg)           \
   28     do {                                        \
   29         OPA_assert(OPA_emulation_lock);    \
   30         pthread_mutex_unlock(OPA_emulation_lock);   \
   31     } while (0)
   32 
   33 typedef struct { volatile int v;  } OPA_int_t;
   34 typedef struct { int * volatile v; } OPA_ptr_t;
   35 
   36 #define OPA_INT_T_INITIALIZER(val_) { (val_) }
   37 #define OPA_PTR_T_INITIALIZER(val_) { (val_) }
   38 
   39 /*
   40     Emulated atomic primitives
   41     --------------------------
   42 
   43     These are versions of the atomic primitives that emulate the proper behavior
   44     via the use of an inter-process lock.  For more information on their
   45     individual behavior, please see the comment on the corresponding top level
   46     function.
   47 
   48     In general, these emulated primitives should _not_ be used.  Most algorithms
   49     can be more efficiently implemented by putting most or all of the algorithm
   50     inside of a single critical section.  These emulated primitives exist to
   51     ensure that there is always a fallback if no machine-dependent version of a
   52     particular operation has been defined.  They also serve as a very readable
   53     reference for the exact semantics of our OPA_* ops.
   54 */
   55 
   56 static _opa_inline int OPA_load_int(_opa_const OPA_int_t *ptr)
   57 {
   58     int retval;
   59     OPA_IPC_SINGLE_CS_ENTER("atomic_add");
   60     retval = ptr->v;
   61     OPA_IPC_SINGLE_CS_EXIT("atomic_add");
   62     return retval;
   63 }
   64 
   65 static _opa_inline void OPA_store_int(OPA_int_t *ptr, int val)
   66 {
   67     OPA_IPC_SINGLE_CS_ENTER("atomic_add");
   68     ptr->v = val;
   69     OPA_IPC_SINGLE_CS_EXIT("atomic_add");
   70 }
   71 
   72 static _opa_inline void *OPA_load_ptr(_opa_const OPA_ptr_t *ptr)
   73 {
   74     int *retval;
   75     OPA_IPC_SINGLE_CS_ENTER("atomic_add");
   76     retval = ptr->v;
   77     OPA_IPC_SINGLE_CS_EXIT("atomic_add");
   78     return retval;
   79 }
   80 
   81 static _opa_inline void OPA_store_ptr(OPA_ptr_t *ptr, void *val)
   82 {
   83     OPA_IPC_SINGLE_CS_ENTER("atomic_add");
   84     ptr->v = val;
   85     OPA_IPC_SINGLE_CS_EXIT("atomic_add");
   86 }
   87 
   88 /* normal loads/stores are fully ordered, so just use them */
   89 #define OPA_load_acquire_int(ptr_)       OPA_load_int((ptr_))
   90 #define OPA_store_release_int(ptr_,val_) OPA_store_int((ptr_),(val_))
   91 #define OPA_load_acquire_ptr(ptr_)       OPA_load_ptr((ptr_))
   92 #define OPA_store_release_ptr(ptr_,val_) OPA_store_ptr((ptr_),(val_))
   93 
   94 static _opa_inline void OPA_add_int(OPA_int_t *ptr, int val)
   95 {
   96     OPA_IPC_SINGLE_CS_ENTER("atomic_add");
   97     ptr->v += val;
   98     OPA_IPC_SINGLE_CS_EXIT("atomic_add");
   99 }
  100 
  101 static _opa_inline void *OPA_cas_ptr(OPA_ptr_t *ptr, int *oldv, int *newv)
  102 {
  103     int *prev;
  104     OPA_IPC_SINGLE_CS_ENTER("atomic_cas");
  105     prev = ptr->v;
  106     if (prev == oldv) {
  107         ptr->v = newv;
  108     }
  109     OPA_IPC_SINGLE_CS_EXIT("atomic_cas");
  110     return prev;
  111 }
  112 
  113 static _opa_inline int OPA_cas_int(OPA_int_t *ptr, int oldv, int newv)
  114 {
  115     int prev;
  116     OPA_IPC_SINGLE_CS_ENTER("atomic_cas");
  117     prev = ptr->v;
  118     if (prev == oldv) {
  119         ptr->v = newv;
  120     }
  121     OPA_IPC_SINGLE_CS_EXIT("atomic_cas");
  122     return prev;
  123 }
  124 
  125 static _opa_inline int OPA_decr_and_test_int(OPA_int_t *ptr)
  126 {
  127     int new_val;
  128     OPA_IPC_SINGLE_CS_ENTER("atomic_decr_and_test");
  129     new_val = --(ptr->v);
  130     OPA_IPC_SINGLE_CS_EXIT("atomic_decr_and_test");
  131     return (0 == new_val);
  132 }
  133 
  134 static _opa_inline void OPA_decr_int(OPA_int_t *ptr)
  135 {
  136     OPA_IPC_SINGLE_CS_ENTER("atomic_decr");
  137     --(ptr->v);
  138     OPA_IPC_SINGLE_CS_EXIT("atomic_decr");
  139 }
  140 
  141 static _opa_inline int OPA_fetch_and_add_int(OPA_int_t *ptr, int val)
  142 {
  143     int prev;
  144     OPA_IPC_SINGLE_CS_ENTER("atomic_fetch_and_add");
  145     prev = ptr->v;
  146     ptr->v += val;
  147     OPA_IPC_SINGLE_CS_EXIT("atomic_fetch_and_add");
  148     return prev;
  149 }
  150 
  151 static _opa_inline int OPA_fetch_and_decr_int(OPA_int_t *ptr)
  152 {
  153     int prev;
  154     OPA_IPC_SINGLE_CS_ENTER("atomic_fetch_and_decr");
  155     prev = ptr->v;
  156     --(ptr->v);
  157     OPA_IPC_SINGLE_CS_EXIT("atomic_fetch_and_decr");
  158     return prev;
  159 }
  160 
  161 static _opa_inline int OPA_fetch_and_incr_int(OPA_int_t *ptr)
  162 {
  163     int prev;
  164     OPA_IPC_SINGLE_CS_ENTER("atomic_fetch_and_incr");
  165     prev = ptr->v;
  166     ++(ptr->v);
  167     OPA_IPC_SINGLE_CS_EXIT("atomic_fetch_and_incr");
  168     return prev;
  169 }
  170 
  171 static _opa_inline void OPA_incr_int(OPA_int_t *ptr)
  172 {
  173     OPA_IPC_SINGLE_CS_ENTER("atomic_incr");
  174     ++(ptr->v);
  175     OPA_IPC_SINGLE_CS_EXIT("atomic_incr");
  176 }
  177 
  178 static _opa_inline void *OPA_swap_ptr(OPA_ptr_t *ptr, void *val)
  179 {
  180     int *prev;
  181     OPA_IPC_SINGLE_CS_ENTER("atomic_swap_ptr");
  182     prev = ptr->v;
  183     ptr->v = val;
  184     OPA_IPC_SINGLE_CS_EXIT("atomic_swap_ptr");
  185     return prev;
  186 }
  187 
  188 static _opa_inline int OPA_swap_int(OPA_int_t *ptr, int val)
  189 {
  190     int prev;
  191     OPA_IPC_SINGLE_CS_ENTER("atomic_swap_int");
  192     prev = ptr->v;
  193     ptr->v = val;
  194     OPA_IPC_SINGLE_CS_EXIT("atomic_swap_int");
  195     return (int)prev;
  196 }
  197 
  198 /* lock/unlock provides barrier */
  199 #define OPA_write_barrier()      do {} while (0)
  200 #define OPA_read_barrier()       do {} while (0)
  201 #define OPA_read_write_barrier() do {} while (0)
  202 
  203 
  204 #endif /* defined(OPA_HAVE_PTHREAD_H) */
  205 #endif /* !defined(OPA_BY_LOCK_H_INCLUDED) */