ObjFW
Loading...
Searching...
No Matches
OFAtomic.h
1/*
2 * Copyright (c) 2008-2024 Jonathan Schleifer <js@nil.im>
3 *
4 * All rights reserved.
5 *
6 * This program is free software: you can redistribute it and/or modify it
7 * under the terms of the GNU Lesser General Public License version 3.0 only,
8 * as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
13 * version 3.0 for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public License
16 * version 3.0 along with this program. If not, see
17 * <https://www.gnu.org/licenses/>.
18 */
19
20#include <stdlib.h>
21
22#import "macros.h"
23
24#ifndef OF_HAVE_ATOMIC_OPS
25# error No atomic operations available!
26#endif
27
28#if !defined(OF_HAVE_THREADS)
29static OF_INLINE int
30OFAtomicIntAdd(volatile int *_Nonnull p, int i)
31{
32 return (*p += i);
33}
34
35static OF_INLINE int32_t
36OFAtomicInt32Add(volatile int32_t *_Nonnull p, int32_t i)
37{
38 return (*p += i);
39}
40
41static OF_INLINE void *_Nullable
42OFAtomicPointerAdd(void *volatile _Nullable *_Nonnull p, intptr_t i)
43{
44 return (*(char *volatile *)p += i);
45}
46
47static OF_INLINE int
48OFAtomicIntSubtract(volatile int *_Nonnull p, int i)
49{
50 return (*p -= i);
51}
52
53static OF_INLINE int32_t
54OFAtomicInt32Subtract(volatile int32_t *_Nonnull p, int32_t i)
55{
56 return (*p -= i);
57}
58
59static OF_INLINE void *_Nullable
60OFAtomicPointerSubtract(void *volatile _Nullable *_Nonnull p, intptr_t i)
61{
62 return (*(char *volatile *)p -= i);
63}
64
65static OF_INLINE int
66OFAtomicIntIncrease(volatile int *_Nonnull p)
67{
68 return ++*p;
69}
70
71static OF_INLINE int32_t
72OFAtomicInt32Increase(volatile int32_t *_Nonnull p)
73{
74 return ++*p;
75}
76
77static OF_INLINE int
78OFAtomicIntDecrease(volatile int *_Nonnull p)
79{
80 return --*p;
81}
82
83static OF_INLINE int32_t
84OFAtomicInt32Decrease(volatile int32_t *_Nonnull p)
85{
86 return --*p;
87}
88
89static OF_INLINE unsigned int
90OFAtomicIntOr(volatile unsigned int *_Nonnull p, unsigned int i)
91{
92 return (*p |= i);
93}
94
95static OF_INLINE uint32_t
96OFAtomicInt32Or(volatile uint32_t *_Nonnull p, uint32_t i)
97{
98 return (*p |= i);
99}
100
101static OF_INLINE unsigned int
102OFAtomicIntAnd(volatile unsigned int *_Nonnull p, unsigned int i)
103{
104 return (*p &= i);
105}
106
107static OF_INLINE uint32_t
108OFAtomicInt32And(volatile uint32_t *_Nonnull p, uint32_t i)
109{
110 return (*p &= i);
111}
112
113static OF_INLINE unsigned int
114OFAtomicIntXor(volatile unsigned int *_Nonnull p, unsigned int i)
115{
116 return (*p ^= i);
117}
118
119static OF_INLINE uint32_t
120OFAtomicInt32Xor(volatile uint32_t *_Nonnull p, uint32_t i)
121{
122 return (*p ^= i);
123}
124
125static OF_INLINE bool
126OFAtomicIntCompareAndSwap(volatile int *_Nonnull p, int o, int n)
127{
128 if (*p == o) {
129 *p = n;
130 return true;
131 }
132
133 return false;
134}
135
136static OF_INLINE bool
137OFAtomicInt32CompareAndSwap(volatile int32_t *_Nonnull p, int32_t o, int32_t n)
138{
139 if (*p == o) {
140 *p = n;
141 return true;
142 }
143
144 return false;
145}
146
147static OF_INLINE bool
148OFAtomicPointerCompareAndSwap(void *volatile _Nullable *_Nonnull p,
149 void *_Nullable o, void *_Nullable n)
150{
151 if (*p == o) {
152 *p = n;
153 return true;
154 }
155
156 return false;
157}
158
159static OF_INLINE void
160OFMemoryBarrier(void)
161{
162 /* nop */
163}
164
165static OF_INLINE void
166OFAcquireMemoryBarrier(void)
167{
168 /* nop */
169}
170
171static OF_INLINE void
172OFReleaseMemoryBarrier(void)
173{
174 /* nop */
175}
176#elif (defined(OF_AMD64) || defined(OF_X86)) && defined(__GNUC__)
177# import "platform/x86/OFAtomic.h"
178#elif defined(OF_POWERPC) && defined(__GNUC__) && !defined(__APPLE_CC__) && \
179 !defined(OF_AIX)
180# import "platform/PowerPC/OFAtomic.h"
181#elif defined(OF_HAVE_ATOMIC_BUILTINS)
182# import "platform/GCC4.7/OFAtomic.h"
183#elif defined(OF_HAVE_SYNC_BUILTINS)
184# import "platform/GCC4/OFAtomic.h"
185#elif defined(OF_HAVE_OSATOMIC)
186# import "platform/macOS/OFAtomic.h"
187#else
188# error No atomic operations available!
189#endif