@@ -453,43 +453,10 @@ end
453
453
454
454
Mark `var` or `ex` as being performed atomically, if `ex` is a supported expression.
455
455
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
493
460
494
461
Perform the store operation expressed on the right atomically and return the
495
462
new value.
@@ -498,18 +465,19 @@ With `=`, this operation translates to a `setproperty!(a.b, :x, new)` call.
498
465
With any operator also, this operation translates to a `modifyproperty!(a.b,
499
466
:x, +, addend)[2]` call.
500
467
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
507
474
508
475
Perform the binary operation expressed on the right atomically. Store the
509
476
result into the field in the first argument and return the values `(old, new)`.
510
477
511
478
This operation translates to a `modifyproperty!(a.b, :x, func, arg2)` call.
512
479
480
+
513
481
See [atomics](#man-atomics) in the manual for more details.
514
482
515
483
```jldoctest
@@ -518,44 +486,53 @@ julia> mutable struct Atomic{T}; @atomic x::T; end
518
486
julia> a = Atomic(1)
519
487
Atomic{Int64}(1)
520
488
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
522
493
2
523
494
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
525
496
3
526
497
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
528
499
(3, 4)
529
500
530
501
julia> @atomic a.x # fetch field x of a, with sequential consistency
531
502
4
532
503
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
534
505
(4, 10)
535
506
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
537
508
(10, 10)
538
509
```
539
510
"""
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)
541
518
order isa QuoteNode || (order = esc (order))
542
- return make_atomic! (order, a1, op, a2 )
519
+ return make_atomic (order, ex )
543
520
end
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)
546
523
end
547
- macro atomic! (order, ex )
524
+ macro atomic (order, a1, op, a2 )
548
525
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)
553
527
end
554
- function make_atomic! (order, ex)
528
+ function make_atomic (order, ex)
555
529
@nospecialize
556
530
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 ])
559
536
elseif ex. head === :(= )
560
537
l, r = ex. args[1 ], ex. args[2 ]
561
538
if is_expr (l, :., 2 )
@@ -575,26 +552,23 @@ function make_atomic!(order, ex)
575
552
end
576
553
end
577
554
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 )
582
556
end
583
557
end
584
558
end
585
- error (" could not parse @atomic! modify expression $ex " )
559
+ error (" could not parse @atomic expression $ex " )
586
560
end
587
- function make_atomic! (order, a1, op, a2)
561
+ function make_atomic (order, a1, op, a2)
588
562
@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" )
590
564
a1l, a1r, op, a2 = esc (a1. args[1 ]), esc (a1. args[2 ]), esc (op), esc (a2)
591
565
return :(modifyproperty! ($ a1l, $ a1r, $ op, $ a2, $ order))
592
566
end
593
567
594
568
595
569
"""
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
598
572
599
573
Stores `new` into `a.b.x` and returns the old value of `a.b.x`.
600
574
@@ -608,32 +582,32 @@ julia> mutable struct Atomic{T}; @atomic x::T; end
608
582
julia> a = Atomic(1)
609
583
Atomic{Int64}(1)
610
584
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
612
586
1
613
587
614
588
julia> @atomic a.x # fetch field x of a, with sequential consistency
615
589
4
616
590
```
617
591
"""
618
- macro atomic_swap! (order, ex, val)
592
+ macro atomicswap (order, ex, val)
619
593
order isa QuoteNode || (order = esc (order))
620
- return make_atomic_swap! (order, ex, val)
594
+ return make_atomicswap (order, ex, val)
621
595
end
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)
624
598
end
625
- function make_atomic_swap! (order, ex, val)
599
+ function make_atomicswap (order, ex, val)
626
600
@nospecialize
627
- is_expr (ex, :., 2 ) || error (" @atomic_swap! expression missing field access" )
601
+ is_expr (ex, :., 2 ) || error (" @atomicswap expression missing field access" )
628
602
l, r, val = esc (ex. args[1 ]), esc (ex. args[2 ]), esc (val)
629
603
return :(swapproperty! ($ l, $ r, $ val, $ order))
630
604
end
631
605
632
606
633
607
"""
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
637
611
638
612
Perform the conditional replacement expressed by the pair atomically, returning
639
613
the values `(old, success::Bool)`. Where `success` indicates whether the
@@ -649,39 +623,39 @@ julia> mutable struct Atomic{T}; @atomic x::T; end
649
623
julia> a = Atomic(1)
650
624
Atomic{Int64}(1)
651
625
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
653
627
(1, true)
654
628
655
629
julia> @atomic a.x # fetch field x of a, with sequential consistency
656
630
2
657
631
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
659
633
(2, false)
660
634
661
635
julia> xchg = 2 => 0; # replace field x of a with 0 if it was 1, with sequential consistency
662
636
663
- julia> @atomic_replace! a.x xchg
637
+ julia> @atomicreplace a.x xchg
664
638
(2, true)
665
639
666
640
julia> @atomic a.x # fetch field x of a, with sequential consistency
667
641
0
668
642
```
669
643
"""
670
- macro atomic_replace! (success_order, fail_order, ex, old_new)
644
+ macro atomicreplace (success_order, fail_order, ex, old_new)
671
645
fail_order isa QuoteNode || (fail_order = esc (fail_order))
672
646
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)
674
648
end
675
- macro atomic_replace! (order, ex, old_new)
649
+ macro atomicreplace (order, ex, old_new)
676
650
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)
678
652
end
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)
681
655
end
682
- function make_atomic_replace! (success_order, fail_order, ex, old_new)
656
+ function make_atomicreplace (success_order, fail_order, ex, old_new)
683
657
@nospecialize
684
- is_expr (ex, :., 2 ) || error (" @atomic_replace! expression missing field access" )
658
+ is_expr (ex, :., 2 ) || error (" @atomicreplace expression missing field access" )
685
659
ll, lr = esc (ex. args[1 ]), esc (ex. args[2 ])
686
660
if is_expr (old_new, :call , 3 ) && old_new. args[1 ] === :(=> )
687
661
exp, rep = esc (old_new. args[2 ]), esc (old_new. args[3 ])
0 commit comments