"Fossies" - the Fresh Open Source Software Archive

Member "openpa-1.0.4/src/opa_primitives.h" (5 Dec 2012, 6423 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_primitives.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_PRIMITIVES_H_INCLUDED
    8 #define OPA_PRIMITIVES_H_INCLUDED
    9 
   10 #include "opa_config.h"
   11 #include "opa_util.h"
   12 
   13 /* Clean up some of the opa_config.h definitions.  This is a consequence
   14    of using the AX_PREFIX_CONFIG_H macro. Autoconf won't define inline
   15    or _opa_inline when a real "inline" works.  Since we are
   16    unconditionally using _opa_inline we must define it ourselves in this
   17    case. */
   18 #ifndef _opa_inline
   19 #define _opa_inline inline
   20 #endif
   21 #ifndef _opa_restrict
   22 #define _opa_restrict restrict
   23 #endif
   24 #ifndef _opa_const
   25 #define _opa_const const
   26 #endif
   27 
   28 /*
   29    Primitive atomic functions
   30    --------------------------
   31 
   32    The included file is responsible for defining the types of OPA_int_t and
   33    OPA_ptr_t as well as a set of functions for operating on these
   34    types.  If you have the following declaration:
   35 
   36        OPA_int_t atomic_var;
   37 
   38    Then in order for the emulation functions to compile, the underlying value of
   39    atomic_var should be accessible via:
   40 
   41        atomic_var.v;
   42 
   43    The same goes for OPA_ptr_t.
   44 
   45    The atomic functions that must be ported for each architecture: 
   46 
   47    static _opa_inline int   OPA_load_int(_opa_const OPA_int_t *ptr);
   48    static _opa_inline void  OPA_store_int(OPA_int_t *ptr, int val);
   49    static _opa_inline void *OPA_load_ptr(_opa_const OPA_ptr_t *ptr);
   50    static _opa_inline void  OPA_store_ptr(OPA_ptr_t *ptr, void *val);
   51 
   52    static _opa_inline void OPA_add_int(OPA_int_t *ptr, int val);
   53    static _opa_inline void OPA_incr_int(OPA_int_t *ptr);
   54    static _opa_inline void OPA_decr_int(OPA_int_t *ptr);
   55 
   56    static _opa_inline int OPA_decr_and_test_int(OPA_int_t *ptr);
   57    static _opa_inline int OPA_fetch_and_add_int(OPA_int_t *ptr, int val);
   58    static _opa_inline int OPA_fetch_and_incr_int(OPA_int_t *ptr);
   59    static _opa_inline int OPA_fetch_and_decr_int(OPA_int_t *ptr);
   60 
   61    static _opa_inline void *OPA_cas_ptr(OPA_ptr_t *ptr, void *oldv, void *newv);
   62    static _opa_inline int   OPA_cas_int(OPA_int_t *ptr, int oldv, int newv);
   63 
   64    static _opa_inline void *OPA_swap_ptr(OPA_ptr_t *ptr, void *val);
   65    static _opa_inline int   OPA_swap_int(OPA_int_t *ptr, int val);
   66 
   67    // (the memory barriers may be macros instead of inline functions)
   68    static _opa_inline void OPA_write_barrier();
   69    static _opa_inline void OPA_read_barrier();
   70    static _opa_inline void OPA_read_write_barrier();
   71 
   72    // Loads and stores with memory ordering guarantees (also may be macros):
   73    static _opa_inline int   OPA_load_acquire_int(_opa_const OPA_int_t *ptr);
   74    static _opa_inline void  OPA_store_release_int(OPA_int_t *ptr, int val);
   75    static _opa_inline void *OPA_load_acquire_ptr(_opa_const OPA_ptr_t *ptr);
   76    static _opa_inline void  OPA_store_release_ptr(OPA_ptr_t *ptr, void *val);
   77 
   78    // Compiler barrier, only preventing compiler reordering, *not* CPU
   79    // reordering (may be a macro):
   80    static _opa_inline void OPA_compiler_barrier();
   81 
   82    // The following need to be ported only for architectures supporting LL/SC:
   83    static _opa_inline int OPA_LL_int(OPA_int_t *ptr);
   84    static _opa_inline int OPA_SC_int(OPA_int_t *ptr, int val);
   85    static _opa_inline void *OPA_LL_ptr(OPA_ptr_t *ptr);
   86    static _opa_inline int OPA_SC_ptr(OPA_ptr_t *ptr, void *val);
   87 
   88    // Additionally, the following initializer macros must be defined:
   89    #define OPA_INT_T_INITIALIZER(val_) ...
   90    #define OPA_PTR_T_INITIALIZER(val_) ...
   91 
   92    // They should be useable as C89 static initializers like so:
   93 
   94    struct { int x; OPA_int_t y; OPA_ptr_t z; } foo = { 35, OPA_INT_T_INITIALIZER(1), OPA_PTR_T_INITIALIZER(NULL) };
   95 */
   96 
   97 /* Include the appropriate header for the architecture */
   98 #if defined(OPA_USE_UNSAFE_PRIMITIVES)
   99 /* comes first to permit user overrides in the style of NDEBUG */
  100 #include "primitives/opa_unsafe.h"
  101 #elif   defined(OPA_HAVE_GCC_AND_POWERPC_ASM)
  102 #include "primitives/opa_gcc_ppc.h"
  103 #elif   defined(OPA_HAVE_GCC_AND_ARM_ASM)
  104 #include "primitives/opa_gcc_arm.h"
  105 #elif defined(OPA_HAVE_GCC_X86_32_64)
  106 #include "primitives/opa_gcc_intel_32_64.h"
  107 #elif defined(OPA_HAVE_GCC_X86_32_64_P3)
  108 #include "primitives/opa_gcc_intel_32_64_p3.h"
  109 #elif defined(OPA_HAVE_GCC_AND_IA64_ASM)
  110 #include "primitives/opa_gcc_ia64.h"
  111 #elif defined(OPA_HAVE_GCC_AND_SICORTEX_ASM)
  112 #include "primitives/opa_gcc_sicortex.h"
  113 #elif defined(OPA_HAVE_GCC_INTRINSIC_ATOMICS)
  114 #include "primitives/opa_gcc_intrinsics.h"
  115 #elif defined(OPA_HAVE_SUN_ATOMIC_OPS)
  116 #include "primitives/opa_sun_atomic_ops.h"
  117 #elif defined(OPA_HAVE_NT_INTRINSICS)
  118 #include "primitives/opa_nt_intrinsics.h"
  119 #elif defined(OPA_USE_LOCK_BASED_PRIMITIVES)
  120 #include "primitives/opa_by_lock.h"
  121 #else
  122 #error no primitives implementation specified
  123 #endif
  124 
  125 /*
  126     This routine is needed because the MPIU_THREAD_XXX_CS_{ENTER,EXIT} macros do
  127     not provide synchronization across multiple processes, only across multiple
  128     threads within a process.  In order to safely emulate atomic operations on a
  129     shared memory region, we need a shared memory backed lock mechanism.
  130 
  131     This routine must be called by any subsystem that intends to use the atomic
  132     abstractions if the cpp directive OPA_USE_LOCK_BASED_PRIMITIVES is defined.  It must
  133     be called exactly once by _all_ processes, not just a single leader.  This
  134     function will initialize the contents of the lock variable if the caller
  135     specifies (isLeader==true).  Note that multiple initialization is forbidden
  136     by several lock implementations, especially pthreads.
  137 
  138     Inputs:
  139       shm_lock - A pointer to an allocated piece of shared memory that can hold
  140                  a mutex (e.g., pthread_mutex_t).  This is not portable to
  141                  non-pthreads systems at this time.
  142       isLeader - This boolean value should be set to true for exactly one
  143                  thread/process of the group that calls this function.
  144 */
  145 #if defined(OPA_HAVE_PTHREAD_H)
  146 #  include <pthread.h>
  147 typedef pthread_mutex_t OPA_emulation_ipl_t;
  148 int OPA_Interprocess_lock_init(OPA_emulation_ipl_t *shm_lock, int isLeader);
  149 #endif
  150 
  151 
  152 /* FIXME This should probably be pushed down into the platform-specific headers. */
  153 #if defined(OPA_HAVE_SCHED_YIELD)
  154 #  include <sched.h>
  155 #  define OPA_busy_wait() sched_yield()
  156 #else
  157 #  define OPA_busy_wait() do { } while (0)
  158 #endif
  159 
  160 #endif /* defined(OPA_PRIMITIVES_H_INCLUDED) */