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