Skip to content

Commit 0d5e8bf

Browse files
committed
Add docs.
1 parent 3d7877a commit 0d5e8bf

1 file changed

Lines changed: 124 additions & 1 deletion

File tree

lib/std/atomic.c3

Lines changed: 124 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
// a copy of which can be found in the LICENSE_STDLIB file.
44
module std::atomic::types;
55

6+
<*
7+
A wrapper providing atomic load, store and read-modify-write operations over a
8+
single value of `Type`. All operations default to SEQ_CONSISTENT ordering.
9+
*>
610
struct Atomic <Type>
711
{
812
Type data;
@@ -30,8 +34,17 @@ macro void Atomic.store(&self, Type value, AtomicOrdering $ordering = SEQ_CONSIS
3034
}
3135

3236
<*
33-
Atomically compare the value with `*expected` if equal, replace it with `desired`
37+
Atomically compare the value with `*expected`: if equal, replace it with `desired`
3438
and return true. Otherwise write the current value into `*expected` and return false.
39+
40+
@param [&inout] expected : "On entry the value to compare against; on a failed exchange it receives the current value."
41+
@param desired : "The value to store if the comparison succeeds."
42+
@param $success : "Memory ordering applied when the exchange succeeds, defaults to SEQ_CONSISTENT."
43+
@param $failure : "Memory ordering applied when the exchange fails, defaults to SEQ_CONSISTENT."
44+
@return "True if the value matched `*expected` and was replaced, false otherwise."
45+
46+
@require $success != NOT_ATOMIC && $success != UNORDERED : "Invalid success ordering."
47+
@require $failure != RELEASE && $failure != ACQUIRE_RELEASE : "Invalid failure ordering."
3548
*>
3649
macro bool Atomic.compare_exchange(&self, Type* expected, Type desired, AtomicOrdering $success = SEQ_CONSISTENT, AtomicOrdering $failure = SEQ_CONSISTENT)
3750
{
@@ -41,66 +54,170 @@ macro bool Atomic.compare_exchange(&self, Type* expected, Type desired, AtomicOr
4154
return false;
4255
}
4356

57+
<*
58+
Atomically add `value` to the stored value.
59+
60+
@param value : "The value to add."
61+
@param $ordering : "Memory ordering, defaults to SEQ_CONSISTENT."
62+
@return "The previous value, before the addition."
63+
@require $ordering != NOT_ATOMIC && $ordering != UNORDERED : "Invalid ordering for a read-modify-write."
64+
*>
4465
macro Type Atomic.add(&self, Type value, AtomicOrdering $ordering = SEQ_CONSISTENT)
4566
{
4667
return atomic::fetch_add(&self.data, value, $ordering);
4768
}
4869

70+
<*
71+
Atomically subtract `value` from the stored value.
72+
73+
@param value : "The value to subtract."
74+
@param $ordering : "Memory ordering, defaults to SEQ_CONSISTENT."
75+
@return "The previous value, before the subtraction."
76+
@require $ordering != NOT_ATOMIC && $ordering != UNORDERED : "Invalid ordering for a read-modify-write."
77+
*>
4978
macro Type Atomic.sub(&self, Type value, AtomicOrdering $ordering = SEQ_CONSISTENT)
5079
{
5180
return atomic::fetch_sub(&self.data, value, $ordering);
5281
}
5382

83+
<*
84+
Atomically multiply the stored value by `value`, using a compare-exchange loop.
85+
86+
@param value : "The value to multiply by."
87+
@param $ordering : "Memory ordering, defaults to SEQ_CONSISTENT."
88+
@return "The previous value, before the multiplication."
89+
@require $ordering != NOT_ATOMIC && $ordering != UNORDERED : "Invalid ordering for a read-modify-write."
90+
*>
5491
macro Type Atomic.mul(&self, Type value, AtomicOrdering $ordering = SEQ_CONSISTENT)
5592
{
5693
return atomic::fetch_mul(&self.data, value, $ordering);
5794
}
5895

96+
<*
97+
Atomically divide the stored value by `value`, using a compare-exchange loop.
98+
99+
@param value : "The value to divide by."
100+
@param $ordering : "Memory ordering, defaults to SEQ_CONSISTENT."
101+
@return "The previous value, before the division."
102+
@require $ordering != NOT_ATOMIC && $ordering != UNORDERED : "Invalid ordering for a read-modify-write."
103+
*>
59104
macro Type Atomic.div(&self, Type value, AtomicOrdering $ordering = SEQ_CONSISTENT)
60105
{
61106
return atomic::fetch_div(&self.data, value, $ordering);
62107
}
63108

109+
<*
110+
Atomically replace the stored value with the maximum of it and `value`.
111+
112+
@param value : "The value to compare against."
113+
@param $ordering : "Memory ordering, defaults to SEQ_CONSISTENT."
114+
@return "The previous value, before the operation."
115+
@require $ordering != NOT_ATOMIC && $ordering != UNORDERED : "Invalid ordering for a read-modify-write."
116+
*>
64117
macro Type Atomic.max(&self, Type value, AtomicOrdering $ordering = SEQ_CONSISTENT)
65118
{
66119
return atomic::fetch_max(&self.data, value, $ordering);
67120
}
68121

122+
<*
123+
Atomically replace the stored value with the minimum of it and `value`.
124+
125+
@param value : "The value to compare against."
126+
@param $ordering : "Memory ordering, defaults to SEQ_CONSISTENT."
127+
@return "The previous value, before the operation."
128+
@require $ordering != NOT_ATOMIC && $ordering != UNORDERED : "Invalid ordering for a read-modify-write."
129+
*>
69130
macro Type Atomic.min(&self, Type value, AtomicOrdering $ordering = SEQ_CONSISTENT)
70131
{
71132
return atomic::fetch_min(&self.data, value, $ordering);
72133
}
73134

135+
<*
136+
Atomically bitwise-or the stored value with `value`. Not available for floats.
137+
138+
@param value : "The value to or with."
139+
@param $ordering : "Memory ordering, defaults to SEQ_CONSISTENT."
140+
@return "The previous value, before the operation."
141+
@require $ordering != NOT_ATOMIC && $ordering != UNORDERED : "Invalid ordering for a read-modify-write."
142+
*>
74143
macro Type Atomic.or(&self, Type value, AtomicOrdering $ordering = SEQ_CONSISTENT) @if(types::flat_kind(Type) != FLOAT)
75144
{
76145
return atomic::fetch_or(&self.data, value, $ordering);
77146
}
78147

148+
<*
149+
Atomically bitwise-xor the stored value with `value`. Not available for floats.
150+
151+
@param value : "The value to xor with."
152+
@param $ordering : "Memory ordering, defaults to SEQ_CONSISTENT."
153+
@return "The previous value, before the operation."
154+
@require $ordering != NOT_ATOMIC && $ordering != UNORDERED : "Invalid ordering for a read-modify-write."
155+
*>
79156
macro Type Atomic.xor(&self, Type value, AtomicOrdering $ordering = SEQ_CONSISTENT) @if(types::flat_kind(Type) != FLOAT)
80157
{
81158
return atomic::fetch_xor(&self.data, value, $ordering);
82159
}
83160

161+
<*
162+
Atomically bitwise-and the stored value with `value`. Not available for floats.
163+
164+
@param value : "The value to and with."
165+
@param $ordering : "Memory ordering, defaults to SEQ_CONSISTENT."
166+
@return "The previous value, before the operation."
167+
@require $ordering != NOT_ATOMIC && $ordering != UNORDERED : "Invalid ordering for a read-modify-write."
168+
*>
84169
macro Type Atomic.and(&self, Type value, AtomicOrdering $ordering = SEQ_CONSISTENT) @if(types::flat_kind(Type) != FLOAT)
85170
{
86171
return atomic::fetch_and(&self.data, value, $ordering);
87172
}
88173

174+
<*
175+
Atomically shift the stored value right by `amount`, using a compare-exchange loop.
176+
Not available for floats.
177+
178+
@param amount : "The number of bits to shift by."
179+
@param $ordering : "Memory ordering, defaults to SEQ_CONSISTENT."
180+
@return "The previous value, before the shift."
181+
@require $ordering != NOT_ATOMIC && $ordering != UNORDERED : "Invalid ordering for a read-modify-write."
182+
*>
89183
macro Type Atomic.shr(&self, Type amount, AtomicOrdering $ordering = SEQ_CONSISTENT) @if(types::flat_kind(Type) != FLOAT)
90184
{
91185
return atomic::fetch_shift_right(&self.data, amount, $ordering);
92186
}
93187

188+
<*
189+
Atomically shift the stored value left by `amount`, using a compare-exchange loop.
190+
Not available for floats.
191+
192+
@param amount : "The number of bits to shift by."
193+
@param $ordering : "Memory ordering, defaults to SEQ_CONSISTENT."
194+
@return "The previous value, before the shift."
195+
@require $ordering != NOT_ATOMIC && $ordering != UNORDERED : "Invalid ordering for a read-modify-write."
196+
*>
94197
macro Type Atomic.shl(&self, Type amount, AtomicOrdering $ordering = SEQ_CONSISTENT) @if(types::flat_kind(Type) != FLOAT)
95198
{
96199
return atomic::fetch_shift_left(&self.data, amount, $ordering);
97200
}
98201

202+
<*
203+
Atomically set the boolean flag to true. Only available for bool.
204+
205+
@param $ordering : "Memory ordering, defaults to SEQ_CONSISTENT."
206+
@return "The previous value of the flag."
207+
@require $ordering != NOT_ATOMIC && $ordering != UNORDERED : "Invalid ordering for a read-modify-write."
208+
*>
99209
macro Type Atomic.set(&self, AtomicOrdering $ordering = SEQ_CONSISTENT) @if(types::flat_kind(Type) == BOOL)
100210
{
101211
return atomic::flag_set(&self.data, $ordering);
102212
}
103213

214+
<*
215+
Atomically clear the boolean flag to false. Only available for bool.
216+
217+
@param $ordering : "Memory ordering, defaults to SEQ_CONSISTENT."
218+
@return "The previous value of the flag."
219+
@require $ordering != NOT_ATOMIC && $ordering != UNORDERED : "Invalid ordering for a read-modify-write."
220+
*>
104221
macro Type Atomic.clear(&self, AtomicOrdering $ordering = SEQ_CONSISTENT) @if(types::flat_kind(Type) == BOOL)
105222
{
106223
return atomic::flag_clear(&self.data, $ordering);
@@ -114,6 +231,12 @@ macro bool @is_native_atomic_value(#value) @private
114231
return is_native_atomic_type($Typeof(#value));
115232
}
116233

234+
<*
235+
Check whether a type can be operated on with native atomic instructions, that is,
236+
it is an int, pointer, function pointer, float or bool no larger than a pointer.
237+
238+
@return "True if `$Type` supports native atomic operations."
239+
*>
117240
macro bool is_native_atomic_type($Type)
118241
{
119242
$if $Type::size > void*::size:

0 commit comments

Comments
 (0)