Skip to content

Commit

Permalink
update text
Browse files Browse the repository at this point in the history
  • Loading branch information
vtjnash committed Mar 12, 2021
1 parent fe4c222 commit 258f06f
Show file tree
Hide file tree
Showing 6 changed files with 34 additions and 30 deletions.
12 changes: 8 additions & 4 deletions base/expr.jl
Original file line number Diff line number Diff line change
Expand Up @@ -453,16 +453,20 @@ end
"""
@atomic ex
Mark `ex` as being performed atomically.
Mark `ex` as being performed atomically, if `ex` is a supported expression.
```julia
mutable struct Atomic{T}; @atomic x::T; end
a = Atomic(1)
@atomic a.x = 2 # set field x of a
@atomic a.x # fetch field x or a
# TODO: @atomic a.x += 1 # increment field x of a
# TODO: @atomic +!(a.x, 1) # increment field x of a
# TODO: @atomic a.x, z = y, a.x # swap field x of a with y and put the old value in z
```
The following forms are also planned, but not yet implemented:
```
# @atomic a.x += 1 # increment field x of a
# @atomic +!(a.x, 1) # increment field x of a
# @atomic a.x, z = y, a.x # swap field x of a with y and put the old value in z
```
"""
macro atomic(ex)
Expand Down
10 changes: 5 additions & 5 deletions src/builtins.c
Original file line number Diff line number Diff line change
Expand Up @@ -850,9 +850,9 @@ JL_CALLABLE(jl_f_getfield)
}
int isatomic = jl_field_isatomic(st, idx);
if (!isatomic && order != jl_memory_order_notatomic && order != jl_memory_order_unspecified)
jl_atomic_error("getfield non-atomic field cannot be accessed atomically");
jl_atomic_error("getfield: non-atomic field cannot be accessed atomically");
if (isatomic && order == jl_memory_order_notatomic)
jl_atomic_error("getfield atomic field cannot be accessed non-atomically");
jl_atomic_error("getfield: atomic field cannot be accessed non-atomically");
v = jl_get_nth_field_checked(v, idx);
if (order >= jl_memory_order_acq_rel || order == jl_memory_order_acquire)
jl_fence(); // `v` already had at least consume ordering
Expand All @@ -875,7 +875,7 @@ JL_CALLABLE(jl_f_setfield)
if (st == jl_module_type)
jl_error("cannot assign variables in other modules");
if (!st->mutabl)
jl_errorf("setfield! immutable struct of type %s cannot be changed", jl_symbol_name(st->name->name));
jl_errorf("setfield!: immutable struct of type %s cannot be changed", jl_symbol_name(st->name->name));
size_t idx;
if (jl_is_long(args[1])) {
idx = jl_unbox_long(args[1]) - 1;
Expand All @@ -892,8 +892,8 @@ JL_CALLABLE(jl_f_setfield)
}
int isatomic = !!jl_field_isatomic(st, idx);
if (isatomic == (order == jl_memory_order_notatomic))
jl_atomic_error(isatomic ? "setfield! atomic field cannot be written non-atomically"
: "setfield! non-atomic field cannot be written atomically");
jl_atomic_error(isatomic ? "setfield!: atomic field cannot be written non-atomically"
: "setfield!: non-atomic field cannot be written atomically");
if (order >= jl_memory_order_acq_rel || order == jl_memory_order_release)
jl_fence(); // `st->[idx]` will be have at least relaxed ordering
set_nth_field(st, v, idx, args[2], isatomic);
Expand Down
8 changes: 4 additions & 4 deletions src/cgutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1725,7 +1725,7 @@ static bool emit_getfield_unknownidx(jl_codectx_t &ctx,
bool maybeatomic = stt->name->atomicfields != NULL;
if (strct.ispointer() && !maybeatomic) { // boxed or stack
if (order != jl_memory_order_notatomic && order != jl_memory_order_unspecified) {
emit_atomic_error(ctx, "getfield non-atomic field cannot be accessed atomically");
emit_atomic_error(ctx, "getfield: non-atomic field cannot be accessed atomically");
*ret = jl_cgval_t(); // unreachable
return true;
}
Expand Down Expand Up @@ -1800,11 +1800,11 @@ static jl_cgval_t emit_getfield_knownidx(jl_codectx_t &ctx, const jl_cgval_t &st
bool isatomic = jl_field_isatomic(jt, idx);
bool needlock = isatomic && !jl_field_isptr(jt, idx) && jl_datatype_size(jfty) > MAX_ATOMIC_SIZE;
if (!isatomic && order != jl_memory_order_notatomic && order != jl_memory_order_unspecified) {
emit_atomic_error(ctx, "getfield non-atomic field cannot be accessed atomically");
emit_atomic_error(ctx, "getfield: non-atomic field cannot be accessed atomically");
return jl_cgval_t(); // unreachable
}
if (isatomic && order == jl_memory_order_notatomic) {
emit_atomic_error(ctx, "getfield atomic field cannot be accessed non-atomically");
emit_atomic_error(ctx, "getfield: atomic field cannot be accessed non-atomically");
return jl_cgval_t(); // unreachable
}
if (jfty == jl_bottom_type) {
Expand Down Expand Up @@ -2926,7 +2926,7 @@ static void emit_setfield(jl_codectx_t &ctx,
}
}
else {
std::string msg = "setfield! immutable struct of type "
std::string msg = "setfield!: immutable struct of type "
+ std::string(jl_symbol_name(sty->name->name))
+ " cannot be changed";
emit_error(ctx, msg);
Expand Down
2 changes: 1 addition & 1 deletion src/rtutils.c
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@ JL_DLLEXPORT void jl_set_nth_field(jl_value_t *v, size_t idx0, jl_value_t *rhs)
{
jl_datatype_t *st = (jl_datatype_t*)jl_typeof(v);
if (!st->mutabl)
jl_errorf("setfield! immutable struct of type %s cannot be changed", jl_symbol_name(st->name->name));
jl_errorf("setfield!: immutable struct of type %s cannot be changed", jl_symbol_name(st->name->name));
if (idx0 >= jl_datatype_nfields(st))
jl_bounds_error_int(v, idx0 + 1);
//jl_value_t *ft = jl_field_type(st, idx0);
Expand Down
8 changes: 4 additions & 4 deletions test/core.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1099,9 +1099,9 @@ end
let strct = LoadError("yofile", 0, "bad")
@test nfields(strct) == 3 # sanity test
@test_throws BoundsError(strct, 10) getfield(strct, 10)
@test_throws ErrorException("setfield! immutable struct of type LoadError cannot be changed") setfield!(strct, 0, "")
@test_throws ErrorException("setfield! immutable struct of type LoadError cannot be changed") setfield!(strct, 4, "")
@test_throws ErrorException("setfield! immutable struct of type LoadError cannot be changed") setfield!(strct, :line, 0)
@test_throws ErrorException("setfield!: immutable struct of type LoadError cannot be changed") setfield!(strct, 0, "")
@test_throws ErrorException("setfield!: immutable struct of type LoadError cannot be changed") setfield!(strct, 4, "")
@test_throws ErrorException("setfield!: immutable struct of type LoadError cannot be changed") setfield!(strct, :line, 0)
@test strct.file == "yofile"
@test strct.line === 0
@test strct.error == "bad"
Expand All @@ -1123,7 +1123,7 @@ let mstrct = TestMutable("melm", 1, nothing)
@test_throws BoundsError(mstrct, 4) setfield!(mstrct, 4, "")
end
let strct = LoadError("yofile", 0, "bad")
@test_throws(ErrorException("setfield! immutable struct of type LoadError cannot be changed"),
@test_throws(ErrorException("setfield!: immutable struct of type LoadError cannot be changed"),
ccall(:jl_set_nth_field, Cvoid, (Any, Csize_t, Any), strct, 0, ""))
end
let mstrct = TestMutable("melm", 1, nothing)
Expand Down
24 changes: 12 additions & 12 deletions test/intrinsics.jl
Original file line number Diff line number Diff line change
Expand Up @@ -153,20 +153,20 @@ end
@test_intrinsic Core.Intrinsics.fptoui UInt Float16(3.3) UInt(3)
end

@test Core.Intrinsics.atomics_fence(:sequentially_consistent) === nothing
@test Core.Intrinsics.atomics_pointerref(C_NULL, :sequentially_consistent) == nothing
@test Core.Intrinsics.atomic_fence(:sequentially_consistent) === nothing
@test Core.Intrinsics.atomic_pointerref(C_NULL, :sequentially_consistent) == nothing
let r = Ref{Int}(10)
p = Base.unsafe_convert(Ptr{Int}, r)
GC.@preserve r begin
@test Core.Intrinsics.atomics_pointerref(p, :sequentially_consistent) === 10
@test Core.Intrinsics.atomics_pointerset(p, 1, :sequentially_consistent) === p
@test Core.Intrinsics.atomics_pointerref(p, :sequentially_consistent) === 1
@test Core.Intrinsics.atomics_pointercmpswap(p, 100, 1, :sequentially_consistent, :sequentially_consistent) === true
@test Core.Intrinsics.atomics_pointerref(p, :sequentially_consistent) === 100
@test Core.Intrinsics.atomics_pointercmpswap(p, 1, 1, :sequentially_consistent, :sequentially_consistent) === false
@test Core.Intrinsics.atomics_pointerref(p, :sequentially_consistent) === 100
@test Core.Intrinsics.atomics_pointermodify(p, +, 1, :sequentially_consistent) == 100
@test Core.Intrinsics.atomics_pointermodify(p, +, 1, :sequentially_consistent) == 101
@test Core.Intrinsics.atomics_pointerref(p, :sequentially_consistent) == 102
@test Core.Intrinsics.atomic_pointerref(p, :sequentially_consistent) === 10
@test Core.Intrinsics.atomic_pointerset(p, 1, :sequentially_consistent) === p
@test Core.Intrinsics.atomic_pointerref(p, :sequentially_consistent) === 1
@test Core.Intrinsics.atomic_pointercmpswap(p, 100, 1, :sequentially_consistent, :sequentially_consistent) === true
@test Core.Intrinsics.atomic_pointerref(p, :sequentially_consistent) === 100
@test Core.Intrinsics.atomic_pointercmpswap(p, 1, 1, :sequentially_consistent, :sequentially_consistent) === false
@test Core.Intrinsics.atomic_pointerref(p, :sequentially_consistent) === 100
@test Core.Intrinsics.atomic_pointermodify(p, +, 1, :sequentially_consistent) == 100
@test Core.Intrinsics.atomic_pointermodify(p, +, 1, :sequentially_consistent) == 101
@test Core.Intrinsics.atomic_pointerref(p, :sequentially_consistent) == 102
end
end

0 comments on commit 258f06f

Please sign in to comment.