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: +

+ + {#header_close#} - {#see_also|@atomicLoad|@atomicStore|@atomicRmw|@cmpxchgWeak|@cmpxchgStrong#} + {#header_open|Single Threaded Builds#} +

Zig has a compile option -fsingle-threaded which has the following effects:

+ + {#header_close#} {#header_close#} @@ -4281,42 +4343,36 @@ comptime { {#header_open|@atomicLoad#}
{#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:

- - {#header_close#} - {#header_open|Undefined Behavior#}

Zig has many instances of undefined behavior. If undefined behavior is