Skip to content

Commit

Permalink
fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
vtjnash committed Apr 21, 2021
1 parent f9ec5ad commit 4c60a8d
Show file tree
Hide file tree
Showing 8 changed files with 22 additions and 24 deletions.
5 changes: 2 additions & 3 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,9 @@ Command-line option changes
Multi-threading changes
-----------------------
* If the `JULIA_NUM_THREADS` environment variable is set to `auto`, then the number of threads will be set to the number of CPU threads ([#38952])

* Intrinsics for atomic pointer operations are now defined for certain byte sizes.
* Intrinsics for atomic pointer operations are now defined for certain byte sizes. ([#37847])
* Support for declaring and using individual fields of a mutable struct as
atomic now available.
atomic now available. ([#37847])


Build system changes
Expand Down
6 changes: 3 additions & 3 deletions base/Base.jl
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,11 @@ getproperty(x, f::Symbol, order::Symbol) = (@_inline_meta; getfield(x, f, order)
setproperty!(x, f::Symbol, v, order::Symbol) = (@_inline_meta; setfield!(x, f, convert(fieldtype(typeof(x), f), v), order))

swapproperty!(x, f::Symbol, v, order::Symbol=:notatomic) =
Core.swapfield!(x, f, convert(fieldtype(typeof(x), f), v), order)
(@_inline_meta; Core.swapfield!(x, f, convert(fieldtype(typeof(x), f), v), order))
modifyproperty!(x, f::Symbol, op, v, order::Symbol=:notatomic) =
Core.modifyfield!(x, f, op, v, order)
(@_inline_meta; Core.modifyfield!(x, f, op, v, order))
cmpswapproperty!(x, f::Symbol, expected, desired, success_order::Symbol=:notatomic, fail_order::Symbol=success_order) =
Core.cmpswapfield!(x, f, expected, convert(fieldtype(typeof(x), f), desired), success_order, fail_order)
(@_inline_meta; Core.cmpswapfield!(x, f, expected, convert(fieldtype(typeof(x), f), desired), success_order, fail_order))


include("coreio.jl")
Expand Down
2 changes: 1 addition & 1 deletion base/condition.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
@noinline function concurrency_violation()
# can be useful for debugging
#try; error(); catch; ccall(:jlbacktrace, Cvoid, ()); end
throw(ConcurrencyViolationError("concurrency violation detected"))
throw(ConcurrencyViolationError("lock must be held"))
end

"""
Expand Down
6 changes: 3 additions & 3 deletions base/docs/basedocs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2680,7 +2680,7 @@ See also [`setfield!`](@ref Core.setfield!),
Base.setproperty!

"""
swapproperty!(x, f::Symbol, v, order::Symbol=:notatomic)
swapproperty!(x, f::Symbol, v, order::Symbol=:not_atomic)
The syntax `@atomic a.b, _ = c, a.b` returns `(c, swapproperty!(a, :b, c, :sequentially_consistent))`,
where there must be one getfield expression common to both sides.
Expand All @@ -2691,7 +2691,7 @@ and [`setproperty!`](@ref Base.setproperty!).
Base.swapproperty!

"""
modifyproperty!(x, f::Symbol, op, v, order::Symbol=:notatomic)
modifyproperty!(x, f::Symbol, op, v, order::Symbol=:not_atomic)
The syntax `@atomic a().b = max(a().b, c)` returns `modifyproperty!(a(), :b,
max, c, :sequentially_consistent))`, where the first argument must be a
Expand All @@ -2703,7 +2703,7 @@ and [`setproperty!`](@ref Base.setproperty!).
Base.modifyproperty!

"""
cmpswapproperty!(x, f::Symbol, expected, desired, success_order::Symbol=:notatomic, fail_order::Symbol=success_order)
cmpswapproperty!(x, f::Symbol, expected, desired, success_order::Symbol=:not_atomic, fail_order::Symbol=success_order)
Perform a compare-and-swap operation on `x.f` from `expected` to `desired`, per
egal (there is no convenient `@atomic` syntax for this).
Expand Down
1 change: 0 additions & 1 deletion base/expr.jl
Original file line number Diff line number Diff line change
Expand Up @@ -485,7 +485,6 @@ julia> z
The following forms are also planned, but not yet implemented:
```julia
# @atomic +!(a.x, 1) # increment field x of a
# @atomic a.x = +(a.x, 1) # increment field x of a
# @atomic a.x = +(_, 1) # increment field x of a
```
Expand Down
2 changes: 1 addition & 1 deletion src/builtins.c
Original file line number Diff line number Diff line change
Expand Up @@ -824,7 +824,7 @@ enum jl_memory_order jl_get_atomic_order(jl_sym_t *order, char loading, char sto
enum jl_memory_order jl_get_atomic_order_checked(jl_sym_t *order, char loading, char storing)
{
enum jl_memory_order mo = jl_get_atomic_order(order, loading, storing);
if (mo < 0) // notatomic or invalid
if (mo < 0) // invalid
jl_atomic_error("invalid atomic ordering");
return mo;
}
Expand Down
8 changes: 4 additions & 4 deletions src/runtime_intrinsics.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ JL_DLLEXPORT jl_value_t *jl_atomic_pointerref(jl_value_t *p, jl_value_t *order)
jl_error("pointerref: invalid pointer");
size_t nb = jl_datatype_size(ety);
if ((nb & (nb - 1)) != 0 || nb > MAX_POINTERATOMIC_SIZE)
jl_error("pointerref: invalid atomic operation");
jl_error("pointerref: invalid pointer for atomic operation");
return jl_atomic_new_bits(ety, pp);
}
}
Expand All @@ -112,7 +112,7 @@ JL_DLLEXPORT jl_value_t *jl_atomic_pointerset(jl_value_t *p, jl_value_t *x, jl_v
jl_type_error("pointerset", ety, x);
size_t nb = jl_datatype_size(ety);
if ((nb & (nb - 1)) != 0 || nb > MAX_POINTERATOMIC_SIZE)
jl_error("pointerset: invalid atomic operation");
jl_error("pointerset: invalid pointer for atomic operation");
jl_atomic_store_bits(pp, x, nb);
}
return p;
Expand All @@ -136,7 +136,7 @@ JL_DLLEXPORT jl_value_t *jl_atomic_pointerswap(jl_value_t *p, jl_value_t *x, jl_
jl_type_error("pointerswap", ety, x);
size_t nb = jl_datatype_size(ety);
if ((nb & (nb - 1)) != 0 || nb > MAX_POINTERATOMIC_SIZE)
jl_error("pointerswap: invalid atomic operation");
jl_error("pointerswap: invalid pointer for atomic operation");
y = jl_atomic_swap_bits(ety, pp, x, nb);
}
return y;
Expand Down Expand Up @@ -211,7 +211,7 @@ JL_DLLEXPORT jl_value_t *jl_atomic_pointercmpswap(jl_value_t *p, jl_value_t *exp
jl_type_error("pointercmpswap", ety, x);
size_t nb = jl_datatype_size(ety);
if ((nb & (nb - 1)) != 0 || nb > MAX_POINTERATOMIC_SIZE)
jl_error("pointercmpswap: invalid atomic operation");
jl_error("pointercmpswap: invalid pointer for atomic operation");
return jl_atomic_cmpswap_bits((jl_datatype_t*)ety, pp, expected, x, nb);
}
}
Expand Down
16 changes: 8 additions & 8 deletions test/intrinsics.jl
Original file line number Diff line number Diff line change
Expand Up @@ -183,14 +183,14 @@ for TT in (Int8, Int16, Int32, Int64, Int128, Int256, Int512, Complex{Int32}, Co
@test_throws TypeError Core.Intrinsics.atomic_pointercmpswap(p, T(100), S(2), :sequentially_consistent, :sequentially_consistent)
end
@test Core.Intrinsics.pointerref(p, 1, 1) === T(10) === r[]
if sizeof(r) > 2 * sizeof(Int)
@test_throws ErrorException("pointerref: invalid atomic operation") Core.Intrinsics.atomic_pointerref(p, :sequentially_consistent)
@test_throws ErrorException("pointerset: invalid atomic operation") Core.Intrinsics.atomic_pointerset(p, T(1), :sequentially_consistent)
@test_throws ErrorException("pointerswap: invalid atomic operation") Core.Intrinsics.atomic_pointerswap(p, T(100), :sequentially_consistent)
@test_throws ErrorException("pointerref: invalid atomic operation") Core.Intrinsics.atomic_pointermodify(p, add, T(1), :sequentially_consistent)
@test_throws ErrorException("pointerref: invalid atomic operation") Core.Intrinsics.atomic_pointermodify(p, swap, S(1), :sequentially_consistent)
@test_throws ErrorException("pointercmpswap: invalid atomic operation") Core.Intrinsics.atomic_pointercmpswap(p, T(100), T(2), :sequentially_consistent, :sequentially_consistent)
@test_throws ErrorException("pointercmpswap: invalid atomic operation") Core.Intrinsics.atomic_pointercmpswap(p, S(100), T(2), :sequentially_consistent, :sequentially_consistent)
if sizeof(r) > 8
@test_throws ErrorException("pointerref: invalid pointer for atomic operation") Core.Intrinsics.atomic_pointerref(p, :sequentially_consistent)
@test_throws ErrorException("pointerset: invalid pointer for atomic operation") Core.Intrinsics.atomic_pointerset(p, T(1), :sequentially_consistent)
@test_throws ErrorException("pointerswap: invalid pointer for atomic operation") Core.Intrinsics.atomic_pointerswap(p, T(100), :sequentially_consistent)
@test_throws ErrorException("pointerref: invalid pointer for atomic operation") Core.Intrinsics.atomic_pointermodify(p, add, T(1), :sequentially_consistent)
@test_throws ErrorException("pointerref: invalid pointer for atomic operation") Core.Intrinsics.atomic_pointermodify(p, swap, S(1), :sequentially_consistent)
@test_throws ErrorException("pointercmpswap: invalid pointer for atomic operation") Core.Intrinsics.atomic_pointercmpswap(p, T(100), T(2), :sequentially_consistent, :sequentially_consistent)
@test_throws ErrorException("pointercmpswap: invalid pointer for atomic operation") Core.Intrinsics.atomic_pointercmpswap(p, S(100), T(2), :sequentially_consistent, :sequentially_consistent)
@test Core.Intrinsics.pointerref(p, 1, 1) === T(10) === r[]
else
TT !== Any && @test_throws TypeError Core.Intrinsics.atomic_pointermodify(p, swap, S(1), :sequentially_consistent)
Expand Down

0 comments on commit 4c60a8d

Please sign in to comment.