Programming Languages — Technical specification for C++ extensions for concurrency 2

This document builds upon ISO/IEC 14882 by describing requirements for implementations of an interface that computer programs written in the C++ programming language could use to invoke algorithms with concurrent execution. The algorithms described by this document are realizable across a broad class of computer architectures. This document is written as a set of differences from the base standard. Some of the functionality described by this document might be considered for standardization in a future version of C++, but it is not currently part of ISO/IEC 14882:2020. Some of the functionality in this document might never be standardized, and other functionality might be standardized in a substantially different form. The goal of this document is to build widespread existing practice for concurrency in the ISO/IEC 14882:2020 algorithms library. It gives advice on extensions to those vendors who wish to provide them.

Langages de programmation — Spécification technique pour les extensions C++ de concurrency 2

General Information

Status
Published
Publication Date
25-Nov-2024
Current Stage
6060 - International Standard published
Start Date
26-Nov-2024
Due Date
19-Nov-2024
Completion Date
26-Nov-2024
Ref Project
Technical specification
ISO/IEC TS 9922:2024 - Programming Languages — Technical specification for C++ extensions for concurrency 2 Released:11/26/2024
English language
19 pages
sale 15% off
Preview
sale 15% off
Preview

Standards Content (Sample)


Technical
Specification
ISO/IEC TS 9922
First edition
Programming Languages —
2024-11
Technical specification for C++
extensions for concurrency 2
Langages de programmation — Spécification technique pour les
extensions C++ de concurrency 2
Reference number
© ISO/IEC 2024
All rights reserved. Unless otherwise specified, or required in the context of its implementation, no part of this publication may
be reproduced or utilized otherwise in any form or by any means, electronic or mechanical, including photocopying, or posting on
the internet or an intranet, without prior written permission. Permission can be requested from either ISO at the address below
or ISO’s member body in the country of the requester.
ISO copyright office
CP 401 • Ch. de Blandonnet 8
CH-1214 Vernier, Geneva
Phone: +41 22 749 01 11
Email: copyright@iso.org
Website: www.iso.org
Published in Switzerland
© ISO/IEC 2024 – All rights reserved
ii
ISO/IEC DTS 9922:2024(E) 9922
Contents
Foreword iv
1 Scope 1
2 Normative references 2
3 Terms and definitions 3
4 General 4
4.1 Implementation compliance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
4.2 Namespaces and headers and modifications to standard classes . . . . . . . . . . . . . . . 4
4.3 Feature-testing recommendations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
5 Synchronized Value 6
5.1 General . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
5.2 Header synopsis . . . . . . . . . . . . . . . . . . . . 6
5.3 Class template synchronized_value . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
5.4 apply function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
6 Safe reclamation 8
6.1 General . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
6.2 Hazard pointers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
6.3 Read-copy update (RCU) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
7 Bytewise Atomic Memcpy 16
7.1 General . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
7.2 Header synopsis . . . . . . . . . . . . . . . . 16
7.3 atomic_load_per_byte_memcpy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
7.4 atomic_store_per_byte_memcpy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
8 Asymmetric Fence 17
8.1 General . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
8.2 Header synopsis . . . . . . . . . . . . . . . . . . . . . 17
8.3 asymmetric_thread_fence_heavy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
8.4 asymmetric_thread_fence_light . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
9 Order and consistency 19
© ISO/IEC 2024 – All rights reserved
iii
ISO/IEC DTS 9922:2024(E) 9922
Foreword [foreword]
ISO (the International Organization for Standardization) and IEC (the International Electrotechnical
Commission) form the specialized system for worldwide standardization. National bodies that are members
of ISO or IEC participate in the development of International Standards through technical committees
established by the respective organization to deal with particular fields of technical a ctivity. ISO and IEC
technical committees collaborate in fields of mutual i nterest. Other international organizations, governmental
and non-governmental, in liaison with ISO and IEC, also take part in the work.
The procedures used to develop this document and those intended for its further maintenance are described
in the ISO/IEC Directives, Part 1. In particular, the different a pproval c riteria n eeded f or t he different
types of document should be noted. This document was drafted in accordance with the editorial rules of the
ISO/IEC Directives, Part 2 (see www.iso.org/directives or www.iec.ch/members_experts/refdocs).
ISO and IEC draw attention to the possibility that the implementation of this document may involve the
use of (a) patent(s). ISO and IEC take no position concerning the evidence, validity or applicability of any
claimed patent rights in respect thereof. As of the date of publication of this document, ISO and IEC had not
received notice of (a) patent(s) which may be required to implement this document. However, implementers
are cautioned that this may not represent the latest information, which may be obtained from the patent
database available at www.iso.org/patents and patents.iec.ch. ISO and IEC shall not be held responsible for
identifying any or all such patent rights.
Any trade name used in this document is information given for the convenience of users and does not
constitute an endorsement.
For an explanation of the voluntary nature of standards, the meaning of ISO specific terms and expressions
related to conformity assessment, as well as information about ISO’s adherence to the World Trade Organiza-
tion (WTO) principles in the Technical Barriers to Trade (TBT) see www.iso.org/iso/foreword.html. In the
IEC, see www.iec.ch/understanding-standards.
This document was prepared by Joint Technical Committee ISO/IEC JTC 1, Information technology,
Subcommittee SC 22, Programming languages, their environments and system software interfaces.
Any feedback or questions on this document should be directed to the user’s national standards body.
A complete listing of these bodies can be found at www.iso.org/members.html and www.iec.ch/national-
committees.
© ISO/IEC 2024 – All rights reserved
iv
ISO/IEC DTS 9922:2024(E) 9922
1 Scope [scope]
This document builds upon ISO/IEC 14882 by describing requirements for implementations of an interface
that computer programs written in the C++ programming language could use to invoke algorithms with
concurrent execution. The algorithms described by this document are realizable across a broad class of
computer architectures. This document is written as a set of differences from the base standard.
Some of the functionality described by this document might be considered for standardization in a future
version of C++, but it is not currently part of ISO/IEC 14882:2020. Some of the functionality in this
document might never be standardized, and other functionality might be standardized in a substantially
different form.
The goal of this document is to build widespread existing practice for concurrency in the ISO/IEC 14882:2020
algorithms library. It gives advice on extensions to those vendors who wish to provide them.
© ISO/IEC 2024 – All rights reserved
ISO/IEC DTS 9922:2024(E) 9922
2 Normative references [refs]
The following documents are referred to in the text in such a way that some or all of their content constitutes
requirements of this document. For dated references, only the edition cited applies. For undated references,
the latest edition of the referenced document (including any amendments) applies.
— ISO/IEC 14882:2020, Programming Languages — C++
© ISO/IEC 2024 – All rights reserved
ISO/IEC DTS 9922:2024(E) 9922
3 Terms and definitions [defs]
No terms and definitions are listed in this document.
ISO and IEC maintain terminological databases for use in standardization at the following addresses:
— IEC Electropedia: available at www.electropedia.org
— ISO Online browsing platform: available at www.iso.org/obp
© ISO/IEC 2024 – All rights reserved
ISO/IEC DTS 9922:2024(E) 9922
4 General [general]
4.1 Implementation compliance [general.compliance]
Conformance requirements for this document are those defined in 4.1, as applied to a merged document
consisting of ISO/IEC 14882:2020 amended by this document.
NOTE Conformance is defined in terms of the behaviour of programs.
4.2 Namespaces and headers and modifications to standard classes
[general.namespaces]
Since the extensions described in this document are experimental and not part of the ISO/IEC 14882:2020
library, they are not declared directly within namespace std. Unless otherwise specified, all components
described in this document either:
— modify an existing interface in the ISO/IEC 14882:2020 library in-place,
— are declared in a namespace whose name appends ::experimental::concurrency_v2 to a namespace
defined in the ISO/IEC 14882:2020 library, such as std, or
— are declared in a subnamespace of a namespace described in the previous bullet, whose name is not the
same as an existing subnamespace of namespace std.
Whenever an unqualified name is used in the specification of a declaration D, its meaning is established in
accordance with 4.1.2 by performing unqualified name lookup in the context of D.
NOTE 1 Argument-dependent lookup is not performed.
Similarly, the meaning of a qualified-id is established in accordance with performing qualified name lookup in
the context of D.
NOTE 2 Operators in expressions are not so constrained.
Table 1 shows the headers described in this document
Table 1 — C++ library headers





4.3 Feature-testing recommendations [general.feature.test]
An implementation that provides support for this document should define each feature test macro defined
in Table 2 and Table 3 if no associated headers are indicated for that macro, and if associated headers are
indicated for a macro, that macro is defined after inclusion of one of the corresponding headers specified in
Table 2 and Table 3.
Table 2 — Feature-test macros name
Title Subclause Macro name
Synchronized Value 5 __cpp_lib_experimental_synchronized_value
Hazard pointers 6.2 __cpp_lib_experimental_hazard_pointer
Read-copy update(RCU) 6.3 __cpp_lib_experimental_rcu
Bytewise atomic memcpy 7 __cpp_lib_experimental_bytewise_atomic_memcpy
Asymmetric Fence 8,33 __cpp_lib_experimental_asymmetric_fence
© ISO/IEC 2024 – All rights reserved
ISO/IEC DTS 9922:2024(E) 9922
Table 3 — Feature-test macros header
Title Value Header
Synchronized Value 202406
Hazard pointers 202406
Read-copy update(RCU) 202406
Bytewise atomic memcpy 202406
Asymmetric Fence 202406
© ISO/IEC 2024 – All rights reserved
ISO/IEC DTS 9922:2024(E) 9922
5 Synchronized Value [synchronizedvalue]
5.1 General [synchronizedvalue.general]
This clause describes a class template to provide locked access to a value in order to facilitate the construction
of race-free programs.
5.2 Header synopsis [synchronizedvalue.syn]
namespace std::experimental::inline concurrency_v2 {
template
class synchronized_value;
template
invoke_result_t apply(
F&& f,synchronized_value&. values);
}
5.3 Class template synchronized_value [synchronizedvalue.class]
namespace std::experimental::inline concurrency_v2 {
template
class synchronized_value
{
public:
synchronized_value(const synchronized_value&) = delete;
synchronized_value& operator=(const synchronized_value&) = delete;
template
synchronized_value(Args&&. args);
private:
T value; // exposition only
mutex mut; // exposition only
};
template
synchronized_value(T)
-> synchronized_value;
}
An object of type synchronized_value wraps an object of type T. The wrapped object can be accessed
by passing a callable object or function to apply. All such accesses are done with a lock held to ensure that
only one thread may be accessing the wrapped object for a given synchronized_value at a time.
template
synchronized_value(Args&&. args);
Constraints:
— (sizeof.(Args) != 1)istrueor(!same_as>
&&.) is true
— is_constructible_v is true
Effects: Direct-non-list-initializes value with std::forward(args).
Throws: Any exceptions emitted by the initialization of value.
system_error if any necessary resources cannot be acquired.
© ISO/IEC 2024 – All rights reserved
ISO/IEC DTS 9922:2024(E) 9922
5.4 apply function [synchronizedvalue.fn]
template
invoke_result_t apply(
F&& f,synchronized_value&. values);
Constraints: sizeof.(values) != 0 is true.
Effects: Equivalent to:
scoped_lock lock(values.mut.);
return invoke(std::forward(f),values.value.);
NOTE 1 It is not possible to pass a single instance of synchronized_value more than once to the same
invocation of apply.
EXAMPLE
synchronized_value sv;
void f(int,int);
apply(f,sv,sv); // undefined behaviour, sv passed more than once to same call
NOTE 2 The invocation of f cannot call apply directly or indirectly passing any of values.
© ISO/IEC 2024 – All rights reserved
ISO/IEC DTS 9922:2024(E) 9922
6 Safe reclamation [saferecl]
6.1 General [saferecl.general]
This clause adds safe-reclamation techniques, which are most frequently used to straightforwardly resolve
access-deletion races.
6.2 Hazard pointers [saferecl.hp]
6.2.1 General [saferecl.hp.general]
A hazard pointer is a single-writer multi-reader pointer that can be owned by at most one thread at any
time. Only the owner of the hazard pointer can set its value, while any number of threads may read its value.
The owner thread sets the value of a hazard pointer to point to an object in order to indicate to concurrent
threads—that may delete such an object—that the object is not yet safe to delete.
A class type T is hazard-protectable if it has exactly one public base class of type hazard_pointer_-
obj_base for some D and no base classes of type hazard_pointer_obj_base for any other
combination T’, D’. An object is hazard-protectable if it is of hazard-protectable type.
The span between creation and destruction of a hazard pointer h is partitioned into a series of protection
epochs; in each protection epoch, h either is associated with a hazard-protectable object, or is unassociated.
Upon creation, a hazard pointer is unassociated. Changing the association (possibly to the same object)
initiates a new protection epoch and ends the preceding one.
A hazard pointer belongs to exactly one domain.
An object of type hazard_pointer is either empty or owns a hazard pointer. Each hazard pointer is owned
by exactly one object of type hazard_pointer.
NOTE 1 An empty hazard_pointer object is different from a hazard_pointer object that owns an unassociated
hazard pointer. An empty hazard_pointer object does not own any hazard pointers.
An object x of hazard-protectable type T is retired to a domain with a deleter of type D when the member
function hazard_pointer_obj_base::retire is invoked on x. Any given object x shall be retired at
most once.
A retired object x is reclaimed by invoking its deleter with a pointer to x.
A hazard-protectable object x is definitely reclaimable in a domain dom with respect to an evaluation A if:
(a) x is not reclaimed, and
(b) x is retired to dom in an evaluation that happens before A, and
(c) for all hazard pointers h that belong to dom, the end of any protection epoch where h is associated
with x happens before A.
A hazard-protectable object x is possibly reclaimable in domain dom with respect to an evaluation A if:
(d) x is not reclaimed; and
(e) x is retired to dom in an evaluation R and A does not happen before R; and
(f) for all hazard pointers h that belong to dom, A does not happen before the end of any protection epoch
where h is associated with x; and
(g) for all hazard pointers h belonging to dom and for every protection epoch E of h during which h is
associated with x:
(1) A does not happen before the end of E, and
(2) if the beginning of E happens before x is retired, the end of E strongly happens before A, and
© ISO/IEC 2024 – All rights reserved
ISO/IEC DTS 9922:2024(E) 9922
(3) if E began by an evaluation of try_protect with argument src, label its atomic load operation
L. If there exists an atomic modification B on src such that L observes a modification that is
modification-ordered before B, and B happens before x is retired, the end of E strongly happens
before A.
NOTE 2 In typical use, a store to src sequenced before retiring x will be such an atomic operation B.
NOTE 3 Condition d(2) and d(3) convey the informal notion that a protection epoch that began before retiring
x, as implied either by the happens-before relation or the coherence order of some source, delays the reclamation
of x.
EXAMPLE The following example shows how hazard pointers allow updates to be carried out in the presence
of concurrent readers. The object of type hazard_pointer in print_name protects the object *ptr from
being reclaimed by ptr->retire until the end of the protection epoch.
struct Name : public hazard_pointer_obj_base { /∗ details ∗/ };
atomic name;
// called often and in parallel!
void print_name() {
hazard_pointer h = make_hazard_pointer();
Name* ptr = h.protect(name); /∗ Protection epoch starts ∗/
/∗ . safe to access ∗ptr . ∗/
} /∗ Protection epoch ends. ∗/
// called rarely, but possibly concurrently with print_name
void update_name(Name* new_name) {
Name* ptr = name.exchange(new_name);
ptr->retire();
}
6.2.2 Header synopsis [saferecl.hp.syn]
namespace std::experimental::inline concurrency_v2 {
// 6.2.3, class hazard_pointer_domain
class hazard_pointer_domain;
// 6.2.4, Default hazard_pointer_domain
hazard_pointer_domain& hazard_pointer_default_domain() noexcept;
// 6.2.5, Clean up
void hazard_pointer_clean_up(hazard_pointer_domain& domain = hazard_pointer_default_domain())
noexcept;
// 6.2.6, class template hazard_pointer_obj_base
template > class hazard_pointer_obj_base;
// 6.2.7, class hazard_pointer
class hazard_pointer;
// 6.2.8, Construct non-empty hazard_pointer
hazard_pointer make_hazard_pointer(
hazard_pointer_domain& domain = hazard_pointer_default_domain());
// 6.2.9, Hazard pointer swap
void swap(hazard_pointer&, hazard_pointer&) noexcept;
}
6.2.3 Class hazard_pointer_domain [saferecl.hp.domain]
6.2.3.1 General [saferecl.hp.domain.general]
The number of unreclaimed possibly-reclaimable objects retired to a domain is bounded. The bound is
implementation-defined.
NOTE The bound can be independent of other domains and can be a function of the number of hazard
pointers belonging to the domain, the number of threads that retire objects to the domain, and the number
of threads that use hazard pointers belonging to the domain.
© ISO/IEC 2024 – All rights reserved
ISO/IEC DTS 9922:2024(E) 9922
Concurrent access to a domain does not incur a data race.
class hazard_pointer_domain {
public:
hazard_pointer_domain() noexcept;
explicit hazard_pointer_domain(pmr::polymorphic_allocator poly_alloc) noexcept;
hazard_pointer_domain(const hazard_pointer_domain&) = delete;
hazard_pointer_domain& operator=(const hazard_pointer_domain&) = delete;
hazard_pointer_domain();
~
};
6.2.3.2 Member functions [saferecl.hp.domain.mem]
hazard_pointer_domain() noexcept;
Effects: Equivalent to hazard_pointer_domain({}).
explicit hazard_pointer_domain(pmr::polymorphic_allocator poly_alloc) noexcept;
Remarks: All allocation and deallocation related to hazard pointers belonging to this domain use a
copy of poly_alloc.
hazard_pointer_domain();
~
Preconditions: All hazard pointers belonging to *this have been destroyed.
Effects: Reclaims all objects retired to this domain that have not yet been reclaimed.
6.2.4 Default hazard_pointer_domain [saferecl.hp.domain.default]
hazard_pointer_domain& hazard_pointer_default_domain() noexcept;
Returns: A reference to the default hazard_pointer_domain.
Remarks: The default domain has an unspecified allocator and has static storage duration. The
initialization of the default domain strongly happens before this function returns; the sequencing is
otherwise unspecified.
6.2.5 Clean up [saferecl.hp.cleanup]
void hazard_pointer_clean_up(hazard_pointer_domain& domain = hazard_pointer_default_domain())
noexcept;
Effects: May reclaim possibly-reclaimable objects retired to domain.
Postconditions: All definitely-reclaimable objects retired to domain have been reclaimed.
Synchronization: The completion of the deleter for each reclaimed object synchronizes with the return
...

Questions, Comments and Discussion

Ask us and Technical Secretary will try to provide an answer. You can facilitate discussion about the standard in here.

Loading comments...