diff --git a/README.md b/README.md index b7aeb51..64853ac 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ - is the repository for + is the repository for the C++ Technical Specification "Concurrency TS 2". The draft Technical Specification is found in the `src` directory and is @@ -7,6 +7,40 @@ sources, or you can use the `latexmk` program e.g. `latexmk -pdf ts` will generate a PDF. \textbf{Concurrency TS2 Editor's Report} +\textbf{October 2023 pre-Kona Plenary meeting} +N4968 is the replaced PDTS of Concurrency TS V2. +It contains changes directed by ISO to remove colour changes and replace with explicit change annotations. +\textbf{Mark 2024 post-Tokyo Plenary meeting} N4968 is the replaced PDTS of Concurrency TS V2. It contains changes directed by ISO. The changes include removing paragraph numbers, including item numbers where appropriate, changing internal reference to item number instead of paragraph numbers, updating the font and numbering for notes and examples, and making references normative. + +\textbf{August 2023 post-Varna Plenary meeting} +N4956 is the proposed PDTS of Concurrency TS Version 2. +It contains changes to the N4953 as directed by the committee review and author review. This version has been sent to Geneva. + +Some of those changes are +1. Convert texttt to tcode +2. Use C++20 section numbers +3. Update feature-test macro value/date +4. Use code fonts for header names +5. Capitalize bytewise + + +\textbf{June 2023 pre-Varna Plenary meeting} +N4953 is the proposed working draft of Concurrency TS Version 2. It contains changes to the Concurrency TS as directed by the committee at the Nov 2022 Kona and Feb 2023 Issaquah plenary meeting, and editorial changes. + +FROM KONA: +Concurrency Technical Specification polls +4. Apply the changes in P2396R1 (Concurrency TS fixes) to the Working Paper for Extensions for C++ for Concurrency, version 2. + +5. Apply the changes in P1478R8 (Byte-wise atomic memcpy) to the Working Paper for Extensions for C++ for Concurrency, version 2. + +6. Apply the changes in P1202R5 (Asymmetric Fences) to the Working Paper for Extensions for C++ for Concurrency, version 2. + +FROM ISSAQUAH: +Concurrency TS v2 polls +1. Apply the changes in P0290R4 (synchronized value) to the Concurrency TS v2 working paper. + + + \textbf{pre-Oct 2021 virtual Plenary meeting} N4895 is the proposed working draft of Concurrency TS Version 2. It contains changes to the Concurrency TS as directed by the committee at the June 2021 virtual plenary meeting, and editorial changes. diff --git a/src/ISOlogo.png b/src/ISOlogo.png new file mode 100644 index 0000000..b1b5f1a Binary files /dev/null and b/src/ISOlogo.png differ diff --git a/src/asymmetric.tex b/src/asymmetric.tex new file mode 100644 index 0000000..c6e5910 --- /dev/null +++ b/src/asymmetric.tex @@ -0,0 +1,120 @@ +%!TEX root = ts.tex + +\rSec0[asymmetric]{Asymmetric Fence} + +\rSec1[asymmetric.general]{General} + +This clause describes Asymmetric Fence access. + + +\rSec1[asymmetric.syn]{Header synopsis} + + +\begin{codeblock} +namespace std::experimental::inline concurrency_v2 { + +// 7.3 asymmetric_thread_fence_heavy +void asymmetric_thread_fence_heavy(memory_order order) noexcept; + +// 7.4 asymmetric_thread_fence_light +void asymmetric_thread_fence_light(memory_order order) noexcept; +} +\end{codeblock} + +%%\uline{\texttt{\ namespace\ std::experimental::inline\ %%concurrency\_v2\ \{\ \ ~~void*\ %%atomic\_load\_per\_byte\_memcpy(void*\ dest,\ const\ void*\ %%source,\ size\_t\ count,\ memory\_order\ order);\ \ ~~void*\ %%atomic\_store\_per\_byte\_memcpy(void*\ dest,\ const\ void*\ %%source,\ size\_t\ count,\ memory\_order\ order);\ \ ~~\#define\ %%\_\_cpp\_lib\_experimental\_bytewise\_atomic\_memcpy\ \ %%202XYYL\ \}}} +%%\rSec1[bytewiseatomicmemcpy.general]{General} +%\pnum + +This subclause introduces synchronization primitives called \defn{heavyweight-fences} and +\defn{lightweight-fences}. Like fences, heavyweight-fences and lightweight-fences can have acquire +semantics, release semantics, or both, and can be sequentially consistent (in which case they +are included in the total order \tcode{S} on \tcode{memory_order::seq_cst} operations). +A heavyweight-fence shall have all the +synchronization effects of a fence. % (\CppXref{31.11}). + +NOTE +Heavyweight-fences and +lightweight-fences are distinct from fences. + +%\pnum +A heavyweight-fence with acquire semantics is called an \defn{acquire heavyweight-fence}. A +heavyweight-fence with release semantics is called a \defn{release heavyweight-fence}. A +lightweight-fence with acquire semantics is called an \defn{acquire lightweight-fence}. A +lightweight-fence with release semantics is called a \defn{release lightweight-fence}. + +%\pnum +If there are evaluations A and B, and atomic operations X and Y, both operating on some atomic +object M, such that A is sequenced before X, X modifies M, Y is sequenced before B, and Y +reads the value written by X or a value written by any side effect in the hypothetical release +sequence X would head if it were a release operation, and one of the following hold: +\setenumerate[0]{label=(\alph*)} +\begin{enumerate} + \item A is a release lightweight-fence and B is an acquire heavyweight-fence; or +\item A is a release heavyweight-fence and B is an acquire lightweight-fence +\end{enumerate} + +then any evaluation sequenced before A strongly happens before any evaluation that B is +sequenced before. + + +\rSec1[asymmetric.heavy]{asymmetric_thread_fence_heavy} +\begin{itemdecl} +void asymmetric_thread_fence_heavy(memory_order order) noexcept; +\end{itemdecl} + +\begin{itemdescr} + + +%\pnum +\effects +Depending on the value of \tcode{order}, this operation: +\setenumerate[0]{label=(\alph*)} +\begin{enumerate} + \item has no effects, if \tcode{order == memory\_order::relaxed} is \tcode{true}; +\item is an acquire heavyweight-fence, if \tcode{order == memory\_order::acquire} or \tcode{order == +memory\_order::consume} is \tcode{true}; +\item is a release heavyweight-fence, if \tcode{order == memory\_order::release} is \tcode{true}; +\item is both an acquire heavyweight-fence and a release heavyweight-fence, if \tcode{order == +memory_order::acq_rel} is \tcode{true}; +\item is a sequentially consistent acquire and release heavyweight-fence, if \tcode{order == +memory_order::seq_cst} is \tcode{true}. +\end{enumerate} + +\end{itemdescr} + +\rSec1[asymmetric.light]{asymmetric_thread_fence_light} +\begin{itemdecl} +void asymmetric_thread_fence_light(memory_order order) noexcept; +\end{itemdecl} + +\begin{itemdescr} + + +%\pnum +\effects +Depending on the value of \tcode{order}, this operation: +\setenumerate[0]{label=(\alph*)} +\begin{enumerate} + + \item has no effects, if \tcode{order == memory\_order::relaxed} is \tcode{true}; +\item is an acquire lightweight-fence, if \tcode{order == memory\_order::acquire} or \tcode{order == +memory\_order::consume} is \tcode{true}; +\item is a release lightweight-fence, if \tcode{order == memory\_order::release} is \tcode{true}; +\item is both an acquire lightweight-fence and a release lightweight-fence, if \tcode{order == +memory\_order::acq\_rel} is \tcode{true}; +\item is a sequentially consistent acquire and release lightweight-fence, if \tcode{order == +memory\_order::seq\_cst} is \tcode{true}. +\end{enumerate} + +\end{itemdescr} + + + +NOTE Delegating both heavyweight-fence and lightweight-fence functions to an +\tcode{atomic_thread_fence(order)} call is a valid implementation. Implementations can adopt +techniques in which calls to \tcode{asymmetric_thread_fence_light} execute more quickly than calls +to \tcode{atomic_thread_fence} with the same \tcode{memory_order}, at the cost of +\tcode{asymmetric_thread_fence_heavy} executing more slowly than calls to +\tcode{atomic_thread_fence} with the same \tcode{memory_order}. + + diff --git a/src/backcover.tex b/src/backcover.tex new file mode 100644 index 0000000..4846f2c --- /dev/null +++ b/src/backcover.tex @@ -0,0 +1,16 @@ +%!TEX root = ts.tex +%%-------------------------------------------------- +%% Title page for C++ Technical Specification + +\thispagestyle{empty} +\begin{tabularx}{6.5in}{p{3.5in}|p{3in}} +\resizebox{0.75in}{!}{\includegraphics{ISOlogo.png}} + & \vspace{3in} ~ \\ +\hline +\vspace{5in} \textsf{\textbf{ICS NN.NNN.NN}} + & \\ +\scriptsize \textsf{Price based on 21 pages} & \\ + & \\ +\scriptsize \textsf{\textcopyright\ ISO 2024 -- all rights reserved} + & \multicolumn{1}{r}{\large \textsf{\textbf{\textcolor{red}{iso.org}}}} \\ +\end{tabularx} diff --git a/src/bytewiseatomic.tex b/src/bytewiseatomic.tex new file mode 100644 index 0000000..4023fe4 --- /dev/null +++ b/src/bytewiseatomic.tex @@ -0,0 +1,112 @@ +%!TEX root = ts.tex + +\rSec0[atomiccpy]{Bytewise Atomic Memcpy} + +\rSec1[atomiccpy.general]{General} + +This clause describes bytewise atomic memcpy access. + + +\rSec1[atomiccpy.syn]{Header \tcode{} synopsis} +%%\uline{\textbf{Header +%%\texttt{\textless{}experimental/bytewise\_atomic\_memcpy\textgre%%ater{}} +%%synopsis}} + +\begin{codeblock} +namespace std::experimental::inline concurrency_v2 { + void* atomic_load_per_byte_memcpy(void* dest, const void* source, size_t count, memory_order order); + void* atomic_store_per_byte_memcpy(void* dest, const void* source, size_t count, memory_order order); +} +\end{codeblock} + +%%\uline{\texttt{\ namespace\ std::experimental::inline\ %%concurrency\_v2\ \{\ \ ~~void*\ %%atomic\_load\_per\_byte\_memcpy(void*\ dest,\ const\ void*\ %%source,\ size\_t\ count,\ memory\_order\ order);\ \ ~~void*\ %%atomic\_store\_per\_byte\_memcpy(void*\ dest,\ const\ void*\ %%source,\ size\_t\ count,\ memory\_order\ order);\ \ ~~\#define\ %%\_\_cpp\_lib\_experimental\_bytewise\_atomic\_memcpy\ \ %%202XYYL\ \}}} +%%\rSec1[bytewiseatomicmemcpy.general]{General} +% \pnum + +The \tcode{atomic_load_per_byte_memcpy()} and +\tcode{atomic_store_per_byte_memcpy()} functions support concurrent +programming idioms in which values may be read while being written, but +the value is trusted only when it can be determined after the fact that +a race did not occur. + +%\begin{note} +NOTE So-called "seqlocks" are the canonical +example of such an idiom.%\end{note} + + +\rSec1[atomiccpy.load]{\tcode{atomic_load_per_byte_memcpy}} +% \pnum + +The \tcode{atomic_load_per_byte_memcpy} / +\tcode{atomic_store_per_byte_memcpy} functions behave as if the +\tcode{source} and \tcode{dest} bytes respectively were individual +atomic objects. + +\textbf{\tcode{void*\ atomic_load_per_byte_memcpy(void* dest, const void* source, size_t count, memory_order order);}} + +\begin{itemdescr} +% \pnum + +\expects + +\tcode{order} is \tcode{memory_order::acquire} or +\tcode{memory_order::relaxed}. \tcode{(char*)dest + [0, count)} +and \tcode{(const char*)source + [0, count)} are valid ranges +that do not overlap. + +% \pnum +\effects +Copies \tcode{count} consecutive bytes pointed to by +\tcode{source} into consecutive bytes pointed to by \tcode{dest}. Each +individual load operation from a source byte is atomic with memory order +\tcode{order}. These individual loads are unsequenced with respect to +each other. The function implicitly creates objects (\CppXrefInAccord{7.2}) +in the destination region of storage immediately prior to copying the +sequence of bytes to the destination. + +%\begin{note} +NOTE There is no requirement +that the individual bytes be copied in order, or that the implementation +operates on individual bytes.%\end{note} + +% \pnum +\returns +\tcode{dest}. +\end{itemdescr} + +\rSec1[atomiccpy.store]{\tcode{atomic_store_per_byte_memcpy}} +\textbf{\tcode{void* atomic_store_per_byte_memcpy(void* dest, const void* source, size_t count, memory_order order);}} + +\begin{itemdescr} +% \pnum + +\expects +\tcode{order} is \tcode{memory_order::release} or +\tcode{memory_order::relaxed}. \tcode{(char*)dest + [0, count)} +and \tcode{(const char*)source + [0, count)} are valid ranges +that do not overlap. + +% \pnum +\effects +Copies \tcode{count} consecutive bytes pointed to by +\tcode{source} into consecutive bytes pointed to by \tcode{dest}. Each +individual store operation to a destination byte is atomic with memory +order \tcode{order}. These individual stores are unsequenced with +respect to each other. The function implicitly creates objects +(\CppXrefInAccord{6.7.2}) in the destination region of storage immediately +prior to copying the sequence of bytes to the destination. + +% \pnum +\returns + +\tcode{dest}. +\end{itemdescr} + +%\begin{note} +NOTE If any of the atomic byte loads performed by an +\tcode{atomic_load_per_byte_memcpy()} call A with +\tcode{memory_order::acquire} argument take their value from an atomic +byte store performed by \tcode{atomic_store_per_byte_memcpy()} call +B with \tcode{memory_order::release} argument, then the start of B +strongly happens before the completion of A.%\end{note} +%%\end{quote} diff --git a/src/config.tex b/src/config.tex index 8a41179..16cb883 100644 --- a/src/config.tex +++ b/src/config.tex @@ -1,11 +1,11 @@ %!TEX root = ts.tex %%-------------------------------------------------- %% Version numbers -\newcommand{\docno}{N4895} -\newcommand{\isodocno}{ISO/IEC ?????:2021(E)} -\newcommand{\prevdocno}{None} +\newcommand{\docno}{9922} +\newcommand{\isodocno}{ISO/IEC DTS 9922:2024(E)} +\newcommand{\prevdocno}{N4895;N4953;N4956;N4968} \newcommand{\cppver}{201703L @@@} %% MW: need update -\newcommand{\tsver}{202108} +\newcommand{\tsver}{202406} %% Title \newcommand{\doctitle}{Extensions to \Cpp for Concurrency Version 2 @@@} @@ -17,8 +17,8 @@ %% Release date \newcommand{\reldate}{\today} -\newcommand{\copyrightyear}{2021} -\newcommand{\cppstddocno}{ISO/IEC 14882:2020} +\newcommand{\copyrightyear}{2024} +\newcommand{\cppstddocno}{ISO/IEC DTS 9922:2024(E)} %% Library chapters diff --git a/src/cover-wd.tex b/src/cover-wd.tex index d5294c4..c8d4433 100644 --- a/src/cover-wd.tex +++ b/src/cover-wd.tex @@ -4,28 +4,53 @@ \thispagestyle{empty} -\begingroup -\def\hd{\begin{tabular}{ll} - \textbf{Document Number:} & {\larger\docno} \\ - \textbf{Date:} & \reldate \\ - \textbf{Revises:} & \prevdocno \\ - \textbf{Reply to:} & Michael Wong \\ - & Codeplay \\ - & fraggamuffin@gmail.com - \end{tabular} -} -\newlength{\hdwidth} -\settowidth{\hdwidth}{\hd} -\hfill\begin{minipage}{\hdwidth}\hd\end{minipage} -\endgroup +\begin{tabularx}{6.5in}{p{3.5in}|p{3in}} +\resizebox{0.75in}{!}{\includegraphics{ISOlogo.png}} + & \begin{tabular}[t]{l} + ~ \vspace{-0.7in} ~ \\ + \huge \textsf{\textbf{International}} \\ + \huge \textsf{\textbf{Standard}} \\ + ~ \vspace{2in} ~ \\ + %%\large \textsf{\textbf{\textcolor{red}{ISO SC22 WG21 N4968}}} \\ + \\ + \end{tabular} \\ +\hline +\vspace{0.05in} \large \textbf{Programming Languages — Technical specification for C++ Extensions for Concurrency 2} + & \vspace{0.05in} \large \textsf{\textbf{Second edition}} \\ +\emph{Langages de programmation — Spécification technique pour les extensions C++ pour la Concurrence 2} + & \large \textsf{\textbf{2024-03}} \\ +\vspace{5.2in} ~ & \\ +\scriptsize \textsf{Reference number} + & \\ +\scriptsize \textsf{ISO 9922:2024(en)} + & \scriptsize \textsf{\textcopyright\ ISO 2024} +\end{tabularx} -\vspace{2.5cm} -\begin{center} -\textbf{\Huge -Working Draft, Extensions to \Cpp for Concurrency Version 2} -\end{center} -\vfill -\textbf{Note: this is an early draft. It's known to be incomplet and - incorrekt, and it has lots of - b\kern-1.2pta\kern1ptd\hspace{1.5em}for\kern-3ptmat\kern0.6ptti\raise0.15ex\hbox{n}g.} + +% \begingroup +% \def\hd{\begin{tabular}{ll} +% \textbf{Document Number:} & {\larger\docno} \\ +% \textbf{Date:} & \reldate \\ +% \textbf{Revises:} & \prevdocno \\ +% \textbf{Reply to:} & Michael Wong \\ +% & Codeplay \\ +% & fraggamuffin@gmail.com +% \end{tabular} +% } +% \newlength{\hdwidth} +% \settowidth{\hdwidth}{\hd} +% \hfill\begin{minipage}{\hdwidth}\hd\end{minipage} +% \endgroup + +% \vspace{2.5cm} +% \begin{center} +% \textbf{\Huge +% Programming Languages — Technical specification for \Cpp extensions for concurrency 2 +%%PDTS, Extensions to \Cpp for Concurrency +% } +% \end{center} +% \vfill +%%\textbf{Note: this is an early draft. It's known to be incomplet and +%% incorrekt, and it has lots of +%% b\kern-1.2pta\kern1ptd\hspace{1.5em}for\kern-%%3ptmat\kern0.6ptti\raise0.15ex\hbox{n}g.} \newpage diff --git a/src/foreword.tex b/src/foreword.tex index 3266ad1..4ca6103 100644 --- a/src/foreword.tex +++ b/src/foreword.tex @@ -1,17 +1,23 @@ %!TEX root = ts.tex \rSec0[foreword]{Foreword} +%%\hypersetup{colorlinks=true, linkcolor=blue, urlcolor=blue} 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 activity. ISO and IEC technical committees collaborate in fields of mutual interest. 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 approval criteria needed for the 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). +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 approval criteria needed for the 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 \href{www.iso.org/directives}{www.iso.org/directives} +or +\href{www.iec.ch/members_experts/refdocs}{www.iec.ch/members_experts/refdocs}). -Attention is drawn to the possibility that some of the elements of this document may be the subject of patent rights. ISO and IEC shall not be held responsible for identifying any or all such patent rights. Details of any patent rights identified during the development of the document will be in the Introduction and/or on the ISO list of patent declarations received (see www.iso.org/patents) or the IEC list of patent declarations received (see http://patents.iec.ch). +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 \href{www.iso.org/patents}{www.iso.org/patents} +and +\href{patents.iec.ch/}{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 on 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 Organization (WTO) principles in the Technical Barriers to Trade (TBT), see www.iso.org/iso/foreword.html. +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 Organization (WTO) principles in the Technical Barriers to Trade (TBT) see \href{www.iso.org/iso/foreword.html/}{www.iso.org/iso/foreword.html}. In the IEC, see \href{www.iec.ch/understanding-standards/}{www.iec.ch/understanding-standards}. -This document was prepared by Joint Technical Committee ISO/IEC JTC 1, \textit{Information technology}, Subcommittee SC 22, \textit{Programming languages, their environments and system software interfaces}. +This document was prepared by Joint Technical Committee ISO/IEC JTC 1, \emph{Information technology}, Subcommittee SC 22, \emph{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. \ No newline at end of file +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 \href{www.iso.org/members.html/}{www.iso.org/members.html} and \href{www.iec.ch/national-committees/}{www.iec.ch/national-committees}. diff --git a/src/front.tex b/src/front.tex index 8f8abbb..4ad2b73 100644 --- a/src/front.tex +++ b/src/front.tex @@ -12,6 +12,7 @@ \renewcommand\@pnumwidth{2.5em} \makeatother + \begin{KeepFromToc} \tableofcontents \end{KeepFromToc} diff --git a/src/general.tex b/src/general.tex index eda9065..1ac26ad 100644 --- a/src/general.tex +++ b/src/general.tex @@ -2,84 +2,77 @@ \rSec0[scope]{Scope} -\pnum -This document describes requirements for implementations of an interface that computer programs written in the C++ programming language may use to invoke algorithms with concurrent execution. The algorithms described by this document are realizable across a broad class of computer architectures. +%\pnum +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. -\pnum -{\cppstddocno} provide important context and specification for -this document. This document is written as a set of changes against that specification. Instructions to modify or add paragraphs are written as -explicit instructions. Modifications made directly to existing text from {\cppstddocno} use \added{underlining} to represent added text and \removed{strikethrough} to represent deleted text. +%\pnum +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. -\pnum -This document is non-normative. Some of the functionality described by this document may be considered for standardization in a future version of C++, but it is not currently part of any C++ standard. Some of the functionality in this document may never be standardized, and other functionality may be standardized in a substantially changed form. - -\pnum -The goal of this document is to build widespread existing practice for concurrency in the C++ standard algorithms library. It gives advice on extensions to those vendors who wish to provide them. +%\pnum +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. \rSec0[refs]{Normative references} -\pnum -The following referenced document is indispensable for the application 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. +%\pnum +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. \begin{itemize} -\item {\cppstddocno}, \doccite{Programming Languages --- C++} +\item ISO/IEC 14882:2020, \doccite{Programming Languages --- C++} \end{itemize} -\pnum -ISO/IEC 14882:2020 is herein called the C++ Standard. References to clauses within the C++ Standard are written as ``\CppXref{3.2}''. The library described in \CppXref{16-32} is herein called the C++ Standard Library. - -\pnum -Unless otherwise specified, the whole of the C++ Standard's Library introduction (\CppXref{16}) is included into this Technical Specification by reference. +%\pnum +%Unless otherwise specified, the whole of the ISO/IEC 14882:2020 library introduction (\CppXref{16}) is included into this Technical Specification by reference. \rSec0[defs]{Terms and definitions} -\pnum +%\pnum \indextext{definitions|(}% No terms and definitions are listed in this document. ISO and IEC maintain terminological databases for use in standardization at the following addresses: \begin{itemize} - \item IEC Electropedia: available at https://www.electropedia.org/ - \item ISO Online browsing platform: available at https://www.iso.org/obp + \item IEC Electropedia: available at \href{//www.electropedia.org/}{www.electropedia.org} + \item ISO Online browsing platform: available at \href{//www.iso.org/obp/}{www.iso.org/obp} \end{itemize} \rSec0[general]{General} \rSec1[general.compliance]{Implementation compliance} -\pnum -Conformance requirements for this document are those defined in \CppXref{4.1}, as applied to a merged document consisting of C++20 amended by this document. -\begin{note} -Conformance is defined in terms of the behavior of programs. -\end{note} +%\pnum +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. +%%\begin{note} + +NOTE Conformance is defined in terms of the behaviour of programs.%%\end{note} \rSec1[general.namespaces]{Namespaces and headers and modifications to standard classes} -\pnum -Since the extensions described in this technical specification are experimental and not part of the C++ standard library, they are not declared directly within namespace \tcode{std}. Unless otherwise specified, all components described in this technical specification either: +%\pnum +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 \tcode{std}. Unless otherwise specified, all components described in this document either: \begin{itemize} - \item modify an existing interface in the C++ Standard Library in-place, - \item are declared in a namespace whose name appends \tcode{::experimental::concurrency\_v2} to a namespace defined in the C++ Standard Library, such as \tcode{std}, or + \item modify an existing interface in the ISO/IEC 14882:2020 library in-place, + \item are declared in a namespace whose name appends \tcode{::experimental::concurrency\_v2} to a namespace defined in the ISO/IEC 14882:2020 library, such as \tcode{std}, or \item 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 \tcode{std}. \end{itemize} -\pnum +%\pnum Whenever an unqualified name is used in the specification of a declaration \tcode{D}, its meaning is established -as-if by performing unqualified name lookup +in accordance with 4.1.2 by performing unqualified name lookup in the context of \tcode{D}. \begin{note} -Argument-dependent lookup is not performed. -\end{note} +Argument-dependent lookup is not performed.\end{note} Similarly, the meaning of a \grammarterm{qualified-id} is established -as-if by performing qualified name lookup +in accordance with performing qualified name lookup in the context of \tcode{D}. \begin{note} -Operators in expressions are not so constrained. -\end{note} +Operators in expressions are not so constrained.\end{note} -%%The header described in this document (see Table~\ref{tab:info.headers}) -%%shall import the contents of \tcode{::std::experimental::concurrency::v2} into +%\pnum +\hyperref[tab:C++ library headers]{Table~1} shows the headers described in this document +%%shall import the contents of %%\tcode{::std::experimental::concurrency::v2} into %%\tcode{::std::experimental::concurrency_v1} as if by: %%\begin{codeblock} @@ -89,46 +82,186 @@ %%\end{codeblock} -%%\begin{floattable}{Concurrency\_v2 library headers}{tab:info.headers} -%%{l} +% \begin{floattable}{\textbf{C++ library headers}}{tab:info.headers} +% {l} +% \topline +\begin{table}[htb] +\centering +\textbf{Table 1 \textemdash\ C++ library headers} + +\vspace{0.1in} +\begin{tabular}{|l|} +\hline +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\hline +\end{tabular} +\end{table} + +% \end{floattable} + +\rSec1[general.feature.test]{\textbf{Feature-testing recommendations}} +\label{tab:C++ library headers} +%\pnum +An implementation that provides support for this document should define each feature test macro defined in +\hyperref[Feature-test macros name]{Table~2} +and +\hyperref[Feature-test macros header]{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 +\hyperref[Feature-test macros name]{Table~2} +and +\hyperref[Feature-test macros header]{Table~3}. + +%%\begin{floattable}{\textbf{Feature-test macros name}}{tab:intro.features} +%%{lllll} %%\topline -%%\tcode{} \\ -%%\end{floattable} +%%\lhdr {Title} & \lhdr {Subclause} & \chdr{Macro name} & %%\rhdr{Value} & \rhdr{Header} \\ +%%{ll} +%%\lhdr {Title} & +%%\rhdr {Subclause \\ Macro name \\ Value \\ Header} \\ -\rSec1[general.feature.test]{Feature-testing recommendations (Informative)} -\pnum -An implementation that provides support for this document should define each feature test macro defined in \tref{intro.features} 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 the table. +%%\capsep +%%\tcode{__cpp_concurrency\_v2} & \tcode{\tsver} & none \\ +%%\tcode{Hazard pointers} & \tcode{5.2} & %%\tcode{__cpp_lib_experimental_hazard_pointer} & \tcode{\tsver} %%& \tcode{} \\ +%%\tcode{Read-copy update(RCU)} & \tcode{5.3} & %%\tcode{__cpp_lib_experimental_rcu} & \tcode{\tsver} & %%\tcode{} \\ +%%\tcode{bytewise atomic memcpy} & \tcode{6} & %%\tcode{__cpp_lib_experimental_bytewise_atomic_memcpy} & %%\tcode{\tsver} & \tcode{} \\ +%%\tcode{Asymmetric Fence} & \tcode{7} & %%\tcode{__cpp_lib_experimental_asymmetric_fence} & \tcode{\tsver} %% & \tcode{} \\ +%%\tcode{Synchronized Value} & \tcode{8} & %%\tcode{__cpp_lib_experimental_synchronized_value} & %%\tcode{\tsver} & \tcode{} \\ +%%\end{floattable} -\begin{floattable}{Feature-test macros}{tab:intro.features} -{lll} -\topline -\lhdr{Macro name} & \chdr{Value} & \rhdr{Header} \\ -\capsep +% \begin{floattable}{\textbf{Feature-test macros name}}{tab:intro.features1} +% {lll} +% \topline +\begin{table}[htb] +\centering +\textbf{Table 2 \textemdash\ Feature-test macros name} +\label{Feature-test macros name} + +\vspace{0.1in} +\begin{tabular}{|lll|} +\hline +\textbf{Title} & \textbf{Subclause} & \textbf{Macro name} \\ +\hline +\hline +%%{ll} +%%\lhdr {Title} & +%%\rhdr {Subclause \\ Macro name \\ Value \\ Header} \\ + +% \capsep +%%\tcode{__cpp_concurrency\_v2} & \tcode{\tsver} & none \\ +\tcode{Synchronized Value} & \tcode{5} & \tcode{__cpp_lib_experimental_synchronized_value} \\ +\tcode{Hazard pointers} & \tcode{6.2} & \tcode{__cpp_lib_experimental_hazard_pointer} \\ +\tcode{Read-copy update(RCU)} & \tcode{6.3} & \tcode{__cpp_lib_experimental_rcu} \\ +\tcode{Bytewise atomic memcpy} & \tcode{7} & \tcode{__cpp_lib_experimental_bytewise_atomic_memcpy} \\ +\tcode{Asymmetric Fence} & \tcode{8,33} & \tcode{__cpp_lib_experimental_asymmetric_fence} \\ + +% \end{floattable} +\hline +\end{tabular} +\end{table} + +% \begin{floattable}{\textbf{Feature-test macros header}}{tab:intro.features2} +% {lll} +% \topline +% \lhdr {Title} & \chdr{Value} & \rhdr{Header} \\ +\begin{table}[htb] +\centering +\textbf{Table 3 \textemdash\ Feature-test macros header} + +\vspace{0.1in} +\begin{tabular}{|lll|} +\hline +\textbf{Title} & \textbf{Value} & \textbf{Header} \\ +\hline +%%{ll} +%%\lhdr {Title} & +%%\rhdr {Subclause \\ Macro name \\ Value \\ Header} \\ + +% \capsep %%\tcode{__cpp_concurrency\_v2} & \tcode{\tsver} & none \\ -\tcode{__cpp_lib_concurrency\_v2} & \tcode{\tsver} & \tcode{} \\ -\end{floattable} -\rSec1[general.plans]{Future plans (Informative)} -\pnum -This section describes tentative plans for future versions of this technical specification and plans for moving content into -future versions of the C++ Standard. - -\pnum - The C++ committee intends to release a new version of this technical specification approximately every few years, containing -the concurrency extensions we hope to add to a near-future version of the C++ Standard. Future versions will define their -contents in \tcode{std::experimental::concurrency\_v3}, \tcode{std::experimental::concurrency\_v4}, etc., with the most recent -implemented version inlined into \tcode{std::ex\-perimental}. - -\pnum -When an extension defined in this or a future version of this technical specification represents enough existing practice, it -will be moved into the next version of the C++ Standard by removing the \tcode{experimental::con\-currency\_v$N$} segment of its -namespace and by removing the \tcode{experimental/} prefix from its header's path. - -\rSec1[general.ack]{Acknowledgments} - -This work is the result of a collaboration of researchers in industry and academia. We wish to thank the -original authors of this document, Michael Wong, Paul McKenney, and Maged Michael. We also wish to thank people -who made valuable contributions within and outside these groups, including Jens Maurer, and many others not named -here who contributed to the discussion. +\tcode{Synchronized Value} & \tcode{\tsver} & \tcode{} \\ +\tcode{Hazard pointers} & \tcode{\tsver} & \tcode{} \\ +\tcode{Read-copy update(RCU)} & \tcode{\tsver} & \tcode{} \\ +\tcode{Bytewise atomic memcpy} & \tcode{\tsver} & \tcode{} \\ +\tcode{Asymmetric Fence} & \tcode{\tsver} & \tcode{} \\ +\hline +\end{tabular} +\end{table} + +% \end{floattable} + +~ + +~ + +~ + +~ + +~ + +~ + +~ + +~ + +~ + +~ + +~ + +~ + +~ + +~ + +~ + +~ + +~ + +~ + +~ + +~ + +~ + +~ + +~ +\label{Feature-test macros header} + +% \rSec1[general.plans]{Future plans (Informative)} +% %\pnum +% This clause describes tentative plans for future versions of this document and plans for moving content into +% future versions of ISO/IEC 14882:2020. + +% \pnum +% The C++ committee intends to release a new version of this document approximately every few years, containing +% the concurrency extensions we hope to add to a near-future version of ISO/IEC 14882:2020. Future versions will define their +% contents in \tcode{std::experimental::concurrency\_v3}, \tcode{std::experimental::concurrency\_v4}, etc., with the most recent +% implemented version inlined into \tcode{std::ex\-perimental}. + +% \pnum +% When an extension defined in this or a future version of this document represents enough existing practice, it +% will be moved into the next version of ISO/IEC 14882:2020 by removing the \tcode{experimental::con\-currency\_v$N$} segment of its +% namespace and by removing the \tcode{experimental/} prefix from its header's path. + +% \rSec1[general.ack]{Acknowledgments} + +% This work is the result of a collaboration of researchers in industry and academia. We wish to thank the +% original authors of this document, Michael Wong, Paul McKenney, and Maged Michael, and the editing review team of Jonathan Wakely, Daniel Krügler, and Bryan St. Amour. We also wish to thank people +% who made valuable contributions within and outside these groups, including Jens Maurer, and many others not named +% here who contributed to the discussion. diff --git a/src/macros.tex b/src/macros.tex index ca96745..c33be9a 100644 --- a/src/macros.tex +++ b/src/macros.tex @@ -225,10 +225,10 @@ \newcommand{\gterm}[1]{\GrammarStylex{#1}} \newcommand{\fakegrammarterm}[1]{\gterm{#1}} \newcommand{\keyword}[1]{\tcode{#1}\indextext{\idxcode{#1}}} % macro length: 8 -\newcommand{\grammarterm}[1]{\indexgram{\idxgram{#1}}\gterm{#1}} +\newcommand{\grammarterm}[1]{#1} \newcommand{\grammartermnc}[1]{\indexgram{\idxgram{#1}}\gterm{#1\nocorr}} \newcommand{\regrammarterm}[1]{\textit{#1}} -\newcommand{\placeholder}[1]{\textit{#1}} % macro length: 12 +\newcommand{\placeholder}[1]{#1} % macro length: 12 \newcommand{\placeholdernc}[1]{\textit{#1\nocorr}} % macro length: 14 \newcommand{\exposid}[1]{\tcode{\placeholder{#1}}} % macro length: 8 \newcommand{\exposidnc}[1]{\tcode{\placeholdernc{#1}}\itcorr[-1]} % macro length: 10 @@ -236,7 +236,7 @@ \newcommand{\defnlibxname}[1]{\indexlibrary{\idxxname{#1}}\xname{#1}} % Non-compound defined term. -\newcommand{\defn}[1]{\defnx{#1}{#1}} +\newcommand{\defn}[1]{#1} % Defined term with different index entry. \newcommand{\defnx}[2]{\indexdefn{#2}\textit{#1}} % Compound defined term with 'see' for primary term. @@ -280,8 +280,8 @@ \newcommand{\leftshift}[1]{\ensuremath{\mathbin{\mathsf{lshift}_{#1}}}} %% Notes and examples -\newcommand{\noteintro}[1]{[\textit{#1}:} -\newcommand{\noteoutro}[1]{\textit{\,---\,#1}\kern.5pt]} +\newcommand{\noteintro}[1]{#1} +\newcommand{\noteoutro}[1]{\,---\,#1\kern.5pt]} % \newnoteenvironment{ENVIRON}{BEGIN TEXT}{END TEXT} % Creates a note-like environment beginning with BEGIN TEXT and @@ -293,14 +293,31 @@ \newsubclausecounter{#1} \newenvironment{tail#1} {\par\small\stepcounter{#1}\noteintro{#2}} +{} +\newenvironment{#1} +{\begin{tail#1}} +{\end{tail#1}\small\par} % \small\par is for ISO/IEC 14882:2020 post-DIS compatibility +} + +\newnoteenvironment{note}{NOTE \arabic{note}}{end note} + +% \newexplenvironment{ENVIRON}{BEGIN TEXT}{END TEXT} +% Creates an example-like environment beginning with BEGIN TEXT and +% ending with END TEXT. A counter with name ENVIRON indicates the +% number of this kind of note / example that has occurred in this +% subclause. +% Use tailENVIRON to avoid inserting a \par at the end. +\newcommand{\newexplenvironment}[3]{ +\newsubclausecounter{#1} +\newenvironment{tail#1} +{\par\small\stepcounter{#1}\noteintro{#2}} {\noteoutro{#3}} \newenvironment{#1} {\begin{tail#1}} -{\end{tail#1}\small\par} % \small\par is for C++20 post-DIS compatibility +{\end{tail#1}\small\par} % \small\par is for ISO/IEC 14882:2020 post-DIS compatibility } -\newnoteenvironment{note}{Note \arabic{note}}{end note} -\newnoteenvironment{example}{Example \arabic{example}}{end example} +\newexplenvironment{example}{EXAMPLE \arabic{example}}{end EXAMPLE} \makeatletter \let\footnote\@undefined @@ -319,10 +336,10 @@ \makeatother %% Library function descriptions -\newcommand{\Fundescx}[1]{\textit{#1}} +\newcommand{\Fundescx}[1]{#1} \newcommand{\Fundesc}[1]{\Fundescx{#1}:\space} \newcommand{\recommended}{\Fundesc{Recommended practice}} -\newcommand{\required}{\Fundesc{Required behavior}} +\newcommand{\required}{\Fundesc{Required behaviour}} \newcommand{\constraints}{\Fundesc{Constraints}} \newcommand{\mandates}{\Fundesc{Mandates}} \newcommand{\expects}{\Fundesc{Preconditions}} @@ -330,7 +347,7 @@ \newcommand{\ensures}{\Fundesc{Postconditions}} \newcommand{\returns}{\Fundesc{Returns}} \newcommand{\throws}{\Fundesc{Throws}} -\newcommand{\default}{\Fundesc{Default behavior}} +\newcommand{\default}{\Fundesc{Default behaviour}} \newcommand{\complexity}{\Fundesc{Complexity}} \newcommand{\remarks}{\Fundesc{Remarks}} \newcommand{\errors}{\Fundesc{Error conditions}} @@ -408,7 +425,7 @@ %% Concepts \newcommand{\oldconceptname}[1]{Cpp17#1} -\newcommand{\oldconcept}[1]{\textit{\oldconceptname{#1}}} +\newcommand{\oldconcept}[1]{\oldconceptname{#1}} \newcommand{\defnoldconcept}[1]{\indexdefn{\idxoldconcept{#1}}\oldconcept{#1}} \newcommand{\idxoldconcept}[1]{\oldconceptname{#1}@\oldconcept{#1}} % FIXME: A "new" oldconcept (added after C++17), @@ -595,7 +612,7 @@ \newcommand{\nontermdef}[1]{{\BnfNontermshape##1\itcorr}\indexgrammar{\idxgram{##1}}\textnormal{:}} \newcommand{\terminal}[1]{{\BnfTermshape ##1}} \renewcommand{\keyword}[1]{\terminal{##1}\indextext{\idxcode{##1}}} - \renewcommand{\exposid}[1]{\terminal{\textit{##1}}} + \renewcommand{\exposid}[1]{\terminal{##1}} \renewcommand{\placeholder}[1]{\textrm{\textit{##1}}} \newcommand{\descr}[1]{\textnormal{##1}} \newcommand{\bnfindent}{\hspace*{\bnfindentfirst}} diff --git a/src/order.tex b/src/order.tex new file mode 100644 index 0000000..0d378d5 --- /dev/null +++ b/src/order.tex @@ -0,0 +1,29 @@ +%!TEX root = ts.tex + + +% \setcounter{chapter}{33} +% \rSec0[thread]{Concurrency support library} +% \setcounter{section}{5} +% \rSec1[atomics]{Atomic operations} +% \setcounter{subsection}{3} +% \rSec2[atomics.order]{Order and consistency} +\rSec0[atomics.order]{Order and consistency} + +The requirements of ISO/IEC 14882:2020, 33.5.4 apply to this document in order to support asymmetric fences. + +In addition to the four conditions required to be satisfied by $S$, which are listed in ISO/IEC 14882:2020, 33.5.4, paragraph 4, this document requires the following conditions: + +%In addition to the requirements of ISO/IEC 14882:2020, 33.5.4, the +%following conditions are required to be satisfied by $S$: +%In addition to the items in the bulleted list, this document has the following requirements: +\begin{quote} +%%\setcounter{Paras}{3} +% \pnum +\begin{itemize} +\item +if a \tcode{memory_order::seq_cst} lightweight-fence $X$ happens before $A$ and $B$ happens +before a \tcode{memory_order::seq_cst} heavyweight-fence $Y$, then $X$ precedes $Y$ in $S$; and +\item if a \tcode{memory_order::seq_cst} heavyweight-fence $X$ happens before $A$ and $B$ happens +before a \tcode{memory_order::seq_cst} lightweight-fence $Y$, then $X$ precedes $Y$ in $S$. +\end{itemize} +\end{quote} diff --git a/src/srHP.tex b/src/srHP.tex index ae593ae..d965a17 100644 --- a/src/srHP.tex +++ b/src/srHP.tex @@ -4,58 +4,61 @@ \rSec2[saferecl.hp.general]{General} -\pnum +%%\pnum 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\textemdash that may delete such an object\textemdash that the object is not yet safe to delete. -\pnum +%\pnum A class type \tcode{T} is \defn{hazard-protectable} if it has exactly one public base class of type \tcode{hazard_pointer_obj_base} for some \tcode{D} and no base classes of type \tcode{hazard_pointer_obj_base} for any other combination \tcode{T’}, \tcode{D’}. An object is \defn{hazard-protectable} if it is of hazard-protectable type. -\pnum -The span between creation and destruction of a hazard pointer $h$ is partitioned into a series of \defn{protection epochs}; in each protection epoch, $h$ either is \defn{associated with} a hazard-protectable object, or is \defn{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. +%\pnum +The span between creation and destruction of a hazard pointer h is partitioned into a series of \defn{protection epochs}; in each protection epoch, h either is \defn{associated with} a hazard-protectable object, or is \defn{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. -\pnum +%\pnum A hazard pointer \defn{belongs to} exactly one \defn{domain}. -\pnum -An object of type \tcode{hazard_pointer} is either empty or \defn{owns} a hazard pointer. Each hazard pointer is owned by exactly one object of type \tcode{hazard_pointer}. \begin{note} An empty \tcode{hazard_pointer} object is different from a \tcode{hazard_pointer} object that owns an unassociated hazard pointer. An empty \tcode{hazard_pointer} object does not own any hazard pointers. \end{note} +%\pnum +An object of type \tcode{hazard_pointer} is either empty or \defn{owns} a hazard pointer. Each hazard pointer is owned by exactly one object of type \tcode{hazard_pointer}. \begin{note} An empty \tcode{hazard_pointer} object is different from a \tcode{hazard_pointer} object that owns an unassociated hazard pointer. An empty \tcode{hazard_pointer} object does not own any hazard pointers.\end{note} -\pnum +%\pnum An object \tcode{x} of hazard-protectable type \tcode{T} is \defn{retired} to a domain with a deleter of type \tcode{D} when the member function \tcode{hazard_pointer_obj_base::retire} is invoked on \tcode{x}. Any given object \tcode{x} shall be retired at most once. -\pnum +%\pnum A retired object \tcode{x} is \defn{reclaimed} by invoking its deleter with a pointer to \tcode{x}. -\pnum -A hazard-protectable object \tcode{x} is \defn{definitely reclaimable} in a domain $dom$ with respect to -an evaluation $A$ if: - -\begin{itemize} +%\pnum +A hazard-protectable object \tcode{x} is \defn{definitely reclaimable} in a domain dom with respect to +an evaluation A if: +\setenumerate[0]{label=(\alph*)} +\begin{enumerate} \item \tcode{x} is not reclaimed, and -\item \tcode{x} is retired to $dom$ in an evaluation that happens before $A$, and -\item for all hazard pointers $h$ that belong to $dom$, the end of any protection epoch where $h$ is associated with \tcode{x} happens before $A$. -\end{itemize} - -\pnum -A hazard-protectable object \tcode{x} is \defn{possibly reclaimable} in domain $dom$ with respect to an -evaluation $A$ if: -\begin{itemize} +\item \tcode{x} is retired to dom in an evaluation that happens before A, and +\item for all hazard pointers h that belong to dom, the end of any protection epoch where h is associated with \tcode{x} happens before A. +\end{enumerate} + +%\pnum +A hazard-protectable object \tcode{x} is \defn{possibly reclaimable} in domain dom with respect to an +evaluation A if: +\setenumerate[0]{label=(\alph*)} +\begin{enumerate} +\setcounter{enumi}{3} \item \tcode{x} is not reclaimed; and -\item \tcode{x} is retired to $dom$ in an evaluation $R$ and $A$ does not happen before $R$; and -\item 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 \tcode{x}; and -\item for all hazard pointers $h$ belonging to $dom$ and for every protection epoch $E$ of $h$ -during which $h$ is associated with \tcode{x}: -\begin{itemize} - \item $A$ does not happen before the end of $E$, and - \item if the beginning of $E$ happens before \tcode{x} is retired, the end of $E$ strongly -happens before $A$, and - \item if $E$ began by an evaluation of \tcode{try_protect} with argument \tcode{src}, label its -atomic load operation $L$. If there exists an atomic modification $B$ on \tcode{src} such that $L$ observes a modification that is modification-ordered before $B$, and $B$ happens before \tcode{x} is retired, the end of $E$ strongly happens before $A$. \begin{note} In typical use, a store to \tcode{src} sequenced before retiring \tcode{x} will be such an atomic operation $B$. \end{note} -\end{itemize} -\begin{note} The latter two conditions convey the informal notion that a protection epoch that began before retiring \tcode{x}, as implied either by the happens-before relation or the coherence order of some source, delays the reclamation of \tcode{x}. \end{note} -\end{itemize} - -\begin{example} The following example shows how hazard pointers allow updates to be carried out in the presence of concurrent readers. The object of type \tcode{hazard_pointer} in \tcode{print_name} protects the object \tcode{*ptr} from being reclaimed by \tcode{ptr->retire} until the end of the protection epoch. +\item \tcode{x} is retired to dom in an evaluation R and A does not happen before R; and +\item 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 \tcode{x}; and +\item for all hazard pointers h belonging to dom and for every protection epoch E of h +during which h is associated with \tcode{x}: +\setenumerate[0]{label=(\arabic*)} +\begin{enumerate} + \item A does not happen before the end of E, and + \item if the beginning of E happens before \tcode{x} is retired, the end of E strongly +happens before A, and + \item if E began by an evaluation of \tcode{try_protect} with argument \tcode{src}, label its +atomic load operation L. If there exists an atomic modification B on \tcode{src} such that L observes a modification that is modification-ordered before B, and B happens before \tcode{x} is retired, the end of E strongly happens before A. \begin{note} In typical use, a store to \tcode{src} sequenced before retiring \tcode{x} will be such an atomic operation B.\end{note} +\end{enumerate} +\begin{note} Condition d(2) and d(3) convey the informal notion that a protection epoch that began before retiring \tcode{x}, as implied either by the happens-before relation or the coherence order of some source, delays the reclamation of \tcode{x}.\end{note} +\end{enumerate} + +EXAMPLE The following example shows how hazard pointers allow updates to be carried out in the presence of concurrent readers. The object of type \tcode{hazard_pointer} in \tcode{print_name} protects the object \tcode{*ptr} from being reclaimed by \tcode{ptr->retire} until the end of the protection epoch. \begin{codeblock} struct Name : public hazard_pointer_obj_base { /* details */ }; @@ -74,9 +77,8 @@ ptr->retire(); } \end{codeblock} -\end{example} -\rSec2[saferecl.hp.syn]{Header \tcode{} synopsis} +\rSec2[saferecl.hp.syn]{Header \tcode{} synopsis} \begin{codeblock} namespace std::experimental::inline concurrency_v2 { @@ -109,15 +111,17 @@ \rSec3[saferecl.hp.domain.general]{General} -\pnum +%\pnum The number of unreclaimed possibly-reclaimable objects retired to a domain is bounded. -The bound is implementation-defined. \begin{note} The bound can be independent of other +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. \end{note} +threads that use hazard pointers belonging to the domain. -\pnum -Concurrent access to a domain does not incur a data race (\CppXref{6.9.2.1}). +%\pnum +Concurrent access to a domain does not incur a data race. %(\CppXref{6.9.2.1}). \begin{codeblock} class hazard_pointer_domain { @@ -140,19 +144,19 @@ \begin{itemdescr} -\pnum +%\pnum \effects Equivalent to \tcode{hazard_pointer_domain(\{\})}. \end{itemdescr} \begin{itemdecl} -explicit hazard_pointer_domain(pmr::polymorphic_allocator poly_alloc) noexcept;} +explicit hazard_pointer_domain(pmr::polymorphic_allocator poly_alloc) noexcept; \end{itemdecl} \begin{itemdescr} -\pnum +%\pnum \remarks All allocation and deallocation related to hazard pointers belonging to this domain use a copy of \tcode{poly_alloc}. @@ -165,11 +169,11 @@ \begin{itemdescr} -\pnum +%\pnum \expects All hazard pointers belonging to \tcode{*this} have been destroyed. -\pnum +%\pnum \effects Reclaims all objects retired to this domain that have not yet been reclaimed. @@ -183,11 +187,11 @@ \begin{itemdescr} -\pnum +%\pnum \returns A reference to the default \tcode{hazard_pointer_domain}. -\pnum +%\pnum \remarks The default domain has an unspecified allocator and has static storage duration. The initialization of the default domain strongly happens before this function @@ -204,15 +208,15 @@ \begin{itemdescr} -\pnum +%\pnum \effects May reclaim possibly-reclaimable objects retired to \tcode{domain}. -\pnum +%\pnum \ensures All definitely-reclaimable objects retired to \tcode{domain} have been reclaimed. -\pnum +%\pnum \sync The completion of the deleter for each reclaimed object synchronizes with the return from this function call. @@ -235,17 +239,17 @@ }; \end{codeblock} -\pnum -A client-supplied template argument \tcode{D} shall be a function object type (\CppXref{20.14}) +%\pnum +A client-supplied template argument \tcode{D} shall be a function object type %(\CppXref{20.14}) for which, given a value \tcode{d} of type \tcode{D} and a value \tcode{ptr} of type \tcode{T*}, the expression \tcode{d(ptr)} is valid and has the effect of disposing of the pointer as appropriate for that deleter. -\pnum -The behavior of a program that adds specializations for \tcode{hazard_pointer_obj_base} is undefined. +%\pnum +The behaviour of a program that adds specializations for \tcode{hazard_pointer_obj_base} is undefined. -\pnum +%\pnum \tcode{D} shall meet the requirements for \oldconcept{DefaultConstructible} and \oldconcept{MoveAssignable}. -\pnum +%\pnum \tcode{T} may be an incomplete type. \begin{itemdecl} @@ -254,21 +258,21 @@ \begin{itemdescr} -\pnum +%\pnum \mandates \tcode{T} is a hazard-protectable type. -\pnum +%\pnum \expects \tcode{*this} is a base class subobject of an object \tcode{x} of type \tcode{T}. \tcode{x} is not retired. -Move-assigning \tcode{D} from \tcode{d} does not throw an exception. The expression \tcode{d(addressof(x))} has well-defined behavior and does not throw an exception. +Move-assigning \tcode{D} from \tcode{d} does not throw an exception. The expression \tcode{d(addressof(x))} has well-defined behaviour and does not throw an exception. -\pnum +%\pnum \effects Move-assigns \tcode{d} to \exposid{deleter}, thereby setting it as the deleter of \tcode{x}, then retires \tcode{x} to \tcode{domain}. -\pnum +%\pnum Invoking the retire function may reclaim possibly-reclaimable objects retired to \tcode{domain}. \end{itemdescr} @@ -279,7 +283,7 @@ \begin{itemdescr} -\pnum +%\pnum \effects Equivalent to \tcode{retire(D(), domain)}. @@ -314,7 +318,7 @@ \begin{itemdescr} -\pnum +%\pnum \ensures \tcode{*this} is empty. @@ -326,7 +330,7 @@ \begin{itemdescr} -\pnum +%\pnum \ensures If \tcode{other} is empty, \tcode{*this} is empty. Otherwise, \tcode{*this} owns the hazard pointer originally owned by \tcode{other}; \tcode{other} is empty. @@ -340,7 +344,7 @@ \begin{itemdescr} -\pnum +%\pnum \effects If \tcode{*this} is not empty, destroys the hazard pointer owned by \tcode{*this}, thereby ending its current protection epoch. @@ -354,17 +358,17 @@ \begin{itemdescr} -\pnum +%\pnum \effects If \tcode{this == \&other} is true, no effect. Otherwise, if \tcode{*this} is not empty, destroys the hazard pointer owned by \tcode{*this}, thereby ending its current protection epoch. -\pnum +%\pnum \ensures If \tcode{other} was empty, \tcode{*this} is empty. Otherwise, \tcode{*this} owns the hazard pointer originally owned by other. If \tcode{this != \&other} is true, \tcode{other} is empty. -\pnum +%\pnum \returns \tcode{*this}. @@ -378,7 +382,7 @@ \begin{itemdescr} -\pnum +%\pnum \returns \tcode{true} if and only if \tcode{*this} is empty. @@ -391,7 +395,7 @@ \begin{itemdescr} -\pnum +%\pnum \effects Equivalent to \begin{codeblock} @@ -408,28 +412,30 @@ \begin{itemdescr} -\pnum +%\pnum \mandates \tcode{T} is a hazard-protectable type. -\pnum +%\pnum \expects \tcode{*this} is not empty. -\pnum +%\pnum \effects -\begin{itemize} +\begin{enumerate} \item Initializes a variable \tcode{old} of type \tcode{T*} with the value of \tcode{ptr}. \item Evaluates the function call \tcode{reset_protection(old)}. \item Assigns the value of \tcode{src.load(std::memory_order_acquire)} to \tcode{ptr}. \item If \tcode{old == ptr} is false, evaluates the function call \tcode{reset_protection()}. -\end{itemize} +\end{enumerate} -\pnum +%\pnum \returns -\tcode{old == ptr}. \begin{note} It is possible for \tcode{try_protect} to return \tcode{true} when \tcode{ptr} is a null pointer. \end{note} +\tcode{old == ptr}. -\pnum +NOTE 1 It is possible for \tcode{try_protect} to return \tcode{true} when \tcode{ptr} is a null pointer. + +%\pnum \complexity Constant. @@ -441,15 +447,15 @@ \begin{itemdescr} -\pnum +%\pnum \mandates \tcode{T} is a hazard-protectable type. -\pnum +%\pnum \defn{Preconditions}: \tcode{*this} is not empty. -\pnum +%\pnum \effects If \tcode{ptr} is a null pointer value, invokes \tcode{reset_protection()}. Otherwise, associates the hazard pointer owned by \tcode{*this} with \tcode{*ptr}, thereby ending the current protection epoch. @@ -461,11 +467,11 @@ \begin{itemdescr} -\pnum +%\pnum \expects \tcode{*this} is not empty. -\pnum +%\pnum \ensures The hazard pointer owned by \tcode{*this} is unassociated. @@ -477,11 +483,13 @@ \begin{itemdescr} -\pnum +%\pnum \effects -Swaps the hazard pointer ownership of this object with that of other. \begin{note} The owned hazard pointers, if any, remain unchanged during the swap and continue to be associated with the respective objects that they were protecting before the swap, if any. No protection epochs are ended or initiated. \end{note} +Swaps the hazard pointer ownership of this object with that of other. + +NOTE 2 The owned hazard pointers, if any, remain unchanged during the swap and continue to be associated with the respective objects that they were protecting before the swap, if any. No protection epochs are ended or initiated. -\pnum +%\pnum \complexity Constant. @@ -496,15 +504,15 @@ \begin{itemdescr} -\pnum +%\pnum \effects Constructs a hazard pointer belonging to \tcode{domain}. -\pnum +%\pnum \returns A \tcode{hazard_pointer} object that owns the newly-constructed hazard pointer. -\pnum +%\pnum \throws Any exception thrown by the allocator of \tcode{domain}. @@ -518,7 +526,7 @@ \begin{itemdescr} -\pnum +%\pnum \effects Equivalent to \tcode{a.swap(b)}. diff --git a/src/srrcu.tex b/src/srrcu.tex index 165d58b..fe0fa69 100644 --- a/src/srrcu.tex +++ b/src/srrcu.tex @@ -4,55 +4,56 @@ \rSec2[saferecl.rcu.general]{General} -\pnum +% \pnum RCU is a synchronization mechanism that can be used for linked data structures that are frequently read, but seldom updated. RCU does not provide mutual exclusion, but instead allows the user to schedule specified actions such as deletion at some later time. -\pnum +% \pnum A class type \tcode{T} is \defn{rcu-protectable} if it has exactly one public base class of type \tcode{rcu_obj_base} for some \tcode{D} and no base classes of type \tcode{rcu_obj_base} for any other combination \tcode{X}, \tcode{Y}. An object is rcu-protectable if it is of rcu-protectable type. -\pnum -An invocation of \tcode{unlock} $U$ on an \tcode{rcu_domain dom} corresponds -to an invocation of \tcode{lock} $L$ on \tcode{dom} if $L$ is -sequenced before $U$ and either +% \pnum +An invocation of \tcode{unlock} U on an \tcode{rcu_domain dom} corresponds +to an invocation of \tcode{lock} L on \tcode{dom} if L is +sequenced before U and either \begin{itemize} \item no other invocation of \tcode{lock} on \tcode{dom} is sequenced - after $L$ and before $U$ or -\item every invocation of \tcode{unlock} $U'$ on \tcode{dom} such - that $L$ is sequenced before $U'$ and $U'$ - is sequenced before $U$ corresponds to an invocation of - \tcode{lock} $L'$ on \tcode{dom} such that $L$ is sequenced - before $L'$ and $L'$ is sequenced before $U'$. + after L and before U or +\item every invocation of \tcode{unlock} U' on \tcode{dom} such + that L is sequenced before U' and U' + is sequenced before U corresponds to an invocation of + \tcode{lock} L' on \tcode{dom} such that L is sequenced + before L' and L' is sequenced before U'. \end{itemize} -\begin{note} -This pairs nested locks and unlocks on a given domain in each thread. -\end{note} -\pnum +NOTE +This associates corresponding locks and unlocks within a nested set +on a given domain in each thread. + +% \pnum A \defn{region of RCU protection} on a domain \tcode{dom} starts -with a \tcode{lock} $L$ on \tcode{dom} and ends with its corresponding -\tcode{unlock} $U$. +with a \tcode{lock} L on \tcode{dom} and ends with its corresponding +\tcode{unlock} U. -\pnum -Given a region of RCU protection $R$ on a domain \tcode{dom} -and given an evaluation $E$ that scheduled another evaluation -$F$ in \tcode{dom}, if $E$ does not strongly happen before -the start of $R$, the end of $R$ strongly happens before -evaluating $F$. +% \pnum +Given a region of RCU protection R on a domain \tcode{dom} +and given an evaluation E that scheduled another evaluation +F in \tcode{dom}, if E does not strongly happen before +the start of R, the end of R strongly happens before +evaluating F. -\pnum +% \pnum The evaluation of a scheduled evaluation is potentially concurrent with any other such evaluation. Each scheduled evaluation is evaluated at most once. -\rSec2[saferecl.rcu.syn]{Header \tcode{} synopsis} +\rSec2[saferecl.rcu.syn]{Header \tcode{} synopsis} % \indexheader{rcu} \begin{codeblock} @@ -101,26 +102,26 @@ }; \end{codeblock} -\pnum +% \pnum A client-supplied template argument \tcode{D} shall be a -function object type \CppXref{20.14} for which, +function object type \CppXrefInAccord{20.14} for which, given a value \tcode{d} of type \tcode{D} and a value \tcode{ptr} of type \tcode{T*}, the expression \tcode{d(ptr)} is valid and has the effect of disposing of the pointer as appropriate for that deleter. -\pnum -The behavior of a program that adds specializations for +% \pnum +The behaviour of a program that adds specializations for \tcode{rcu_obj_base} is undefined. -\pnum +% \pnum \tcode{D} shall meet the requirements for \oldconcept{DefaultConstructible} and \oldconcept{MoveAssignable}. -\pnum +% \pnum \tcode{T} may be an incomplete type. -\pnum +% \pnum If \tcode{D} is trivially copyable, all specializations of \tcode{rcu_obj_base} are trivially copyable. @@ -130,47 +131,43 @@ \begin{itemdescr} -\pnum +% \pnum \mandates \tcode{T} is an rcu-protectable type. -\pnum +% \pnum \expects \tcode{*this} is a base class subobject of an object \tcode{x} of type \tcode{T}. The member function \tcode{rcu_obj_base::retire} was not invoked on \tcode{x} before. The assignment to \exposid{deleter} does not throw an exception. The expression \tcode{\exposid{deleter}(addressof(x))} has -well-defined behavior and does not throw an exception. +well-defined behaviour and does not throw an exception. -\pnum +% \pnum \effects Evaluates \tcode{\exposid{deleter} = std::move(d)} and schedules the evaluation of the expression \tcode{de\-let\-er(ad\-dress\-of(x))} in the domain \tcode{dom}. -\pnum +% \pnum \remarks It is implementation-defined whether or not scheduled evaluations in \tcode{dom} can be invoked by the \tcode{retire} function. -\begin{note} + +NOTE If such evaluations acquire resources held across any invocation of retire on \tcode{dom}, deadlock can occur. -\end{note} \end{itemdescr} \rSec2[saferecl.rcu.domain]{Class \tcode{rcu_domain}} +\rSec3[saferecl.rcu.domain.general]{General} + % @@@ Removed the obsolete reference comments. -This class meets the requirements of \oldconcept{BasicLockable} \CppXref{32.2.5.2} and provides regions of RCU protection. - -\begin{example} -\begin{codeblock} -std::scoped_lock rlock(rcu_default_domain()); -\end{codeblock} -\end{example} +This class meets the requirements of \oldconcept{BasicLockable} \CppXrefInAccord{32.2.5.2} and provides regions of RCU protection. \begin{codeblock} class rcu_domain { @@ -186,6 +183,11 @@ The functions \tcode{lock} and \tcode{unlock} establish (possibly nested) regions of RCU protection. +EXAMPLE +\begin{codeblock} +std::scoped_lock rlock(rcu_default_domain()); +\end{codeblock} + \rSec3[saferecl.rcu.domain.lock]{\tcode{rcu_domain::lock}} \begin{itemdecl} @@ -194,14 +196,14 @@ \begin{itemdescr} -\pnum +% \pnum \effects Opens a region of RCU protection. -\pnum +% \pnum \remarks Calls to the function lock do not introduce a data race -(\CppXref{6.9.2.1}) involving \tcode{*this}. +(\CppXrefInAccord{6.9.2.1}) involving \tcode{*this}. \end{itemdescr} @@ -213,31 +215,29 @@ \begin{itemdescr} -\pnum +% \pnum \expects A call to the function \tcode{lock} that opened an unclosed region of RCU protection is sequenced before the call to \tcode{unlock}. -\pnum +% \pnum \effects Closes the unclosed region of RCU protection that was most recently opened. -\pnum +% \pnum \remarks It is implementation-defined whether or not scheduled evaluations in \tcode{*this} can be invoked by the \tcode{unlock} function. \begin{note} If such evaluations acquire resources held across any invocation -of \tcode{unlock} on \tcode{*this}, deadlock can occur. -\end{note} +of \tcode{unlock} on \tcode{*this}, deadlock can occur.\end{note} Calls to the function \tcode{unlock} do not introduce a data race involving \tcode{*this}. \begin{note} -Evaluation of scheduled evaluations can still cause a data race. -\end{note} +Evaluation of scheduled evaluations can still cause a data race.\end{note} \end{itemdescr} @@ -249,7 +249,7 @@ \begin{itemdescr} -\pnum +% \pnum \returns A reference to the default object of type \tcode{rcu_domain}. A reference to the same object is returned every time this @@ -265,14 +265,14 @@ \begin{itemdescr} -\pnum +% \pnum \effects If the call to \tcode{rcu_synchronize} does not strongly happen before the lock opening an RCU protection region \tcode{R} on \tcode{dom}, blocks until the \tcode{unlock} closing \tcode{R} happens. -\pnum +% \pnum \sync The \tcode{unlock} closing \tcode{R} strongly happens before the return from \tcode{rcu_synchronize}. @@ -287,16 +287,16 @@ \begin{itemdescr} -\pnum +% \pnum \effects May evaluate any scheduled evaluations in \tcode{dom}. For any evaluation that happens before the call -to \tcode{rcu_barrier} and that schedules an evaluation $E$ -in \tcode{dom}, blocks until $E$ has been evaluated. +to \tcode{rcu_barrier} and that schedules an evaluation E +in \tcode{dom}, blocks until E has been evaluated. -\pnum +% \pnum \sync -The evaluation of any such $E$ strongly +The evaluation of any such E strongly happens before the return from \tcode{rcu_barrier}. \end{itemdescr} @@ -310,18 +310,18 @@ \begin{itemdescr} -\pnum +% \pnum \mandates \tcode{is_move_constructible_v} is true. -\pnum +% \pnum \expects \tcode{D} meets the \oldconcept{MoveConstructible} and \oldconcept{Destructible} requirements. The expression \tcode{d1(p)}, where \tcode{d1} is defined below, is well-formed and its evaluation does not exit via an exception. -\pnum +% \pnum \effects May allocate memory. It is unspecified whether the memory allocation is performed by @@ -332,23 +332,21 @@ \tcode{dom}. \begin{note} If \tcode{rcu_retire} exits via an exception, no evaluation -is scheduled. -\end{note} +is scheduled.\end{note} -\pnum +% \pnum \throws Any exception that would be caught by a handler of type \tcode{bad_alloc}. Any exception thrown by the initialization of \tcode{d1}. -\pnum +% \pnum \remarks It is implementation-defined whether or not scheduled evaluations in dom can be invoked by the \tcode{rcu_retire} function. \begin{note} If such evaluations acquire resources held across any invocation -of \tcode{rcu_retire} on \tcode{dom}, deadlock can occur. -\end{note} +of \tcode{rcu_retire} on \tcode{dom}, deadlock can occur.\end{note} \end{itemdescr} diff --git a/src/styles.tex b/src/styles.tex index a5dd6c9..520c9a2 100644 --- a/src/styles.tex +++ b/src/styles.tex @@ -21,10 +21,10 @@ %% create page styles \makepagestyle{cpppage} -\makeevenhead{cpppage}{\copyright\,\textsc{ISO/IEC}}{}{\textbf{\docno}} -\makeoddhead{cpppage}{\copyright\,\textsc{ISO/IEC}}{}{\textbf{\docno}} -\makeevenfoot{cpppage}{\leftmark}{}{\thepage} -\makeoddfoot{cpppage}{\leftmark}{}{\thepage} +\makeevenhead{cpppage}{\textsc{ISO/IEC DTS 9922:2024(E)}}{}{\textbf{\docno}} +\makeoddhead{cpppage}{\textsc{ISO/IEC DTS 9922:2024(E)}}{}{\textbf{\docno}} +\makeevenfoot{cpppage}{}{© ISO/IEC 2024 – All rights reserved \\ \thepage}{} +\makeoddfoot{cpppage}{}{© ISO/IEC 2024 – All rights reserved \\ \thepage}{} \makeatletter \makepsmarks{cpppage}{% diff --git a/src/syncvalue.tex b/src/syncvalue.tex new file mode 100644 index 0000000..0bb5b2f --- /dev/null +++ b/src/syncvalue.tex @@ -0,0 +1,147 @@ +%!TEX root = ts.tex +% \setcounter{chapter}{7} +\rSec0[synchronizedvalue]{Synchronized Value} + +\rSec1[synchronizedvalue.general]{General} + +This clause describes a class template to provide locked access to a +value in order to facilitate the construction of race-free programs. + +\rSec1[synchronizedvalue.syn]{Header synopsis} +%%\mbox{}% +%%\hypertarget{header-experimentalsynchronized_value-synopsis}{% +%%\paragraph{Header +%%\textless experimental/synchronized\_value\textgreater{} +%%synopsis}\label{header-experimentalsynchronized_value-%%synopsis}} + +\begin{codeblock} +namespace std::experimental::inline concurrency_v2 { + template + class synchronized_value; + + template + invoke_result_t apply( + F&& f,synchronized_value&... values); +} +\end{codeblock} + +\rSec1[synchronizedvalue.class]{Class template \tcode{synchronized_value} } +%%\mbox{}% +%%\hypertarget{x.1-class-template-synchronized_value}{% +%%\paragraph{\texorpdfstring{x.1 Class template +%%\texttt{synchronized\_value}}{x.1 Class template %%synchronized\_value}}\label{x.1-class-template-%%synchronized_value}} + +\begin{codeblock} +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 @\emph{value;}@ // exposition only + mutex @\emph{mut;}@ // exposition only + }; + +template +synchronized_value(T) +-> synchronized_value; +} +\end{codeblock} + +%%\usepackage{enumitem} +% \pnum +An object of type \tcode{synchronized_value} +wraps an object of type \tcode{T}. The wrapped object can be accessed +by passing a callable object or function to \tcode{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 \tcode{synchronized_value} at +a time. + +\begin{itemdecl} + +template +synchronized_value(Args&&... args); +\end{itemdecl} + + + +%%\begin{description} +%%\item[Constraints:] +\begin{itemdescr} +%%\tightlist +%%\item[] +% \pnum +\constraints +\begin{itemize} +\item + \tcode{(sizeof...(Args) != 1)} is \tcode{true} or + \tcode{(!same_as>\ \&\&...)} + is \tcode{true} +\item + \tcode{is_constructible_v} is + \tcode{true} +\end{itemize} +%%\end{itemdescr} +% \pnum +\effects +Direct-non-list-initializes \emph{\tcode{value}} with +\tcode{std::forward(args)...}. + +% \pnum +\throws +Any exceptions emitted by the initialization of \emph{\tcode{value}}.\\ +\tcode{system_error} if any necessary resources cannot be acquired. +\end{itemdescr} + + +\rSec1[synchronizedvalue.fn]{\tcode{apply} function } +%%\mbox{}% +%%\hypertarget{x.2-apply-function}{% +%%\paragraph{\texorpdfstring{x.2 \tcode{apply} +%%function}{x.2 apply function}}\label{x.2-apply-function}} + +\begin{itemdecl} + template + invoke_result_t apply( + F&& f,synchronized_value&... values); +\end{itemdecl} + +\begin{itemdescr} + +%%\end{itemdescr} + +% \pnum +\constraints +\tcode{sizeof...(values) != 0} is \tcode{true}. + +% \pnum +\effects +Equivalent to: + +\begin{codeblock} + scoped_lock lock(values.@\emph{mut}@...); + return invoke(std::forward(f),values.@\emph{value}@...); +\end{codeblock} + +\begin{note} It is not possible to pass a single instance of \tcode{synchronized_value} +more than once to the same invocation of \tcode{apply}. + +EXAMPLE + +\begin{codeblock} + synchronized_value sv; + void f(int,int); + apply(f,sv,sv); // undefined behaviour, sv passed more than once to same call +\end{codeblock} +\end{note} + +\begin{note} The invocation of \tcode{f} cannot call \tcode{apply} +directly or indirectly passing any of \tcode{values...}.\end{note} +\end{itemdescr} + diff --git a/src/ts.tex b/src/ts.tex index 0180829..8347e00 100644 --- a/src/ts.tex +++ b/src/ts.tex @@ -28,8 +28,9 @@ \usepackage{xcolor} \usepackage[T1]{fontenc} \usepackage[pdftex, final]{graphicx} +\usepackage{pdfpages} \usepackage[pdftex, - pdftitle={C++ Concurrency Technical Specification 2}, + pdftitle={Programming Languages — Technical specification for /Cpp extensions for concurrency 2}, pdfsubject={C++ Concurrency Technical Specification 2}, pdfcreator={Michael Wong, Maged Michael, and Paul E.~McKenney}, bookmarks=true, @@ -40,12 +41,15 @@ linktocpage=true, colorlinks=true, linkcolor=blue, + urlcolor=blue, plainpages=false ]{hyperref} \usepackage{memhfixc} % fix interactions between hyperref and memoir \usepackage{xparse} \usepackage{xstring} - +\documentclass{article} +%\usepackage{fontspec} +%\setmainfont{XITS} \input{layout} \input{styles} \input{macros} @@ -60,7 +64,8 @@ \newcommand{\completionsig}{\Fundesc{Completion signature}} \newcommand{\DEDUCED}{\textit{\texttt{DEDUCED}}} \newcommand{\nativeref}{see~\ref{socket.reqmts.native}} -\newcommand{\CppXref}[1]{\texorpdfstring{C\kern-0.05em\protect\raisebox{.35ex}{\textsmaller[2]{+\kern-0.05em+}}20}{C++20} \S#1} +\newcommand{\CppXref}[1]{ISO/IEC 14882:2020, \S#1} +\newcommand{\CppXrefInAccord}[1]{in accordance with ISO/IEC 14882:2020, #1} % Alternative formatting of cross-references, resolving stable name to number. % Needs include{cxx} and CppXIV from cplusplus/draft/source/macros.tex. % \input{cxx} @@ -116,9 +121,13 @@ \include{general} %%\include{modifications} -\include{srgeneral} -\include{srHP} +\include{syncvalue} +\input{srgeneral} +\input{srHP} \include{srrcu} +\include{bytewiseatomic} +\include{asymmetric} +\include{order} % \include{classes} % \include{overloading} % \include{templates} @@ -138,4 +147,5 @@ %%-------------------------------------------------- %% End of document +\input{backcover} \end{document} diff --git a/tools/check-output.sh b/tools/check-output.sh old mode 100755 new mode 100644