ObjFW
atomic_sync_builtins.h
1 /*
2  * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017
3  * Jonathan Schleifer <js@heap.zone>
4  *
5  * All rights reserved.
6  *
7  * This file is part of ObjFW. It may be distributed under the terms of the
8  * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
9  * the packaging of this file.
10  *
11  * Alternatively, it may be distributed under the terms of the GNU General
12  * Public License, either version 2 or 3, which can be found in the file
13  * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
14  * file.
15  */
16 
17 static OF_INLINE int
18 of_atomic_int_add(volatile int *_Nonnull p, int i)
19 {
20  return __sync_add_and_fetch(p, i);
21 }
22 
23 static OF_INLINE int32_t
24 of_atomic_int32_add(volatile int32_t *_Nonnull p, int32_t i)
25 {
26  return __sync_add_and_fetch(p, i);
27 }
28 
29 static OF_INLINE void *_Nullable
30 of_atomic_ptr_add(void *volatile _Nullable *_Nonnull p, intptr_t i)
31 {
32  return __sync_add_and_fetch(p, (void *)i);
33 }
34 
35 static OF_INLINE int
36 of_atomic_int_sub(volatile int *_Nonnull p, int i)
37 {
38  return __sync_sub_and_fetch(p, i);
39 }
40 
41 static OF_INLINE int32_t
42 of_atomic_int32_sub(volatile int32_t *_Nonnull p, int32_t i)
43 {
44  return __sync_sub_and_fetch(p, i);
45 }
46 
47 static OF_INLINE void *_Nullable
48 of_atomic_ptr_sub(void *volatile _Nullable *_Nonnull p, intptr_t i)
49 {
50  return __sync_sub_and_fetch(p, (void *)i);
51 }
52 
53 static OF_INLINE int
54 of_atomic_int_inc(volatile int *_Nonnull p)
55 {
56  return __sync_add_and_fetch(p, 1);
57 }
58 
59 static OF_INLINE int32_t
60 of_atomic_int32_inc(volatile int32_t *_Nonnull p)
61 {
62  return __sync_add_and_fetch(p, 1);
63 }
64 
65 static OF_INLINE int
66 of_atomic_int_dec(volatile int *_Nonnull p)
67 {
68  return __sync_sub_and_fetch(p, 1);
69 }
70 
71 static OF_INLINE int32_t
72 of_atomic_int32_dec(volatile int32_t *_Nonnull p)
73 {
74  return __sync_sub_and_fetch(p, 1);
75 }
76 
77 static OF_INLINE unsigned int
78 of_atomic_int_or(volatile unsigned int *_Nonnull p, unsigned int i)
79 {
80  return __sync_or_and_fetch(p, i);
81 }
82 
83 static OF_INLINE uint32_t
84 of_atomic_int32_or(volatile uint32_t *_Nonnull p, uint32_t i)
85 {
86  return __sync_or_and_fetch(p, i);
87 }
88 
89 static OF_INLINE unsigned int
90 of_atomic_int_and(volatile unsigned int *_Nonnull p, unsigned int i)
91 {
92  return __sync_and_and_fetch(p, i);
93 }
94 
95 static OF_INLINE uint32_t
96 of_atomic_int32_and(volatile uint32_t *_Nonnull p, uint32_t i)
97 {
98  return __sync_and_and_fetch(p, i);
99 }
100 
101 static OF_INLINE unsigned int
102 of_atomic_int_xor(volatile unsigned int *_Nonnull p, unsigned int i)
103 {
104  return __sync_xor_and_fetch(p, i);
105 }
106 
107 static OF_INLINE uint32_t
108 of_atomic_int32_xor(volatile uint32_t *_Nonnull p, uint32_t i)
109 {
110  return __sync_xor_and_fetch(p, i);
111 }
112 
113 static OF_INLINE bool
114 of_atomic_int_cmpswap(volatile int *_Nonnull p, int o, int n)
115 {
116  return __sync_bool_compare_and_swap(p, o, n);
117 }
118 
119 static OF_INLINE bool
120 of_atomic_int32_cmpswap(volatile int32_t *_Nonnull p, int32_t o, int32_t n)
121 {
122  return __sync_bool_compare_and_swap(p, o, n);
123 }
124 
125 static OF_INLINE bool
126 of_atomic_ptr_cmpswap(void *volatile _Nullable *_Nonnull p,
127  void *_Nullable o, void *_Nullable n)
128 {
129  return __sync_bool_compare_and_swap(p, o, n);
130 }
131 
132 static OF_INLINE void
133 of_memory_barrier(void)
134 {
135  __sync_synchronize();
136 }
137 
138 static OF_INLINE void
139 of_memory_barrier_acquire(void)
140 {
141  __sync_synchronize();
142 }
143 
144 static OF_INLINE void
145 of_memory_barrier_release(void)
146 {
147  __sync_synchronize();
148 }