1 /* 2 * Copyright (C) by Argonne National Laboratory 3 * See COPYRIGHT in top-level directory 4 */ 5 6 #ifndef MPL_ATOMIC_H_INCLUDED 7 #define MPL_ATOMIC_H_INCLUDED 8 9 #include "mplconfig.h" 10 #include <stdint.h> 11 12 typedef struct MPL_atomic_int_t MPL_atomic_int_t; 13 typedef struct MPL_atomic_int32_t MPL_atomic_int32_t; 14 typedef struct MPL_atomic_uint32_t MPL_atomic_uint32_t; 15 typedef struct MPL_atomic_int64_t MPL_atomic_int64_t; 16 typedef struct MPL_atomic_uint64_t MPL_atomic_uint64_t; 17 typedef struct MPL_atomic_ptr_t MPL_atomic_ptr_t; 18 19 /* By default, we use stronger atomic sematics for load and store. However, 20 * the relaxed semantics still can be used where it deemed approprate. 21 */ 22 #define MPL_atomic_load_int MPL_atomic_acquire_load_int 23 #define MPL_atomic_load_int32 MPL_atomic_acquire_load_int32 24 #define MPL_atomic_load_uint32 MPL_atomic_acquire_load_uint32 25 #define MPL_atomic_load_int64 MPL_atomic_acquire_load_int64 26 #define MPL_atomic_load_uint64 MPL_atomic_acquire_load_uint64 27 #define MPL_atomic_load_ptr MPL_atomic_acquire_load_ptr 28 #define MPL_atomic_store_int MPL_atomic_release_store_int 29 #define MPL_atomic_store_int32 MPL_atomic_release_store_int32 30 #define MPL_atomic_store_uint32 MPL_atomic_release_store_uint32 31 #define MPL_atomic_store_int64 MPL_atomic_release_store_int64 32 #define MPL_atomic_store_uint64 MPL_atomic_release_store_uint64 33 #define MPL_atomic_store_ptr MPL_atomic_release_store_ptr 34 35 /* Forward declarations of atomic functions */ 36 /* MPL_atomic_relaxed_load */ 37 static int MPL_atomic_relaxed_load_int(const MPL_atomic_int_t * ptr); 38 static int32_t MPL_atomic_relaxed_load_int32(const MPL_atomic_int32_t * ptr); 39 static uint32_t MPL_atomic_relaxed_load_uint32(const MPL_atomic_uint32_t * ptr); 40 static int64_t MPL_atomic_relaxed_load_int64(const MPL_atomic_int64_t * ptr); 41 static uint64_t MPL_atomic_relaxed_load_uint64(const MPL_atomic_uint64_t * ptr); 42 static void *MPL_atomic_relaxed_load_ptr(const MPL_atomic_ptr_t * ptr); 43 /* MPL_atomic_acquire_load */ 44 static int MPL_atomic_acquire_load_int(const MPL_atomic_int_t * ptr); 45 static int32_t MPL_atomic_acquire_load_int32(const MPL_atomic_int32_t * ptr); 46 static uint32_t MPL_atomic_acquire_load_uint32(const MPL_atomic_uint32_t * ptr); 47 static int64_t MPL_atomic_acquire_load_int64(const MPL_atomic_int64_t * ptr); 48 static uint64_t MPL_atomic_acquire_load_uint64(const MPL_atomic_uint64_t * ptr); 49 static void *MPL_atomic_acquire_load_ptr(const MPL_atomic_ptr_t * ptr); 50 /* MPL_atomic_relaxed_store */ 51 static void MPL_atomic_relaxed_store_int(MPL_atomic_int_t * ptr, int val); 52 static void MPL_atomic_relaxed_store_int32(MPL_atomic_int32_t * ptr, int32_t val); 53 static void MPL_atomic_relaxed_store_uint32(MPL_atomic_uint32_t * ptr, uint32_t val); 54 static void MPL_atomic_relaxed_store_int64(MPL_atomic_int64_t * ptr, int64_t val); 55 static void MPL_atomic_relaxed_store_uint64(MPL_atomic_uint64_t * ptr, uint64_t val); 56 static void MPL_atomic_relaxed_store_ptr(MPL_atomic_ptr_t * ptr, void *val); 57 /* MPL_atomic_release_store */ 58 static void MPL_atomic_release_store_int(MPL_atomic_int_t * ptr, int val); 59 60 static void MPL_atomic_release_store_int32(MPL_atomic_int32_t * ptr, int32_t val); 61 static void MPL_atomic_release_store_uint32(MPL_atomic_uint32_t * ptr, uint32_t val); 62 static void MPL_atomic_release_store_int64(MPL_atomic_int64_t * ptr, int64_t val); 63 static void MPL_atomic_release_store_uint64(MPL_atomic_uint64_t * ptr, uint64_t val); 64 static void MPL_atomic_release_store_ptr(MPL_atomic_ptr_t * ptr, void *val); 65 /* MPL_atomic_swap */ 66 static int MPL_atomic_swap_int(MPL_atomic_int_t * ptr, int val); 67 static int32_t MPL_atomic_swap_int32(MPL_atomic_int32_t * ptr, int32_t val); 68 static uint32_t MPL_atomic_swap_uint32(MPL_atomic_uint32_t * ptr, uint32_t val); 69 static int64_t MPL_atomic_swap_int64(MPL_atomic_int64_t * ptr, int64_t val); 70 static uint64_t MPL_atomic_swap_uint64(MPL_atomic_uint64_t * ptr, uint64_t val); 71 static void *MPL_atomic_swap_ptr(MPL_atomic_ptr_t * ptr, void *val); 72 /* MPL_atomic_cas (compare-and-swap) */ 73 static int MPL_atomic_cas_int(MPL_atomic_int_t * ptr, int oldv, int newv); 74 static int32_t MPL_atomic_cas_int32(MPL_atomic_int32_t * ptr, int32_t oldv, int32_t newv); 75 static uint32_t MPL_atomic_cas_uint32(MPL_atomic_uint32_t * ptr, uint32_t oldv, uint32_t newv); 76 static int64_t MPL_atomic_cas_int64(MPL_atomic_int64_t * ptr, int64_t oldv, int64_t newv); 77 static uint64_t MPL_atomic_cas_uint64(MPL_atomic_uint64_t * ptr, uint64_t oldv, uint64_t newv); 78 static void *MPL_atomic_cas_ptr(MPL_atomic_ptr_t * ptr, void *oldv, void *newv); 79 /* MPL_atomic_fetch_add */ 80 static int MPL_atomic_fetch_add_int(MPL_atomic_int_t * ptr, int val); 81 static int32_t MPL_atomic_fetch_add_int32(MPL_atomic_int32_t * ptr, int32_t val); 82 static uint32_t MPL_atomic_fetch_add_uint32(MPL_atomic_uint32_t * ptr, uint32_t val); 83 static int64_t MPL_atomic_fetch_add_int64(MPL_atomic_int64_t * ptr, int64_t val); 84 static uint64_t MPL_atomic_fetch_add_uint64(MPL_atomic_uint64_t * ptr, uint64_t val); 85 /* MPL_atomic_fetch_sub */ 86 static int MPL_atomic_fetch_sub_int(MPL_atomic_int_t * ptr, int val); 87 static int32_t MPL_atomic_fetch_sub_int32(MPL_atomic_int32_t * ptr, int32_t val); 88 static uint32_t MPL_atomic_fetch_sub_uint32(MPL_atomic_uint32_t * ptr, uint32_t val); 89 static int64_t MPL_atomic_fetch_sub_int64(MPL_atomic_int64_t * ptr, int64_t val); 90 static uint64_t MPL_atomic_fetch_sub_uint64(MPL_atomic_uint64_t * ptr, uint64_t val); 91 92 /* MPL_atomic_barrier */ 93 static void MPL_atomic_write_barrier(void); 94 static void MPL_atomic_read_barrier(void); 95 static void MPL_atomic_read_write_barrier(void); 96 static void MPL_atomic_compiler_barrier(void); 97 98 #if defined(MPL_USE_NO_ATOMIC_PRIMITIVES) 99 #include "mpl_atomic_none.h" 100 #elif defined(MPL_HAVE_C11_ATOMICS) 101 #include "mpl_atomic_c11.h" 102 #elif defined(MPL_HAVE_GCC_INTRINSIC_ATOMIC) 103 #include "mpl_atomic_gcc_atomic.h" 104 #elif defined(MPL_HAVE_GCC_INTRINSIC_SYNC) 105 #include "mpl_atomic_gcc_sync.h" 106 #elif defined(MPL_HAVE_NT_INTRINSICS) 107 #include "mpl_atomic_nt_intrinsics.h" 108 #elif defined(MPL_USE_LOCK_BASED_PRIMITIVES) 109 #include "mpl_atomic_by_lock.h" 110 #else 111 #error no primitives implementation specified 112 #endif 113 114 #endif /* MPL_ATOMIC_H_INCLUDED */ 115