Skip to content

Commit 3193379

Browse files
committed
document @atomic memory refs functionality
1 parent 5aa0a48 commit 3193379

File tree

1 file changed

+140
-20
lines changed

1 file changed

+140
-20
lines changed

base/expr.jl

Lines changed: 140 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1097,29 +1097,42 @@ Mark `var` or `ex` as being performed atomically, if `ex` is a supported express
10971097
If no `order` is specified it defaults to :sequentially_consistent.
10981098
10991099
@atomic a.b.x = new
1100-
@atomic a.b.x += addend
1100+
@atomic a.b.x += added
11011101
@atomic :release a.b.x = new
1102-
@atomic :acquire_release a.b.x += addend
1102+
@atomic :acquire_release a.b.x += added
1103+
@atomic m[idx] = new
1104+
@atomic m[idx] += added
1105+
@atomic :release m[idx] = new
1106+
@atomic :acquire_release m[idx] += added
11031107
11041108
Perform the store operation expressed on the right atomically and return the
11051109
new value.
11061110
1107-
With `=`, this operation translates to a `setproperty!(a.b, :x, new)` call.
1108-
With any operator also, this operation translates to a `modifyproperty!(a.b,
1109-
:x, +, addend)[2]` call.
1111+
With assignment (`=`), this operation translates to a `setproperty!(a.b, :x, new)`
1112+
or, in case of reference, to a `setindex_atomic!(m, idx, new)` call.
1113+
With any modifying operator this operation translates to a
1114+
`modifyproperty!(a.b, :x, op, added)[2]` or, in case of reference, to a
1115+
`modifyindex!(m, idx, op, added)[2]` call.
11101116
11111117
@atomic a.b.x max arg2
11121118
@atomic a.b.x + arg2
11131119
@atomic max(a.b.x, arg2)
11141120
@atomic :acquire_release max(a.b.x, arg2)
11151121
@atomic :acquire_release a.b.x + arg2
11161122
@atomic :acquire_release a.b.x max arg2
1123+
@atomic m[idx] max arg2
1124+
@atomic m[idx] + arg2
1125+
@atomic max(m[idx], arg2)
1126+
@atomic :acquire_release max(m[idx], arg2)
1127+
@atomic :acquire_release m[idx] + arg2
1128+
@atomic :acquire_release m[idx] max arg2
11171129
11181130
Perform the binary operation expressed on the right atomically. Store the
1119-
result into the field in the first argument and return the values `(old, new)`.
1120-
1121-
This operation translates to a `modifyproperty!(a.b, :x, func, arg2)` call.
1131+
result into the field or the reference in the first argument, and return the values
1132+
`(old, new)`.
11221133
1134+
This operation translates to a `modifyproperty!(a.b, :x, func, arg2)` or,
1135+
in case of reference to a `modifyindex!(m, idx, func, arg2)` call.
11231136
11241137
See [Per-field atomics](@ref man-atomics) section in the manual for more details.
11251138
@@ -1152,8 +1165,36 @@ julia> @atomic a.x max 5 # again change field x of a to the max value, with sequ
11521165
10 => 10
11531166
```
11541167
1168+
```jldoctest
1169+
julia> mem = AtomicMemory{Int}(undef, 2);
1170+
1171+
julia> @atomic mem[1] = 2 # set mem[1] to value 2 with sequential consistency
1172+
2
1173+
1174+
julia> @atomic :monotonic mem[1] # fetch the first value of mem, with monotonic consistency
1175+
2
1176+
1177+
julia> @atomic mem[1] += 1 # increment the first value of mem, with sequential consistency
1178+
3
1179+
1180+
julia> @atomic mem[1] + 1 # increment the first value of mem, with sequential consistency
1181+
3 => 4
1182+
1183+
julia> @atomic mem[1] # fetch the first value of mem, with sequential consistency
1184+
4
1185+
1186+
julia> @atomic max(mem[1], 10) # change the first value of mem to the max value, with sequential consistency
1187+
4 => 10
1188+
1189+
julia> @atomic mem[1] max 5 # again change the first value of mem to the max value, with sequential consistency
1190+
10 => 5
1191+
```
1192+
11551193
!!! compat "Julia 1.7"
1156-
This functionality requires at least Julia 1.7.
1194+
Atomic fields functionality requires at least Julia 1.7.
1195+
1196+
!!! compat "Julia 1.12"
1197+
Atomic reference functionality requires at least Julia 1.12.
11571198
"""
11581199
macro atomic(ex)
11591200
if !isa(ex, Symbol) && !is_expr(ex, :(::))
@@ -1227,10 +1268,14 @@ end
12271268
"""
12281269
@atomicswap a.b.x = new
12291270
@atomicswap :sequentially_consistent a.b.x = new
1271+
@atomicswap m[idx] = new
1272+
@atomicswap :sequentially_consistent m[idx] = new
12301273
1231-
Stores `new` into `a.b.x` and returns the old value of `a.b.x`.
1274+
Stores `new` into `a.b.x` (`m[idx]` in case of reference) and returns the old
1275+
value of `a.b.x` (the old value stored at `m[idx]`, respectively).
12321276
1233-
This operation translates to a `swapproperty!(a.b, :x, new)` call.
1277+
This operation translates to a `swapproperty!(a.b, :x, new)` or,
1278+
in case of reference, `swapindex!(mem, idx, new)` call.
12341279
12351280
See [Per-field atomics](@ref man-atomics) section in the manual for more details.
12361281
@@ -1248,8 +1293,23 @@ julia> @atomic a.x # fetch field x of a, with sequential consistency
12481293
4
12491294
```
12501295
1296+
```jldoctest
1297+
julia> mem = AtomicMemory{Int}(undef, 2);
1298+
1299+
julia> @atomic mem[1] = 1;
1300+
1301+
julia> @atomicswap mem[1] = 4 # replace the first value of `mem` with 4, with sequential consistency
1302+
1
1303+
1304+
julia> @atomic mem[1] # fetch the first value of mem, with sequential consistency
1305+
4
1306+
```
1307+
12511308
!!! compat "Julia 1.7"
1252-
This functionality requires at least Julia 1.7.
1309+
Atomic fields functionality requires at least Julia 1.7.
1310+
1311+
!!! compat "Julia 1.12"
1312+
Atomic reference functionality requires at least Julia 1.12.
12531313
"""
12541314
macro atomicswap(order, ex)
12551315
order isa QuoteNode || (order = esc(order))
@@ -1277,12 +1337,16 @@ end
12771337
@atomicreplace a.b.x expected => desired
12781338
@atomicreplace :sequentially_consistent a.b.x expected => desired
12791339
@atomicreplace :sequentially_consistent :monotonic a.b.x expected => desired
1340+
@atomicreplace m[idx] expected => desired
1341+
@atomicreplace :sequentially_consistent m[idx] expected => desired
1342+
@atomicreplace :sequentially_consistent :monotonic m[idx] expected => desired
12801343
12811344
Perform the conditional replacement expressed by the pair atomically, returning
12821345
the values `(old, success::Bool)`. Where `success` indicates whether the
12831346
replacement was completed.
12841347
1285-
This operation translates to a `replaceproperty!(a.b, :x, expected, desired)` call.
1348+
This operation translates to a `replaceproperty!(a.b, :x, expected, desired)` or,
1349+
in case of reference, to a `replaceindex!(mem, idx, expected, desired)` call.
12861350
12871351
See [Per-field atomics](@ref man-atomics) section in the manual for more details.
12881352
@@ -1299,7 +1363,7 @@ julia> @atomicreplace a.x 1 => 2 # replace field x of a with 2 if it was 1, with
12991363
julia> @atomic a.x # fetch field x of a, with sequential consistency
13001364
2
13011365
1302-
julia> @atomicreplace a.x 1 => 2 # replace field x of a with 2 if it was 1, with sequential consistency
1366+
julia> @atomicreplace a.x 1 => 3 # replace field x of a with 2 if it was 1, with sequential consistency
13031367
(old = 2, success = false)
13041368
13051369
julia> xchg = 2 => 0; # replace field x of a with 0 if it was 2, with sequential consistency
@@ -1311,8 +1375,34 @@ julia> @atomic a.x # fetch field x of a, with sequential consistency
13111375
0
13121376
```
13131377
1378+
```jldoctest
1379+
julia> mem = AtomicMemory{Int}(undef, 2);
1380+
1381+
julia> @atomic mem[1] = 1;
1382+
1383+
julia> @atomicreplace mem[1] 1 => 2 # replace the first value of mem with 2 if it was 1, with sequential consistency
1384+
(old = 1, success = true)
1385+
1386+
julia> @atomic mem[1] # fetch the first value of mem, with sequential consistency
1387+
2
1388+
1389+
julia> @atomicreplace mem[1] 1 => 3 # replace field x of a with 2 if it was 1, with sequential consistency
1390+
(old = 2, success = false)
1391+
1392+
julia> xchg = 2 => 0; # replace field x of a with 0 if it was 2, with sequential consistency
1393+
1394+
julia> @atomicreplace mem[1] xchg
1395+
(old = 2, success = true)
1396+
1397+
julia> @atomic mem[1] # fetch the first value of mem, with sequential consistency
1398+
0
1399+
```
1400+
13141401
!!! compat "Julia 1.7"
1315-
This functionality requires at least Julia 1.7.
1402+
Atomic fields functionality requires at least Julia 1.7.
1403+
1404+
!!! compat "Julia 1.12"
1405+
Atomic reference functionality requires at least Julia 1.12.
13161406
"""
13171407
macro atomicreplace(success_order, fail_order, ex, old_new)
13181408
fail_order isa QuoteNode || (fail_order = esc(fail_order))
@@ -1354,12 +1444,15 @@ end
13541444
@atomiconce a.b.x = value
13551445
@atomiconce :sequentially_consistent a.b.x = value
13561446
@atomiconce :sequentially_consistent :monotonic a.b.x = value
1447+
@atomiconce m[idx] = value
1448+
@atomiconce :sequentially_consistent m[idx] = value
1449+
@atomiconce :sequentially_consistent :monotonic m[idx] = value
13571450
13581451
Perform the conditional assignment of value atomically if it was previously
1359-
unset, returning the value `success::Bool`. Where `success` indicates whether
1360-
the assignment was completed.
1452+
unset. Returned value `success::Bool` indicates whether the assignment was completed.
13611453
1362-
This operation translates to a `setpropertyonce!(a.b, :x, value)` call.
1454+
This operation translates to a `setpropertyonce!(a.b, :x, value)` or,
1455+
in case of reference, to a `setindexonce_atomic!(m, idx, value)` call.
13631456
13641457
See [Per-field atomics](@ref man-atomics) section in the manual for more details.
13651458
@@ -1379,12 +1472,39 @@ true
13791472
julia> @atomic a.x # fetch field x of a, with sequential consistency
13801473
1
13811474
1382-
julia> @atomiconce a.x = 1 # set field x of a to 1, if unset, with sequential consistency
1475+
julia> @atomiconce :monotonic a.x = 2 # set field x of a to 1, if unset, with monotonic consistence
13831476
false
13841477
```
13851478
1479+
```jldoctest
1480+
julia> mem = AtomicMemory{Vector{Int}}(undef, 1);
1481+
1482+
julia> isassigned(mem, 1)
1483+
false
1484+
1485+
julia> @atomiconce mem[1] = [1] # set the first value of mem to [1], if unset, with sequential consistency
1486+
true
1487+
1488+
julia> isassigned(mem, 1)
1489+
true
1490+
1491+
julia> @atomic mem[1] # fetch the first value of mem, with sequential consistency
1492+
1-element Vector{Int64}:
1493+
1
1494+
1495+
julia> @atomiconce :monotonic mem[1] = [2] # set the first value of mem to [2], if unset, with monotonic
1496+
false
1497+
1498+
julia> @atomic mem[1]
1499+
1-element Vector{Int64}:
1500+
1
1501+
```
1502+
13861503
!!! compat "Julia 1.11"
1387-
This functionality requires at least Julia 1.11.
1504+
Atomic fields functionality requires at least Julia 1.11.
1505+
1506+
!!! compat "Julia 1.12"
1507+
Atomic reference functionality requires at least Julia 1.12.
13881508
"""
13891509
macro atomiconce(success_order, fail_order, ex)
13901510
fail_order isa QuoteNode || (fail_order = esc(fail_order))

0 commit comments

Comments
 (0)