libmetal
atomic.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * 1. Redistributions of source code must retain the above copyright notice,
8  * this list of conditions and the following disclaimer.
9  *
10  * 2. Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following disclaimer in the documentation
12  * and/or other materials provided with the distribution.
13  *
14  * 3. Neither the name of Xilinx nor the names of its contributors may be used
15  * to endorse or promote products derived from this software without
16  * specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28  * POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 /*
32  * @file gcc/atomic.h
33  * @brief GCC specific atomic primitives for libmetal.
34  */
35 
36 #ifndef __METAL_GCC_ATOMIC__H__
37 #define __METAL_GCC_ATOMIC__H__
38 
39 #ifdef __cplusplus
40 extern "C" {
41 #endif
42 
43 typedef int atomic_flag;
44 typedef char atomic_char;
45 typedef unsigned char atomic_uchar;
46 typedef short atomic_short;
47 typedef unsigned short atomic_ushort;
48 typedef int atomic_int;
49 typedef unsigned int atomic_uint;
50 typedef long atomic_long;
51 typedef unsigned long atomic_ulong;
52 typedef long long atomic_llong;
53 typedef unsigned long long atomic_ullong;
54 
55 #define ATOMIC_FLAG_INIT 0
56 #define ATOMIC_VAR_INIT(VAL) (VAL)
57 
58 typedef enum {
65 } memory_order;
66 
67 #define atomic_flag_test_and_set(FLAG) \
68  __sync_lock_test_and_set((FLAG), 1)
69 #define atomic_flag_test_and_set_explicit(FLAG, MO) \
70  atomic_flag_test_and_set(FLAG)
71 #define atomic_flag_clear(FLAG) \
72  __sync_lock_release((FLAG))
73 #define atomic_flag_clear_explicit(FLAG, MO) \
74  atomic_flag_clear(FLAG)
75 #define atomic_init(OBJ, VAL) \
76  do { *(OBJ) = (VAL); } while (0)
77 #define atomic_is_lock_free(OBJ) \
78  (sizeof(*(OBJ)) <= sizeof(long))
79 #define atomic_store(OBJ, VAL) \
80  do { *(OBJ) = (VAL); __sync_synchronize(); } while (0)
81 #define atomic_store_explicit(OBJ, VAL, MO) \
82  atomic_store((OBJ), (VAL))
83 #define atomic_load(OBJ) \
84  ({ __sync_synchronize(); *(OBJ); })
85 #define atomic_load_explicit(OBJ, MO) \
86  atomic_load(OBJ)
87 #define atomic_exchange(OBJ, DES) \
88  ({ \
89  typeof(OBJ) obj = (OBJ); \
90  typeof(*obj) des = (DES); \
91  typeof(*obj) expval; \
92  typeof(*obj) oldval = atomic_load(obj); \
93  do { \
94  expval = oldval; \
95  oldval = __sync_val_compare_and_swap( \
96  obj, expval, des); \
97  } while (oldval != expval); \
98  oldval; \
99  })
100 #define atomic_exchange_explicit(OBJ, DES, MO) \
101  atomic_exchange((OBJ), (DES))
102 #define atomic_compare_exchange_strong(OBJ, EXP, DES) \
103  ({ \
104  typeof(OBJ) obj = (OBJ); \
105  typeof(EXP) exp = (EXP); \
106  typeof(*obj) expval = *exp; \
107  typeof(*obj) oldval = __sync_val_compare_and_swap( \
108  obj, expval, (DES)); \
109  *exp = oldval; \
110  oldval == expval; \
111  })
112 #define atomic_compare_exchange_strong_explicit(OBJ, EXP, DES, MO) \
113  atomic_compare_exchange_strong((OBJ), (EXP), (DES))
114 #define atomic_compare_exchange_weak(OBJ, EXP, DES) \
115  atomic_compare_exchange_strong((OBJ), (EXP), (DES))
116 #define atomic_compare_exchange_weak_explicit(OBJ, EXP, DES, MO) \
117  atomic_compare_exchange_weak((OBJ), (EXP), (DES))
118 #define atomic_fetch_add(OBJ, VAL) \
119  __sync_fetch_and_add((OBJ), (VAL))
120 #define atomic_fetch_add_explicit(OBJ, VAL, MO) \
121  atomic_fetch_add((OBJ), (VAL))
122 #define atomic_fetch_sub(OBJ, VAL) \
123  __sync_fetch_and_sub((OBJ), (VAL))
124 #define atomic_fetch_sub_explicit(OBJ, VAL, MO) \
125  atomic_fetch_sub((OBJ), (VAL))
126 #define atomic_fetch_or(OBJ, VAL) \
127  __sync_fetch_and_or((OBJ), (VAL))
128 #define atomic_fetch_or_explicit(OBJ, VAL, MO) \
129  atomic_fetch_or((OBJ), (VAL))
130 #define atomic_fetch_xor(OBJ, VAL) \
131  __sync_fetch_and_xor((OBJ), (VAL))
132 #define atomic_fetch_xor_explicit(OBJ, VAL, MO) \
133  atomic_fetch_xor((OBJ), (VAL))
134 #define atomic_fetch_and(OBJ, VAL) \
135  __sync_fetch_and_and((OBJ), (VAL))
136 #define atomic_fetch_and_explicit(OBJ, VAL, MO) \
137  atomic_fetch_and((OBJ), (VAL))
138 #define atomic_thread_fence(MO) \
139  __sync_synchronize()
140 #define atomic_signal_fence(MO) \
141  __sync_synchronize()
142 
143 #ifdef __cplusplus
144 }
145 #endif
146 
147 #endif /* __METAL_GCC_ATOMIC__H__ */
unsigned short atomic_ushort
Definition: atomic.h:47
long atomic_long
Definition: atomic.h:50
Definition: atomic.h:63
Definition: atomic.h:64
memory_order
Definition: atomic.h:58
short atomic_short
Definition: atomic.h:46
Definition: atomic.h:59
char atomic_char
Definition: atomic.h:44
Definition: atomic.h:60
unsigned char atomic_uchar
Definition: atomic.h:45
unsigned long atomic_ulong
Definition: atomic.h:51
long long atomic_llong
Definition: atomic.h:52
unsigned long long atomic_ullong
Definition: atomic.h:53
unsigned int atomic_uint
Definition: atomic.h:49
Definition: atomic.h:62
int atomic_flag
Definition: atomic.h:43
int atomic_int
Definition: atomic.h:48
Definition: atomic.h:61