@@ -453,43 +453,10 @@ end
453453
454454Mark `var` or `ex` as being performed atomically, if `ex` is a supported expression.
455455
456- See [atomics](#man-atomics) in the manual for more details.
457-
458- ```jldoctest
459- julia> mutable struct Atomic{T}; @atomic x::T; end
460-
461- julia> a = Atomic(1)
462- Atomic{Int64}(1)
463-
464- julia> @atomic a.x # fetch field x of a, with sequential consistency
465- 1
466- ```
467- """
468- macro atomic (ex)
469- if ! isa (ex, Symbol) && ! is_expr (ex, :(:: ))
470- return make_atomic (QuoteNode (:sequentially_consistent ), ex)
471- end
472- return esc (Expr (:atomic , ex))
473- end
474- macro atomic (order, ex)
475- order isa QuoteNode || (order = esc (order))
476- return make_atomic (order, ex)
477- end
478- function make_atomic (order, ex)
479- @nospecialize
480- if isexpr (ex, :., 2 )
481- l, r = esc (ex. args[1 ]), esc (ex. args[2 ])
482- return :(getproperty ($ l, $ r, $ order))
483- end
484- error (" could not parse @atomic expression $ex " )
485- end
486-
487-
488- """
489- @atomic! a.b.x = new
490- @atomic! a.b.x += addend
491- @atomic! :acquire_release a.b.x = new
492- @atomic! :acquire_release a.b.x += addend
456+ @atomic a.b.x = new
457+ @atomic a.b.x += addend
458+ @atomic :acquire_release a.b.x = new
459+ @atomic :acquire_release a.b.x += addend
493460
494461Perform the store operation expressed on the right atomically and return the
495462new value.
@@ -498,18 +465,19 @@ With `=`, this operation translates to a `setproperty!(a.b, :x, new)` call.
498465With any operator also, this operation translates to a `modifyproperty!(a.b,
499466:x, +, addend)[2]` call.
500467
501- @atomic! a.b.x max arg2
502- @atomic! a.b.x + arg2
503- @atomic! max(a.b.x, arg2)
504- @atomic! :acquire_release max(a.b.x, arg2)
505- @atomic! :acquire_release a.b.x + arg2
506- @atomic! :acquire_release a.b.x max arg2
468+ @atomic a.b.x max arg2
469+ @atomic a.b.x + arg2
470+ @atomic max(a.b.x, arg2)
471+ @atomic :acquire_release max(a.b.x, arg2)
472+ @atomic :acquire_release a.b.x + arg2
473+ @atomic :acquire_release a.b.x max arg2
507474
508475Perform the binary operation expressed on the right atomically. Store the
509476result into the field in the first argument and return the values `(old, new)`.
510477
511478This operation translates to a `modifyproperty!(a.b, :x, func, arg2)` call.
512479
480+
513481See [atomics](#man-atomics) in the manual for more details.
514482
515483```jldoctest
@@ -518,44 +486,53 @@ julia> mutable struct Atomic{T}; @atomic x::T; end
518486julia> a = Atomic(1)
519487Atomic{Int64}(1)
520488
521- julia> @atomic! :sequentially_consistent a.x = 2 # set field x of a, with sequential consistency
489+ julia> @atomic a.x # fetch field x of a, with sequential consistency
490+ 1
491+
492+ julia> @atomic :sequentially_consistent a.x = 2 # set field x of a, with sequential consistency
5224932
523494
524- julia> @atomic! a.x += 1 # increment field x of a, with sequential consistency
495+ julia> @atomic a.x += 1 # increment field x of a, with sequential consistency
5254963
526497
527- julia> @atomic! a.x + 1 # increment field x of a, with sequential consistency
498+ julia> @atomic a.x + 1 # increment field x of a, with sequential consistency
528499(3, 4)
529500
530501julia> @atomic a.x # fetch field x of a, with sequential consistency
5315024
532503
533- julia> @atomic! max(a.x, 10) # change field x of a to the max value, with sequential consistency
504+ julia> @atomic max(a.x, 10) # change field x of a to the max value, with sequential consistency
534505(4, 10)
535506
536- julia> @atomic! a.x max 5 # again change field x of a to the max value, with sequential consistency
507+ julia> @atomic a.x max 5 # again change field x of a to the max value, with sequential consistency
537508(10, 10)
538509```
539510"""
540- macro atomic! (order, a1, op, a2)
511+ macro atomic (ex)
512+ if ! isa (ex, Symbol) && ! is_expr (ex, :(:: ))
513+ return make_atomic (QuoteNode (:sequentially_consistent ), ex)
514+ end
515+ return esc (Expr (:atomic , ex))
516+ end
517+ macro atomic (order, ex)
541518 order isa QuoteNode || (order = esc (order))
542- return make_atomic! (order, a1, op, a2 )
519+ return make_atomic (order, ex )
543520end
544- macro atomic! (a1, op, a2)
545- return make_atomic! (QuoteNode (:sequentially_consistent ), a1, op, a2)
521+ macro atomic (a1, op, a2)
522+ return make_atomic (QuoteNode (:sequentially_consistent ), a1, op, a2)
546523end
547- macro atomic! (order, ex )
524+ macro atomic (order, a1, op, a2 )
548525 order isa QuoteNode || (order = esc (order))
549- return make_atomic! (order, ex)
550- end
551- macro atomic! (ex)
552- return make_atomic! (QuoteNode (:sequentially_consistent ), ex)
526+ return make_atomic (order, a1, op, a2)
553527end
554- function make_atomic! (order, ex)
528+ function make_atomic (order, ex)
555529 @nospecialize
556530 if ex isa Expr
557- if isexpr (ex, :call , 3 )
558- return make_atomic! (order, ex. args[2 ], ex. args[1 ], ex. args[3 ])
531+ if isexpr (ex, :., 2 )
532+ l, r = esc (ex. args[1 ]), esc (ex. args[2 ])
533+ return :(getproperty ($ l, $ r, $ order))
534+ elseif isexpr (ex, :call , 3 )
535+ return make_atomic (order, ex. args[2 ], ex. args[1 ], ex. args[3 ])
559536 elseif ex. head === :(= )
560537 l, r = ex. args[1 ], ex. args[2 ]
561538 if is_expr (l, :., 2 )
@@ -575,26 +552,23 @@ function make_atomic!(order, ex)
575552 end
576553 end
577554 if @isdefined (op)
578- l, r = ex. args[1 ], esc (ex. args[2 ])
579- is_expr (l, :.) || error (" @atomic modify expression missing field access" )
580- ll, lr, op = esc (l. args[1 ]), esc (l. args[2 ]), esc (op)
581- return :(modifyproperty! ($ ll, $ lr, $ op, $ r, $ order)[2 ])
555+ return Expr (:ref , make_atomic (order, ex. args[1 ], op, ex. args[2 ]), 2 )
582556 end
583557 end
584558 end
585- error (" could not parse @atomic! modify expression $ex " )
559+ error (" could not parse @atomic expression $ex " )
586560end
587- function make_atomic! (order, a1, op, a2)
561+ function make_atomic (order, a1, op, a2)
588562 @nospecialize
589- is_expr (a1, :., 2 ) || error (" @atomic! modify expression missing field access" )
563+ is_expr (a1, :., 2 ) || error (" @atomic modify expression missing field access" )
590564 a1l, a1r, op, a2 = esc (a1. args[1 ]), esc (a1. args[2 ]), esc (op), esc (a2)
591565 return :(modifyproperty! ($ a1l, $ a1r, $ op, $ a2, $ order))
592566end
593567
594568
595569"""
596- @atomic_swap! a.b.x new
597- @atomic_swap! :sequentially_consistent a.b.x new
570+ @atomicswap a.b.x new
571+ @atomicswap :sequentially_consistent a.b.x new
598572
599573Stores `new` into `a.b.x` and returns the old value of `a.b.x`.
600574
@@ -608,32 +582,32 @@ julia> mutable struct Atomic{T}; @atomic x::T; end
608582julia> a = Atomic(1)
609583Atomic{Int64}(1)
610584
611- julia> @atomic_swap! a.x 2+2 # replace field x of a with 4, with sequential consistency
585+ julia> @atomicswap a.x 2+2 # replace field x of a with 4, with sequential consistency
6125861
613587
614588julia> @atomic a.x # fetch field x of a, with sequential consistency
6155894
616590```
617591"""
618- macro atomic_swap! (order, ex, val)
592+ macro atomicswap (order, ex, val)
619593 order isa QuoteNode || (order = esc (order))
620- return make_atomic_swap! (order, ex, val)
594+ return make_atomicswap (order, ex, val)
621595end
622- macro atomic_swap! (ex, val)
623- return make_atomic_swap! (QuoteNode (:sequentially_consistent ), ex, val)
596+ macro atomicswap (ex, val)
597+ return make_atomicswap (QuoteNode (:sequentially_consistent ), ex, val)
624598end
625- function make_atomic_swap! (order, ex, val)
599+ function make_atomicswap (order, ex, val)
626600 @nospecialize
627- is_expr (ex, :., 2 ) || error (" @atomic_swap! expression missing field access" )
601+ is_expr (ex, :., 2 ) || error (" @atomicswap expression missing field access" )
628602 l, r, val = esc (ex. args[1 ]), esc (ex. args[2 ]), esc (val)
629603 return :(swapproperty! ($ l, $ r, $ val, $ order))
630604end
631605
632606
633607"""
634- @atomic_replace! a.b.x expected => desired
635- @atomic_replace! :sequentially_consistent a.b.x expected => desired
636- @atomic_replace! :sequentially_consistent :monotonic a.b.x expected => desired
608+ @atomicreplace a.b.x expected => desired
609+ @atomicreplace :sequentially_consistent a.b.x expected => desired
610+ @atomicreplace :sequentially_consistent :monotonic a.b.x expected => desired
637611
638612Perform the conditional replacement expressed by the pair atomically, returning
639613the values `(old, success::Bool)`. Where `success` indicates whether the
@@ -649,39 +623,39 @@ julia> mutable struct Atomic{T}; @atomic x::T; end
649623julia> a = Atomic(1)
650624Atomic{Int64}(1)
651625
652- julia> @atomic_replace! a.x 1 => 2 # replace field x of a with 2 if it was 1, with sequential consistency
626+ julia> @atomicreplace a.x 1 => 2 # replace field x of a with 2 if it was 1, with sequential consistency
653627(1, true)
654628
655629julia> @atomic a.x # fetch field x of a, with sequential consistency
6566302
657631
658- julia> @atomic_replace! a.x 1 => 2 # replace field x of a with 2 if it was 1, with sequential consistency
632+ julia> @atomicreplace a.x 1 => 2 # replace field x of a with 2 if it was 1, with sequential consistency
659633(2, false)
660634
661635julia> xchg = 2 => 0; # replace field x of a with 0 if it was 1, with sequential consistency
662636
663- julia> @atomic_replace! a.x xchg
637+ julia> @atomicreplace a.x xchg
664638(2, true)
665639
666640julia> @atomic a.x # fetch field x of a, with sequential consistency
6676410
668642```
669643"""
670- macro atomic_replace! (success_order, fail_order, ex, old_new)
644+ macro atomicreplace (success_order, fail_order, ex, old_new)
671645 fail_order isa QuoteNode || (fail_order = esc (fail_order))
672646 success_order isa QuoteNode || (success_order = esc (success_order))
673- return make_atomic_replace! (success_order, fail_order, ex, old_new)
647+ return make_atomicreplace (success_order, fail_order, ex, old_new)
674648end
675- macro atomic_replace! (order, ex, old_new)
649+ macro atomicreplace (order, ex, old_new)
676650 order isa QuoteNode || (order = esc (order))
677- return make_atomic_replace! (order, order, ex, old_new)
651+ return make_atomicreplace (order, order, ex, old_new)
678652end
679- macro atomic_replace! (ex, old_new)
680- return make_atomic_replace! (QuoteNode (:sequentially_consistent ), QuoteNode (:sequentially_consistent ), ex, old_new)
653+ macro atomicreplace (ex, old_new)
654+ return make_atomicreplace (QuoteNode (:sequentially_consistent ), QuoteNode (:sequentially_consistent ), ex, old_new)
681655end
682- function make_atomic_replace! (success_order, fail_order, ex, old_new)
656+ function make_atomicreplace (success_order, fail_order, ex, old_new)
683657 @nospecialize
684- is_expr (ex, :., 2 ) || error (" @atomic_replace! expression missing field access" )
658+ is_expr (ex, :., 2 ) || error (" @atomicreplace expression missing field access" )
685659 ll, lr = esc (ex. args[1 ]), esc (ex. args[2 ])
686660 if is_expr (old_new, :call , 3 ) && old_new. args[1 ] === :(=> )
687661 exp, rep = esc (old_new. args[2 ]), esc (old_new. args[3 ])
0 commit comments