This file is indexed.

/usr/include/mpich/opa_primitives.h is in libmpich-dev 3.2-6build1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
/*  
 *  (C) 2008 by Argonne National Laboratory.
 *      See COPYRIGHT in top-level directory.
 */

#ifndef OPA_PRIMITIVES_H_INCLUDED
#define OPA_PRIMITIVES_H_INCLUDED

#include "opa_config.h"
#include "opa_util.h"

/* Clean up some of the opa_config.h definitions.  This is a consequence
   of using the AX_PREFIX_CONFIG_H macro. Autoconf won't define inline
   or _opa_inline when a real "inline" works.  Since we are
   unconditionally using _opa_inline we must define it ourselves in this
   case. */
#ifndef _opa_inline
#define _opa_inline inline
#endif
#ifndef _opa_restrict
#define _opa_restrict restrict
#endif
#ifndef _opa_const
#define _opa_const const
#endif

/*
   Primitive atomic functions
   --------------------------

   The included file is responsible for defining the types of OPA_int_t and
   OPA_ptr_t as well as a set of functions for operating on these
   types.  If you have the following declaration:

       OPA_int_t atomic_var;

   Then in order for the emulation functions to compile, the underlying value of
   atomic_var should be accessible via:

       atomic_var.v;

   The same goes for OPA_ptr_t.

   The atomic functions that must be ported for each architecture: 

   static _opa_inline int   OPA_load_int(_opa_const OPA_int_t *ptr);
   static _opa_inline void  OPA_store_int(OPA_int_t *ptr, int val);
   static _opa_inline void *OPA_load_ptr(_opa_const OPA_ptr_t *ptr);
   static _opa_inline void  OPA_store_ptr(OPA_ptr_t *ptr, void *val);

   static _opa_inline void OPA_add_int(OPA_int_t *ptr, int val);
   static _opa_inline void OPA_incr_int(OPA_int_t *ptr);
   static _opa_inline void OPA_decr_int(OPA_int_t *ptr);

   static _opa_inline int OPA_decr_and_test_int(OPA_int_t *ptr);
   static _opa_inline int OPA_fetch_and_add_int(OPA_int_t *ptr, int val);
   static _opa_inline int OPA_fetch_and_incr_int(OPA_int_t *ptr);
   static _opa_inline int OPA_fetch_and_decr_int(OPA_int_t *ptr);

   static _opa_inline void *OPA_cas_ptr(OPA_ptr_t *ptr, void *oldv, void *newv);
   static _opa_inline int   OPA_cas_int(OPA_int_t *ptr, int oldv, int newv);

   static _opa_inline void *OPA_swap_ptr(OPA_ptr_t *ptr, void *val);
   static _opa_inline int   OPA_swap_int(OPA_int_t *ptr, int val);

   // (the memory barriers may be macros instead of inline functions)
   static _opa_inline void OPA_write_barrier();
   static _opa_inline void OPA_read_barrier();
   static _opa_inline void OPA_read_write_barrier();

   // Loads and stores with memory ordering guarantees (also may be macros):
   static _opa_inline int   OPA_load_acquire_int(_opa_const OPA_int_t *ptr);
   static _opa_inline void  OPA_store_release_int(OPA_int_t *ptr, int val);
   static _opa_inline void *OPA_load_acquire_ptr(_opa_const OPA_ptr_t *ptr);
   static _opa_inline void  OPA_store_release_ptr(OPA_ptr_t *ptr, void *val);

   // Compiler barrier, only preventing compiler reordering, *not* CPU
   // reordering (may be a macro):
   static _opa_inline void OPA_compiler_barrier();

   // The following need to be ported only for architectures supporting LL/SC:
   static _opa_inline int OPA_LL_int(OPA_int_t *ptr);
   static _opa_inline int OPA_SC_int(OPA_int_t *ptr, int val);
   static _opa_inline void *OPA_LL_ptr(OPA_ptr_t *ptr);
   static _opa_inline int OPA_SC_ptr(OPA_ptr_t *ptr, void *val);

   // Additionally, the following initializer macros must be defined:
   #define OPA_INT_T_INITIALIZER(val_) ...
   #define OPA_PTR_T_INITIALIZER(val_) ...

   // They should be useable as C89 static initializers like so:

   struct { int x; OPA_int_t y; OPA_ptr_t z; } foo = { 35, OPA_INT_T_INITIALIZER(1), OPA_PTR_T_INITIALIZER(NULL) };
*/

/* Include the appropriate header for the architecture */
#if defined(OPA_USE_UNSAFE_PRIMITIVES)
/* comes first to permit user overrides in the style of NDEBUG */
#include "primitives/opa_unsafe.h"
#elif   defined(OPA_HAVE_GCC_AND_POWERPC_ASM)
#include "primitives/opa_gcc_ppc.h"
#elif   defined(OPA_HAVE_GCC_AND_ARM_ASM)
#include "primitives/opa_gcc_arm.h"
#elif defined(OPA_HAVE_GCC_X86_32_64)
#include "primitives/opa_gcc_intel_32_64.h"
#elif defined(OPA_HAVE_GCC_X86_32_64_P3)
#include "primitives/opa_gcc_intel_32_64_p3.h"
#elif defined(OPA_HAVE_GCC_AND_IA64_ASM)
#include "primitives/opa_gcc_ia64.h"
#elif defined(OPA_HAVE_GCC_AND_SICORTEX_ASM)
#include "primitives/opa_gcc_sicortex.h"
#elif defined(OPA_HAVE_GCC_INTRINSIC_ATOMICS)
#include "primitives/opa_gcc_intrinsics.h"
#elif defined(OPA_HAVE_SUN_ATOMIC_OPS)
#include "primitives/opa_sun_atomic_ops.h"
#elif defined(OPA_HAVE_NT_INTRINSICS)
#include "primitives/opa_nt_intrinsics.h"
#elif defined(OPA_USE_LOCK_BASED_PRIMITIVES)
#include "primitives/opa_by_lock.h"
#else
#error no primitives implementation specified
#endif

/*
    This routine is needed because the MPIU_THREAD_XXX_CS_{ENTER,EXIT} macros do
    not provide synchronization across multiple processes, only across multiple
    threads within a process.  In order to safely emulate atomic operations on a
    shared memory region, we need a shared memory backed lock mechanism.

    This routine must be called by any subsystem that intends to use the atomic
    abstractions if the cpp directive OPA_USE_LOCK_BASED_PRIMITIVES is defined.  It must
    be called exactly once by _all_ processes, not just a single leader.  This
    function will initialize the contents of the lock variable if the caller
    specifies (isLeader==true).  Note that multiple initialization is forbidden
    by several lock implementations, especially pthreads.

    Inputs:
      shm_lock - A pointer to an allocated piece of shared memory that can hold
                 a mutex (e.g., pthread_mutex_t).  This is not portable to
                 non-pthreads systems at this time.
      isLeader - This boolean value should be set to true for exactly one
                 thread/process of the group that calls this function.
*/
#if defined(OPA_HAVE_PTHREAD_H)
#  include <pthread.h>
typedef pthread_mutex_t OPA_emulation_ipl_t;
int OPA_Interprocess_lock_init(OPA_emulation_ipl_t *shm_lock, int isLeader);
#endif


/* FIXME This should probably be pushed down into the platform-specific headers. */
#if defined(OPA_HAVE_SCHED_YIELD)
#  include <sched.h>
#  define OPA_busy_wait() sched_yield()
#else
#  define OPA_busy_wait() do { } while (0)
#endif

#endif /* defined(OPA_PRIMITIVES_H_INCLUDED) */