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 file is part of ObjFW. It may be distributed under the terms of the
7 * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
8 * the packaging of this file.
9 *
10 * Alternatively, it may be distributed under the terms of the GNU General
11 * Public License, either version 2 or 3, which can be found in the file
12 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
13 * file.
14 */
15
16#include <stdlib.h>
17
18#import "macros.h"
19
20#ifndef OF_HAVE_ATOMIC_OPS
21# error No atomic operations available!
22#endif
23
24#if !defined(OF_HAVE_THREADS)
25static OF_INLINE int
26OFAtomicIntAdd(volatile int *_Nonnull p, int i)
27{
28 return (*p += i);
29}
30
31static OF_INLINE int32_t
32OFAtomicInt32Add(volatile int32_t *_Nonnull p, int32_t i)
33{
34 return (*p += i);
35}
36
37static OF_INLINE void *_Nullable
38OFAtomicPointerAdd(void *volatile _Nullable *_Nonnull p, intptr_t i)
39{
40 return (*(char *volatile *)p += i);
41}
42
43static OF_INLINE int
44OFAtomicIntSubtract(volatile int *_Nonnull p, int i)
45{
46 return (*p -= i);
47}
48
49static OF_INLINE int32_t
50OFAtomicInt32Subtract(volatile int32_t *_Nonnull p, int32_t i)
51{
52 return (*p -= i);
53}
54
55static OF_INLINE void *_Nullable
56OFAtomicPointerSubtract(void *volatile _Nullable *_Nonnull p, intptr_t i)
57{
58 return (*(char *volatile *)p -= i);
59}
60
61static OF_INLINE int
62OFAtomicIntIncrease(volatile int *_Nonnull p)
63{
64 return ++*p;
65}
66
67static OF_INLINE int32_t
68OFAtomicInt32Increase(volatile int32_t *_Nonnull p)
69{
70 return ++*p;
71}
72
73static OF_INLINE int
74OFAtomicIntDecrease(volatile int *_Nonnull p)
75{
76 return --*p;
77}
78
79static OF_INLINE int32_t
80OFAtomicInt32Decrease(volatile int32_t *_Nonnull p)
81{
82 return --*p;
83}
84
85static OF_INLINE unsigned int
86OFAtomicIntOr(volatile unsigned int *_Nonnull p, unsigned int i)
87{
88 return (*p |= i);
89}
90
91static OF_INLINE uint32_t
92OFAtomicInt32Or(volatile uint32_t *_Nonnull p, uint32_t i)
93{
94 return (*p |= i);
95}
96
97static OF_INLINE unsigned int
98OFAtomicIntAnd(volatile unsigned int *_Nonnull p, unsigned int i)
99{
100 return (*p &= i);
101}
102
103static OF_INLINE uint32_t
104OFAtomicInt32And(volatile uint32_t *_Nonnull p, uint32_t i)
105{
106 return (*p &= i);
107}
108
109static OF_INLINE unsigned int
110OFAtomicIntXor(volatile unsigned int *_Nonnull p, unsigned int i)
111{
112 return (*p ^= i);
113}
114
115static OF_INLINE uint32_t
116OFAtomicInt32Xor(volatile uint32_t *_Nonnull p, uint32_t i)
117{
118 return (*p ^= i);
119}
120
121static OF_INLINE bool
122OFAtomicIntCompareAndSwap(volatile int *_Nonnull p, int o, int n)
123{
124 if (*p == o) {
125 *p = n;
126 return true;
127 }
128
129 return false;
130}
131
132static OF_INLINE bool
133OFAtomicInt32CompareAndSwap(volatile int32_t *_Nonnull p, int32_t o, int32_t n)
134{
135 if (*p == o) {
136 *p = n;
137 return true;
138 }
139
140 return false;
141}
142
143static OF_INLINE bool
144OFAtomicPointerCompareAndSwap(void *volatile _Nullable *_Nonnull p,
145 void *_Nullable o, void *_Nullable n)
146{
147 if (*p == o) {
148 *p = n;
149 return true;
150 }
151
152 return false;
153}
154
155static OF_INLINE void
156OFMemoryBarrier(void)
157{
158 /* nop */
159}
160
161static OF_INLINE void
162OFAcquireMemoryBarrier(void)
163{
164 /* nop */
165}
166
167static OF_INLINE void
168OFReleaseMemoryBarrier(void)
169{
170 /* nop */
171}
172#elif (defined(OF_AMD64) || defined(OF_X86)) && defined(__GNUC__)
173# import "platform/x86/OFAtomic.h"
174#elif defined(OF_POWERPC) && defined(__GNUC__) && !defined(__APPLE_CC__) && \
175 !defined(OF_AIX)
176# import "platform/PowerPC/OFAtomic.h"
177#elif defined(OF_HAVE_ATOMIC_BUILTINS)
178# import "platform/GCC4.7/OFAtomic.h"
179#elif defined(OF_HAVE_SYNC_BUILTINS)
180# import "platform/GCC4/OFAtomic.h"
181#elif defined(OF_HAVE_OSATOMIC)
182# import "platform/macOS/OFAtomic.h"
183#else
184# error No atomic operations available!
185#endif