/usr/include/atomic_ops/sysdeps/ibmc/powerpc.h is in libatomic-ops-dev 7.4.4-3.
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 | /* FIXME. This is only a placeholder for the AIX compiler. */
/* It doesn't work. Please send a patch. */
/* Memory model documented at http://www-106.ibm.com/developerworks/ */
/* eserver/articles/archguide.html and (clearer) */
/* http://www-106.ibm.com/developerworks/eserver/articles/powerpc.html. */
/* There appears to be no implicit ordering between any kind of */
/* independent memory references. */
/* Architecture enforces some ordering based on control dependence. */
/* I don't know if that could help. */
/* Data-dependent loads are always ordered. */
/* Based on the above references, eieio is intended for use on */
/* uncached memory, which we don't support. It does not order loads */
/* from cached memory. */
/* Thanks to Maged Michael, Doug Lea, and Roger Hoover for helping to */
/* track some of this down and correcting my misunderstandings. -HB */
#include "../all_aligned_atomic_load_store.h"
void AO_sync(void);
#pragma mc_func AO_sync { "7c0004ac" }
#ifdef __NO_LWSYNC__
# define AO_lwsync AO_sync
#else
void AO_lwsync(void);
#pragma mc_func AO_lwsync { "7c2004ac" }
#endif
#define AO_nop_write() AO_lwsync()
#define AO_HAVE_nop_write
#define AO_nop_read() AO_lwsync()
#define AO_HAVE_nop_read
/* We explicitly specify load_acquire and store_release, since these */
/* rely on the fact that lwsync is also a LoadStore barrier. */
AO_INLINE AO_t
AO_load_acquire(const volatile AO_t *addr)
{
AO_t result = *addr;
AO_lwsync();
return result;
}
#define AO_HAVE_load_acquire
AO_INLINE void
AO_store_release(volatile AO_t *addr, AO_t value)
{
AO_lwsync();
*addr = value;
}
#define AO_HAVE_store_release
#ifndef AO_PREFER_GENERALIZED
/* This is similar to the code in the garbage collector. Deleting */
/* this and having it synthesized from compare_and_swap would probably */
/* only cost us a load immediate instruction. */
/*AO_INLINE AO_TS_VAL_t
AO_test_and_set(volatile AO_TS_t *addr) {
# error FIXME Implement me
}
#define AO_HAVE_test_and_set*/
AO_INLINE AO_TS_VAL_t
AO_test_and_set_acquire(volatile AO_TS_t *addr) {
AO_TS_VAL_t result = AO_test_and_set(addr);
AO_lwsync();
return result;
}
#define AO_HAVE_test_and_set_acquire
AO_INLINE AO_TS_VAL_t
AO_test_and_set_release(volatile AO_TS_t *addr) {
AO_lwsync();
return AO_test_and_set(addr);
}
#define AO_HAVE_test_and_set_release
AO_INLINE AO_TS_VAL_t
AO_test_and_set_full(volatile AO_TS_t *addr) {
AO_TS_VAL_t result;
AO_lwsync();
result = AO_test_and_set(addr);
AO_lwsync();
return result;
}
#define AO_HAVE_test_and_set_full
#endif /* !AO_PREFER_GENERALIZED */
/*AO_INLINE AO_t
AO_fetch_compare_and_swap(volatile AO_t *addr, AO_t old_val, AO_t new_val)
{
# error FIXME Implement me
}
#define AO_HAVE_fetch_compare_and_swap*/
AO_INLINE AO_t
AO_fetch_compare_and_swap_acquire(volatile AO_t *addr, AO_t old_val,
AO_t new_val)
{
AO_t result = AO_fetch_compare_and_swap(addr, old_val, new_val);
AO_lwsync();
return result;
}
#define AO_HAVE_fetch_compare_and_swap_acquire
AO_INLINE AO_t
AO_fetch_compare_and_swap_release(volatile AO_t *addr, AO_t old_val,
AO_t new_val)
{
AO_lwsync();
return AO_fetch_compare_and_swap(addr, old_val, new_val);
}
#define AO_HAVE_fetch_compare_and_swap_release
AO_INLINE AO_t
AO_fetch_compare_and_swap_full(volatile AO_t *addr, AO_t old_val,
AO_t new_val)
{
AO_t result;
AO_lwsync();
result = AO_fetch_compare_and_swap(addr, old_val, new_val);
AO_lwsync();
return result;
}
#define AO_HAVE_fetch_compare_and_swap_full
/* TODO: Implement AO_fetch_and_add, AO_and/or/xor directly. */
|