diff --git a/doc/langref.html.in b/doc/langref.html.in index 51f78e1be0af..930b0202ef74 100644 --- a/doc/langref.html.in +++ b/doc/langref.html.in @@ -2243,7 +2243,7 @@ or {#code|test_aligned_struct_fields.zig#}
- Equating packed structs results in a comparison of the backing integer, + Equating packed structs results in a comparison of the backing integer, and only works for the `==` and `!=` operators.
{#code|test_packed_struct_equality.zig#} @@ -4199,11 +4199,73 @@ pub fn print(self: *Writer, arg0: []const u8, arg1: i32) !void { {#header_close#} {#header_close#} + {#header_open|Multithreading#} ++ The {#link|Zig Standard Library#} contains an abstraction of OS threads as {#syntax#}std.Thread{#endsyntax#}, as well + as a number of concurrency primitives under that namespace. +
+ ++ Zig currently inherits LLVM's memory model, but may + define its own one (most likely compatible with LLVM). Until then, + LLVM's documentation is + the ground truth. +
++ All operations performed within a thread happen in the regular program order, as far as it is concerned. + Operations in different threads are only + partially ordered: + they need to synchronize in some way, via atomics or system functions, to rely on each other's results. Multiple + threads operating on a memory location without sufficient synchronization create a race condition: threads may + appear to run operations in the wrong order, and values may be read that were never written (e.g. because a store + was split into multiple operations). +
++ For the purposes of this definition, the allocation of a heap location writes an undefined value to it. Reads + and writes happen byte-wise, and if a race condition happens only on part of a read, then only those bytes of the + returned value are undefined. +
+ {#header_open|Atomics#} -TODO: @atomic rmw
-TODO: builtin atomic memory ordering enum
++ {#link|@atomicRmw#}, {#link|@cmpxchgWeak#} and {#link|@cmpxchgStrong#} make up the building blocks of concurrency + primitives by performing some operations in an atomic step, uninterrupted by other threads or signals. +
+
+ Those builtins, as well as {#link|@atomicLoad#} and {#link|@atomicStore#}, also provide synchronization and
+ ordering guarantees as requested in their AtomicOrder parameters. The AtomicOrder enum,
+ found at {#syntax#}@import("std").builtin.AtomicOrder{#endsyntax#}, mirrors
+ the options defined by LLVM:
+
unordered operations provide just the basic atomic behavior, with no other ordering or synchronization guarantees.monotonic reads and writes on a memory location additionally observe a consistent ordering on
+ that single location, but still do not provide any happens-synchronization.release write happens before all acquires reading the written value.
+ For operations that combine a read and a write, acq_rel provides both behaviors.seq_cst operations provide release and acquire guarantees;
+ additionally, all threads observe the same global ordering of seq_cst operations.Zig has a compile option -fsingle-threaded which has the following effects:
+{#syntax#}@atomicLoad(comptime T: type, ptr: *const T, comptime ordering: AtomicOrder) T{#endsyntax#}
- This builtin function atomically dereferences a pointer to a {#syntax#}T{#endsyntax#} and returns the value. + This builtin function {#link|atomically|Atomics#} dereferences a pointer to a {#syntax#}T{#endsyntax#} and returns the value.
{#syntax#}T{#endsyntax#} must be a pointer, a {#syntax#}bool{#endsyntax#}, a float, an integer or an enum.
-{#syntax#}AtomicOrder{#endsyntax#} can be found with {#syntax#}@import("std").builtin.AtomicOrder{#endsyntax#}.
- {#see_also|@atomicStore|@atomicRmw||@cmpxchgWeak|@cmpxchgStrong#} {#header_close#} {#header_open|@atomicRmw#}{#syntax#}@atomicRmw(comptime T: type, ptr: *T, comptime op: AtomicRmwOp, operand: T, comptime ordering: AtomicOrder) T{#endsyntax#}
- This builtin function dereferences a pointer to a {#syntax#}T{#endsyntax#} and atomically + This builtin function dereferences a pointer to a {#syntax#}T{#endsyntax#} and {#link|atomically|Atomics#} modifies the value and returns the previous value.
{#syntax#}T{#endsyntax#} must be a pointer, a {#syntax#}bool{#endsyntax#}, a float, an integer or an enum.
-{#syntax#}AtomicOrder{#endsyntax#} can be found with {#syntax#}@import("std").builtin.AtomicOrder{#endsyntax#}.
{#syntax#}AtomicRmwOp{#endsyntax#} can be found with {#syntax#}@import("std").builtin.AtomicRmwOp{#endsyntax#}.
- {#see_also|@atomicStore|@atomicLoad|@cmpxchgWeak|@cmpxchgStrong#} {#header_close#} {#header_open|@atomicStore#}{#syntax#}@atomicStore(comptime T: type, ptr: *T, value: T, comptime ordering: AtomicOrder) void{#endsyntax#}
- This builtin function dereferences a pointer to a {#syntax#}T{#endsyntax#} and atomically stores the given value. + This builtin function dereferences a pointer to a {#syntax#}T{#endsyntax#} and {#link|atomically|Atomics#} stores the given value.
{#syntax#}T{#endsyntax#} must be a pointer, a {#syntax#}bool{#endsyntax#}, a float, an integer or an enum.
-{#syntax#}AtomicOrder{#endsyntax#} can be found with {#syntax#}@import("std").builtin.AtomicOrder{#endsyntax#}.
- {#see_also|@atomicLoad|@atomicRmw|@cmpxchgWeak|@cmpxchgStrong#} {#header_close#} {#header_open|@bitCast#} @@ -4535,7 +4591,7 @@ comptime {This function performs a strong atomic compare-and-exchange operation, returning {#syntax#}null{#endsyntax#} if the current value is not the given expected value. It's the equivalent of this code, - except atomic: + except {#link|atomic|Atomics#}:
{#code|not_atomic_cmpxchgStrong.zig#} @@ -4548,8 +4604,6 @@ comptime { an integer or an enum.{#syntax#}@typeInfo(@TypeOf(ptr)).pointer.alignment{#endsyntax#} must be {#syntax#}>= @sizeOf(T).{#endsyntax#}
-{#syntax#}AtomicOrder{#endsyntax#} can be found with {#syntax#}@import("std").builtin.AtomicOrder{#endsyntax#}.
- {#see_also|@atomicStore|@atomicLoad|@atomicRmw|@cmpxchgWeak#} {#header_close#} {#header_open|@cmpxchgWeak#} @@ -4557,7 +4611,7 @@ comptime {This function performs a weak atomic compare-and-exchange operation, returning {#syntax#}null{#endsyntax#} if the current value is not the given expected value. It's the equivalent of this code, - except atomic: + except {#link|atomic|Atomics#}:
{#syntax_block|zig|cmpxchgWeakButNotAtomic#} fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_value: T) ?T { @@ -4580,8 +4634,6 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val an integer or an enum.{#syntax#}@typeInfo(@TypeOf(ptr)).pointer.alignment{#endsyntax#} must be {#syntax#}>= @sizeOf(T).{#endsyntax#}
-{#syntax#}AtomicOrder{#endsyntax#} can be found with {#syntax#}@import("std").builtin.AtomicOrder{#endsyntax#}.
- {#see_also|@atomicStore|@atomicLoad|@atomicRmw|@cmpxchgStrong#} {#header_close#} {#header_open|@compileError#} @@ -5887,18 +5939,6 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val {#see_also|Compile Variables|Zig Build System|Undefined Behavior#} {#header_close#} - {#header_open|Single Threaded Builds#} -Zig has a compile option -fsingle-threaded which has the following effects:
-Zig has many instances of undefined behavior. If undefined behavior is