ObjFW
Loading...
Searching...
No Matches
OFAtomic.h
1/*
2 * Copyright (c) 2008-2026 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 void *_Nullable
36OFAtomicPointerAdd(void *volatile _Nullable *_Nonnull p, intptr_t i)
37{
38 return (*(char *volatile *)p += i);
39}
40
41static OF_INLINE int
42OFAtomicIntSubtract(volatile int *_Nonnull p, int i)
43{
44 return (*p -= i);
45}
46
47static OF_INLINE void *_Nullable
48OFAtomicPointerSubtract(void *volatile _Nullable *_Nonnull p, intptr_t i)
49{
50 return (*(char *volatile *)p -= i);
51}
52
53static OF_INLINE int
54OFAtomicIntIncrease(volatile int *_Nonnull p)
55{
56 return ++*p;
57}
58
59static OF_INLINE int
60OFAtomicIntDecrease(volatile int *_Nonnull p)
61{
62 return --*p;
63}
64
65static OF_INLINE unsigned int
66OFAtomicIntOr(volatile unsigned int *_Nonnull p, unsigned int i)
67{
68 return (*p |= i);
69}
70
71static OF_INLINE unsigned int
72OFAtomicIntAnd(volatile unsigned int *_Nonnull p, unsigned int i)
73{
74 return (*p &= i);
75}
76
77static OF_INLINE bool
78OFAtomicIntCompareAndSwap(volatile int *_Nonnull p, int o, int n)
79{
80 if (*p == o) {
81 *p = n;
82 return true;
83 }
84
85 return false;
86}
87
88static OF_INLINE bool
89OFAtomicPointerCompareAndSwap(void *volatile _Nullable *_Nonnull p,
90 void *_Nullable o, void *_Nullable n)
91{
92 if (*p == o) {
93 *p = n;
94 return true;
95 }
96
97 return false;
98}
99
100static OF_INLINE void
101OFMemoryBarrier(void)
102{
103 /* nop */
104}
105
106static OF_INLINE void
107OFAcquireMemoryBarrier(void)
108{
109 /* nop */
110}
111
112static OF_INLINE void
113OFReleaseMemoryBarrier(void)
114{
115 /* nop */
116}
117#elif (defined(OF_AMD64) || defined(OF_X86)) && defined(__GNUC__)
118# import "platform/x86/OFAtomic.h"
119#elif defined(OF_POWERPC) && defined(__GNUC__) && !defined(__APPLE_CC__) && \
120 !defined(OF_AIX)
121# import "platform/PowerPC/OFAtomic.h"
122#elif defined(OF_HAVE_ATOMIC_BUILTINS)
123# import "platform/GCC4.7/OFAtomic.h"
124#elif defined(OF_HAVE_SYNC_BUILTINS)
125# import "platform/GCC4/OFAtomic.h"
126#elif defined(OF_HAVE_OSATOMIC)
127# import "platform/macOS/OFAtomic.h"
128#else
129# error No atomic operations available!
130#endif