ObjFW
atomic_no_threads.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 (*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 (*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 (*(char *volatile *)p += i);
33 }
34 
35 static OF_INLINE int
36 of_atomic_int_sub(volatile int *_Nonnull p, int i)
37 {
38  return (*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 (*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 (*(char *volatile *)p -= i);
51 }
52 
53 static OF_INLINE int
54 of_atomic_int_inc(volatile int *_Nonnull p)
55 {
56  return ++*p;
57 }
58 
59 static OF_INLINE int32_t
60 of_atomic_int32_inc(volatile int32_t *_Nonnull p)
61 {
62  return ++*p;
63 }
64 
65 static OF_INLINE int
66 of_atomic_int_dec(volatile int *_Nonnull p)
67 {
68  return --*p;
69 }
70 
71 static OF_INLINE int32_t
72 of_atomic_int32_dec(volatile int32_t *_Nonnull p)
73 {
74  return --*p;
75 }
76 
77 static OF_INLINE unsigned int
78 of_atomic_int_or(volatile unsigned int *_Nonnull p, unsigned int i)
79 {
80  return (*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 (*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 (*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 (*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 (*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 (*p ^= i);
111 }
112 
113 static OF_INLINE bool
114 of_atomic_int_cmpswap(volatile int *_Nonnull p, int o, int n)
115 {
116  if (*p == o) {
117  *p = n;
118  return true;
119  }
120 
121  return false;
122 }
123 
124 static OF_INLINE bool
125 of_atomic_int32_cmpswap(volatile int32_t *_Nonnull p, int32_t o, int32_t n)
126 {
127  if (*p == o) {
128  *p = n;
129  return true;
130  }
131 
132  return false;
133 }
134 
135 static OF_INLINE bool
136 of_atomic_ptr_cmpswap(void *volatile _Nullable *_Nonnull p,
137  void *_Nullable o, void *_Nullable n)
138 {
139  if (*p == o) {
140  *p = n;
141  return true;
142  }
143 
144  return false;
145 }
146 
147 static OF_INLINE void
148 of_memory_barrier(void)
149 {
150  /* nop */
151 }
152 
153 static OF_INLINE void
154 of_memory_barrier_acquire(void)
155 {
156  /* nop */
157 }
158 
159 static OF_INLINE void
160 of_memory_barrier_release(void)
161 {
162  /* nop */
163 }