1s0MEC14882:2011(E complete,even though some external actions implied by the call (such as the I/O itself)or by the volatile access may not have completed yet. thread (1.10).which induces a partial order among thoee evaluations.Given any two evaluations A and B.if A Is sequenerd before B,then the cooecutloe of A shall preeede the exoccutlom of B.If A Is not sequenced before B and B is not seroenced before A.then A and B are mmsequenced.[Nofe:The execution of unsermnencd evalations can overlap.-end note Evuluations A and B are indetermoatelg seqsenced when eitber A is sqtenced before B oe B is sequenced before A,but it is unspecified which.[Node:Indeterminately serteneed evaluatioeos ennmot owerlap,but either coukl be exeeuted first.-end note] 14 Every vlue computation and side effect with a full-expeessioe is soquenced before every mhse computation and side effect asociated with the pext full-expreesion to be evaluated.. expressioess are ueruenend.[Node:In an exprossion that is muluated moee thn once during the execution of a program,unsequenced and indeterminately sequenced evaluations of its subexpressions need not be performed comsistently in different evlnations.-end note]The wle commputations of the operands of an operator are sequenced before the value computation of the result of the operntor.If a side cffoct om a scalar object is unseremced relative to either amotherside effeet on the same sealar objeet or a walne computatiom nsing the vlue of the same scalar object.the behavior is undefined. Erawuple: vedd f(int.int): e1dg(1t1.1ut+》《 1=¥1++]: /∥the belatioe i undefined 1=7,1钟。1钟 1"1+4+1 /∥he tehauior年undefined 11+1 /∥e nslue可1 is incremented f(s =-1,=-1):/the belatioe is undefined 一作dC红mp Whem calling a funetion (whether or not the funetion is inline).nery vlue computation and sde effect associated with ang argument expresesion.or with the poestfix expression designnting the called function,is sequenced before exccution of every expresesion or statement in the body of the called function.Note:Value computatloess and side effeets assoeiated with different argumet expresions are unsoquenced.-end note] Every evalusstion in the calling function (including other function calls)that is not otherwise specifically sequenced before or after the eopecution of the body of the called function is indeterminately sequenced with respeet to the eecution of the called functiom.Several comtexts in C++cause evaluation of a function call, even though no corresponding function call syntax appears in the translation unit.Erample:Evaluation of a nev expeessiom invobes one or more alloeation and constructor funetions:see 5.3.4.For another example. imvocation of a conversion function (12.32)can arise in coetexts in which no function call syutax appears. -end crample]The sermencing constraints on the execution of the called fimction (as described above) are features of the furction calls as evaluated.whatever the syntax of the expression that call the function might be. a)As specifiod in 12.2,after a fall-expeession is evelated,a sexaence of gero ot more invocations of destrectoe funetions foe temporary objects takrs plarr,uraally in rerere order of the coatructicn of each terapoeary obyect. 9In other woeds.fanction esecutions do not lnterleave wih each ocher. s1.9 SOEC 2011 -Al rights sserved 11
complete, even though some external actions implied by the call (such as the I/O itself) or by the volatile access may not have completed yet. 13 Sequenced before is an asymmetric, transitive, pair-wise relation between evaluations executed by a single thread (1.10), which induces a partial order among those evaluations. Given any two evaluations A and B, if A is sequenced before B, then the execution of A shall precede the execution of B. If A is not sequenced before B and B is not sequenced before A, then A and B are unsequenced. [ Note: The execution of unsequenced evaluations can overlap. — end note ] Evaluations A and B are indeterminately sequenced when either A is sequenced before B or B is sequenced before A, but it is unspecified which. [ Note: Indeterminately sequenced evaluations cannot overlap, but either could be executed first. — end note ] 14 Every value computation and side effect associated with a full-expression is sequenced before every value computation and side effect associated with the next full-expression to be evaluated.8 . 15 Except where noted, evaluations of operands of individual operators and of subexpressions of individual expressions are unsequenced. [ Note: In an expression that is evaluated more than once during the execution of a program, unsequenced and indeterminately sequenced evaluations of its subexpressions need not be performed consistently in different evaluations. — end note ] The value computations of the operands of an operator are sequenced before the value computation of the result of the operator. If a side effect on a scalar object is unsequenced relative to either anotherside effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined. [Example: void f(int, int); void g(int i, int* v) { i = v[i++]; // the behavior is undefined i = 7, i++, i++; // i becomes 9 i = i++ + 1; // the behavior is undefined i = i + 1; // the value of i is incremented f(i = -1, i = -1); // the behavior is undefined } — end example ] When calling a function (whether or not the function is inline), every value computation and side effect associated with any argument expression, or with the postfix expression designating the called function, is sequenced before execution of every expression or statement in the body of the called function. [ Note: Value computations and side effects associated with different argument expressions are unsequenced. — end note ] Every evaluation in the calling function (including other function calls) that is not otherwise specifically sequenced before or after the execution of the body of the called function is indeterminately sequenced with respect to the execution of the called function.9 Several contexts in C++ cause evaluation of a function call, even though no corresponding function call syntax appears in the translation unit. [Example: Evaluation of a new expression invokes one or more allocation and constructor functions; see 5.3.4. For another example, invocation of a conversion function (12.3.2) can arise in contexts in which no function call syntax appears. — end example ] The sequencing constraints on the execution of the called function (as described above) are features of the function calls as evaluated, whatever the syntax of the expression that calls the function might be. 8) As specified in 12.2, after a full-expression is evaluated, a sequence of zero or more invocations of destructor functions for temporary objects takes place, usually in reverse order of the construction of each temporary object. 9) In other words, function executions do not interleave with each other. § 1.9 ISO/IEC 14882:2011(E) © ISO/IEC 2011 – All rights reserved 11
1S0/1EC14882:2011(目) 1.10 Multi-threaded executions and data races intro.multithread 1 A thread of erecation (also known as a thread)is a single fow of control within a program,including the initial imvocation of a specifie top-level fimnction,and recursively including every fumnction invocation subsequently executed by the thrvad.Node:When one thread creates another.the initial eall to the top-level funetion of the new thread is executed by the new thread,not by the creating thread.-end mote Every thread in a program can potentially aceess every objeet and function in a program Under a bsted implementatlo,a C4+program can have more than one thread ruming coneurrently.The execution of each thread prooeeds as defined by the remainder of this standard.The eecution of the entire program consists of an eecution of all of its threads.Node:Usually the exorcution can be viewed as an interleaving of all its thrvads.Howewr, some kinds of atomic operations.for excample.allw executions inconsistent with a simple interleaving.as described bekw.-end note)Under a freestanding implementation,it is implementation-defined whether a peogram ean have more than one thread of exocution. 2 Implementations should ensure that all unblocked threads eventually make progress.[Note:Standard libeary functions may silently block on I/O or locks.Factors in the eoeution enviroment,including externally-impooed thread priorities,may prevent an implementation from making certain guarantees of foruard progre8一end note The vale of an objeet visible to a thrend T at a particular point is the initial value of the object,a vale axsigned to the objeet by T.or a wmhse assiigned to the objeet by another thread,according to the rules belw.Note:In some cases,there may instead be undefined behavior.Much of this section is motivnted by the desire to support atomic operations with explicit and detailed vissbility comstraints.However,it also implicitly supports a simpler view for more restricted programs -end note] 4 Two expression evaluations conffict if one of them modifies a memory location (1.7)and the other one acs or modiSes the sme memory lcation. The libeary defines a number of atomic operations (Clause 29)and operations on mutexes (Clause 30) that are specially identifled as synchronization operations.These operations play a special role in making aeignments in one thrend visible to another.A synchronization operation on one or more memory locations is cither a consume operation,an acquire operation,a release operntion,or both an acquire and release operation.A synchromiztion operation without an asocisted memmory loeation is a femee and can be either an aoquire fence,a release fepce,or both an acquire and releaee fenoe.In addition,there are relaooed atomic operations,which are Bot synchroeizatson operations,and atomie read-modify-write operations,which have special characteristics.Note:For example,a call that acires a mtex will perform an aouire operation on the locations comprising the mutex.Correspondingly,a call that releases the same mutex will perform a release operation on thoee same locntions.Informally,performing a releame operation on A forces prior side effects on otber memnory loeations to become visible to other threads that later perfoem a consume or an acquire operation on A."Relaoed"atomic operations are pot synchronization operations even thomgh.like synchronlzation operntions,they cannot contribute to data races.-end mote order of Mf.If A and B are modificntions of an atomic object M and A happens before (ass defined below)B. then A shall precede B in the modifieatiom order of Mf,which is defined bekom.Nofe:This states that the modification orders must respect the "happens before"relatioeeship.-end node Nofe:There is a separate order for cach atomle object.There i no roquiremeut that these can be combined into a single total ordeg for all objects.In gemeral this will be impossible since different threads may obeerve modifications to different objects in inconsis城ent orders.一8dote 10)An object with wtomatie ce theend storage diration [3.7)is associated with one specife thread,and can be accessed ly 51.10 12 。50EC2011=Ad广s reserved
1.10 Multi-threaded executions and data races [intro.multithread] 1 A thread of execution (also known as a thread) is a single flow of control within a program, including the initial invocation of a specific top-level function, and recursively including every function invocation subsequently executed by the thread. [ Note: When one thread creates another, the initial call to the top-level function of the new thread is executed by the new thread, not by the creating thread. — end note ] Every thread in a program can potentially access every object and function in a program.10 Under a hosted implementation, a C++ program can have more than one thread running concurrently. The execution of each thread proceeds as defined by the remainder of this standard. The execution of the entire program consists of an execution of all of its threads. [ Note: Usually the execution can be viewed as an interleaving of all its threads. However, some kinds of atomic operations, for example, allow executions inconsistent with a simple interleaving, as described below. — end note ] Under a freestanding implementation, it is implementation-defined whether a program can have more than one thread of execution. 2 Implementations should ensure that all unblocked threads eventually make progress. [ Note: Standard library functions may silently block on I/O or locks. Factors in the execution environment, including externally-imposed thread priorities, may prevent an implementation from making certain guarantees of forward progress. — end note ] 3 The value of an object visible to a thread T at a particular point is the initial value of the object, a value assigned to the object by T, or a value assigned to the object by another thread, according to the rules below. [ Note: In some cases, there may instead be undefined behavior. Much of this section is motivated by the desire to support atomic operations with explicit and detailed visibility constraints. However, it also implicitly supports a simpler view for more restricted programs. — end note ] 4 Two expression evaluations conflict if one of them modifies a memory location (1.7) and the other one accesses or modifies the same memory location. 5 The library defines a number of atomic operations (Clause 29) and operations on mutexes (Clause 30) that are specially identified as synchronization operations. These operations play a special role in making assignments in one thread visible to another. A synchronization operation on one or more memory locations is either a consume operation, an acquire operation, a release operation, or both an acquire and release operation. A synchronization operation without an associated memory location is a fence and can be either an acquire fence, a release fence, or both an acquire and release fence. In addition, there are relaxed atomic operations, which are not synchronization operations, and atomic read-modify-write operations, which have special characteristics. [ Note: For example, a call that acquires a mutex will perform an acquire operation on the locations comprising the mutex. Correspondingly, a call that releases the same mutex will perform a release operation on those same locations. Informally, performing a release operation on A forces prior side effects on other memory locations to become visible to other threads that later perform a consume or an acquire operation on A. “Relaxed” atomic operations are not synchronization operations even though, like synchronization operations, they cannot contribute to data races. — end note ] 6 All modifications to a particular atomic object M occur in some particular total order, called the modification order of M. If A and B are modifications of an atomic object M and A happens before (as defined below) B, then A shall precede B in the modification order of M, which is defined below. [ Note: This states that the modification orders must respect the “happens before” relationship. — end note ] [ Note: There is a separate order for each atomic object. There is no requirement that these can be combined into a single total order for all objects. In general this will be impossible since different threads may observe modifications to different objects in inconsistent orders. — end note ] 10) An object with automatic or thread storage duration (3.7) is associated with one specific thread, and can be accessed by a different thread only indirectly through a pointer or reference (3.9.2). § 1.10 ISO/IEC 14882:2011(E) 12 © ISO/IEC 2011 – All rights reserved
Is0MEC14882:2011(E目 7 A relesse sequence headed by a release operation A on an atomic object If is a maximal comtignous sub. sequence of side eteets in the moditicatson order of Af,where the frst operation i A,and every subsequent operation -is performed by the same thrend that performed A.or -is an atomie real-modify-write operation. 8 Certain libnary calls smehronize witk other libeary call performed by another thread.For excample,an atoenic store-relense synchromizes with a lood-acquire that takes its value from the store (29.3).Note: Exopt in the specified caoes,reading a later valne dors not necsarily ensure visibility as described below. Such a roquirement would sometimes interfere with efficient implementation.-end note][Note:The speciteatioes of the synehroeizatice operatioes detine when ome readk the value written by another.For atomnic objects,the definition is ckar.All operations on a given mutex occur in a single total order.Each mutex acquisition "reads the vale written"by the last mute release.-end node] 0 An evaluation A carries a dependency to an evalustion B if -the vlue of A is used as an operand of B,unless: -B is an invocation of any specialization of std:ki11_dependency (29.3).or -A is the left operand of a bullt-in logical AND (soe 5.14)or logical OR (11,soe 5.15)operator, -A is the left operand of a oonditional (?:soe 5.16)operator,or -A is the left operand of the built-in comma (,operator(5.18): -A writes a sealar object or bit-field M,B reads the wale written by A fromn Mf,and A is serpoemend before B,or -for some emhaation X,A carries a dependency to Y,and Y carries a dependeney to B. Note:"Carries a dependency to"is a subeet of "is soquenced before",and is similarly strictly intra-thread. -end nole 10 An evaluation A is dependencyordered before an evaluation B if -A performs a releaoe operation on an atomnic objeet M,and.in another thread,B performs a coesume operation o M and reads a vlue written by any side effect in the release sqce headed by A.or -for some emaluation X.A is dependency ordered before X and X carries a dependency to B. Note:The relation "is dependemcy-ordered before"is analogos to "synchronizes with",but uses release/ consame i place of relense/acquire.-end note] 11 An evaluation A inter-thrmad happerus lefore an evaluation B if 一A3 vnchronizess with B.or -A is dependency-ordered before B.or 一for some emluation X 一A synchromiass with X and X i到enced before B,r -A is sequenced before X and X inter-thread bappens before B,or -A inter-thread happens before X and X inter-thread happens before B. s1.10 DSOMEC 2011-Al rights teerved 13
7 A release sequence headed by a release operation A on an atomic object M is a maximal contiguous subsequence of side effects in the modification order of M, where the first operation is A, and every subsequent operation — is performed by the same thread that performed A, or — is an atomic read-modify-write operation. 8 Certain library calls synchronize with other library calls performed by another thread. For example, an atomic store-release synchronizes with a load-acquire that takes its value from the store (29.3). [ Note: Except in the specified cases, reading a later value does not necessarily ensure visibility as described below. Such a requirement would sometimes interfere with efficient implementation. — end note ] [ Note: The specifications of the synchronization operations define when one reads the value written by another. For atomic objects, the definition is clear. All operations on a given mutex occur in a single total order. Each mutex acquisition “reads the value written” by the last mutex release. — end note ] 9 An evaluation A carries a dependency to an evaluation B if — the value of A is used as an operand of B, unless: — B is an invocation of any specialization of std::kill_dependency (29.3), or — A is the left operand of a built-in logical AND (&&, see 5.14) or logical OR (||, see 5.15) operator, or — A is the left operand of a conditional (?:, see 5.16) operator, or — A is the left operand of the built-in comma (,) operator (5.18); or — A writes a scalar object or bit-field M, B reads the value written by A from M, and A is sequenced before B, or — for some evaluation X, A carries a dependency to X, and X carries a dependency to B. [ Note: “Carries a dependency to” is a subset of “is sequenced before”, and is similarly strictly intra-thread. — end note ] 10 An evaluation A is dependency-ordered before an evaluation B if — A performs a release operation on an atomic object M, and, in another thread, B performs a consume operation on M and reads a value written by any side effect in the release sequence headed by A, or — for some evaluation X, A is dependency-ordered before X and X carries a dependency to B. [ Note: The relation “is dependency-ordered before” is analogous to “synchronizes with”, but uses release/- consume in place of release/acquire. — end note ] 11 An evaluation A inter-thread happens before an evaluation B if — A synchronizes with B, or — A is dependency-ordered before B, or — for some evaluation X — A synchronizes with X and X is sequenced before B, or — A is sequenced before X and X inter-thread happens before B, or — A inter-thread happens before X and X inter-thread happens before B. § 1.10 ISO/IEC 14882:2011(E) © ISO/IEC 2011 – All rights reserved 13
130/1EC14882:2011(E) Note:The "inter-thrend happens before"relation describes arbitrary concatenations of"seqenced before", "synchromlzes with"and"dependency-ordered before"relationships with two exceptions.The first exception is that a comcatenation is not permitted to end with"dependeney-ordered before"followed by "serecd bedore".The reason for this lmitation is that a consume operation participating in a "depetdency-ordered bedare"relationship provids ordering omly with rspeet to operations to which this consme operation actually earries a dependeney.The reason that this limltatson applies only to the end of such a coneatenation isthat any subexqent release operation will provide the reqmired ordering for a prior commme operation. The secood exception is that a concntenation is not permitted to coesist entirely of "sequenced before" The rensons foe this limitation are (1)to permit "inter-thread happens before"to be transitively closed and (2)the"happens before"relation.defined below.prowides for relationships consisting emtirely of"seqed bedore.一end note] 12 An evaluation A happeas lefore an evaluation B if 一A is sequepced before B,ot -A inter-thread happens before B. The implementation shall esure that no program ecution demonstrates a eycle in the"happens before" relation.Note:This cycle would otherwise be poeesible only through the use of consme operations.-end note] 13 A risille side effeet A on a senlar objeet oe bit-feld Mf with respeet to a value computation B of M satisfies the cooditions: 一A happeas before B and -there is no other side effect X to M such that A happens before X and X happens before B. The value af a non-atomnie sealar object or bit-feld M,os determined by evluation B.shall be the vahe stored by the vissible side effect A.Note:If there is ambiguity about which side effect to a nom-atomic object oe bit-field is vistble,then the behmior is either unspecifiod or undefined.-end mote]Note:This states that operations on ordinary objects are not visibly reordered.This is not actually detectable without data races,but it is necmsary to ensure that data raoes,as defined below,and with saitable restrictions on the nse of atomics,correspond to data races in a simple interleaved (seqmentially comsistent)execution.-end note] 14 The ririle sence of ride effects on an atomic object M,with respect to a vale computation B of M,is a maxcimal comtiguous sub-sequence of side efects in the modification order of Jf.where the first side effect is visible with respeet to B,and for every side edfeet,it is not the case that B happems before it.The vahae of an atomic object Mf,as determined by evaluation B.shall be the vale stored by some operation in the visible sequence of Mf with respect to B.Note:It can be shown that the visible soquence of side effeets of a value computation is uniqoe given the coherence reqquirements below.-end mofe) is If an operation A that modifies an atomic object M happens before an operation B that modifies M,then A shall be earlier than B in the modifiention oeder of Mf.Note:This requirememt is knoun as write-write coherence.一end mote 16 If a value computatlon A of an atomle object M happens before a value computation B of Mf,and A tabes its rale from a side effect on M,them the vale compmuted by B shall either be the value stored by X or the value stored by a side efect Y on Jf,where Y follows X in the modificntion order of Mf.Node:This equiretnemt is kmowwn as rew小l4dto,一end nole] 7If a valne computation A of an atomic object M happens before an operation B on M.then A shall take its whe from a side effect X on Mf.where X peecodes B in the modifieation arder of Af.Note:This equiremnemt is k<wn as re小write coheremc,一end note s1.10 14 ⊙90EC2011-A1gbe0d
[ Note: The “inter-thread happens before” relation describes arbitrary concatenations of “sequenced before”, “synchronizes with” and “dependency-ordered before” relationships, with two exceptions. The first exception is that a concatenation is not permitted to end with “dependency-ordered before” followed by “sequenced before”. The reason for this limitation is that a consume operation participating in a “dependency-ordered before” relationship provides ordering only with respect to operations to which this consume operation actually carries a dependency. The reason that this limitation applies only to the end of such a concatenation is that any subsequent release operation will provide the required ordering for a prior consume operation. The second exception is that a concatenation is not permitted to consist entirely of “sequenced before”. The reasons for this limitation are (1) to permit “inter-thread happens before” to be transitively closed and (2) the “happens before” relation, defined below, provides for relationships consisting entirely of “sequenced before”. — end note ] 12 An evaluation A happens before an evaluation B if: — A is sequenced before B, or — A inter-thread happens before B. The implementation shall ensure that no program execution demonstrates a cycle in the “happens before” relation. [ Note: This cycle would otherwise be possible only through the use of consume operations. — end note ] 13 A visible side effect A on a scalar object or bit-field M with respect to a value computation B of M satisfies the conditions: — A happens before B and — there is no other side effect X to M such that A happens before X and X happens before B. The value of a non-atomic scalar object or bit-field M, as determined by evaluation B, shall be the value stored by the visible side effect A. [ Note: If there is ambiguity about which side effect to a non-atomic object or bit-field is visible, then the behavior is either unspecified or undefined. — end note ] [ Note: This states that operations on ordinary objects are not visibly reordered. This is not actually detectable without data races, but it is necessary to ensure that data races, as defined below, and with suitable restrictions on the use of atomics, correspond to data races in a simple interleaved (sequentially consistent) execution. — end note ] 14 The visible sequence of side effects on an atomic object M, with respect to a value computation B of M, is a maximal contiguous sub-sequence of side effects in the modification order of M, where the first side effect is visible with respect to B, and for every side effect, it is not the case that B happens before it. The value of an atomic object M, as determined by evaluation B, shall be the value stored by some operation in the visible sequence of M with respect to B. [ Note: It can be shown that the visible sequence of side effects of a value computation is unique given the coherence requirements below. — end note ] 15 If an operation A that modifies an atomic object M happens before an operation B that modifies M, then A shall be earlier than B in the modification order of M. [ Note: This requirement is known as write-write coherence. — end note ] 16 If a value computation A of an atomic object M happens before a value computation B of M, and A takes its value from a side effect X on M, then the value computed by B shall either be the value stored by X or the value stored by a side effect Y on M, where Y follows X in the modification order of M. [ Note: This requirement is known as read-read coherence. — end note ] 17 If a value computation A of an atomic object M happens before an operation B on M, then A shall take its value from a side effect X on M, where X precedes B in the modification order of M. [ Note: This requirement is known as read-write coherence. — end note ] § 1.10 ISO/IEC 14882:2011(E) 14 © ISO/IEC 2011 – All rights reserved
S0MEC14882:2011(日 18 If a side effoct X on an atomnic objeet M happens before a vlue computation B of M,then the emlaation B shall take its valoe from X or from a side effect Y that folloms X in the modification order of Mf.Note: This requirement is known as write-read coherence.-emd note 1 Note:The four preceding coherence roquirements elfectively disallo compilr reoedering of atomie oprra- tions to a single object,even if both operations are relaxed loads.This effectively makes the cache coberence guarantee provided by most hardwure avilable to C++atomic openations.-end note] 20 Note:The viible of side effects depends on the "happens before"relation,which depends on the wlues observed by londs of atomics,which we are restricting here.The intended reading is that there mmust exist an ascociation of atomnie loads with modilientioes they ohserve that,together with suitably chosen modification orders and the "happens before"relation derived as described above,satisfy the resulting constraints as impooed bere.-end pofe] 21 The eecution of a program contains a data ruce if it contains two comflicting actions in differett threads, at least one of which is not atomic.and neither happens before the other.Any such data race results in undefined behavice.Note:It can be shown that programs that correctly use mutexs and semory.order. seq_cst operations to prevent all data races and ue no other synchromization operations behave as if the operations executed by their comstituent threads were simply interleaved,with each valoe computation of an object being taben from the last side effect om that object in that interleaving.This is normally referred to as "seqential consistency".However,this applies omly to data-race-free programs,and data-rnce-free programs canpot observe most program transformations that do not change single-thrended program semantics.In fnet,moot single-threaded program transformations coetime to be allowed,since any peogram that behaves differently as a result mst perform an undefined operation.-cod note] [Note:Compiler transformatioess that introduce assigmments to a potentially shared memory location that would not be modilied by the abetract machine are generally preclded by this standard,since sch an asesignment might owerwrite another asesignment by a different thrend in caes in which an abestract machine exccution would not have encountered a data race.This incbudes implementations of data meaber aign- ment that overwrite adjacent members in separate memory locations.Reordering of atomic loads in cases in which the atomics in t may alias is alo generally pruclded,since this my violate the "visible equence rules.一nd note] Note:Traneformations that introduce a speculative read of a potentially shared memory location may not preserve the semanties of the C++progmm defined in this standard,sinee they potentially introduce a data mace.However.they are typlcally valid in the context of an optimizing compiler that targets a speeite machine with welldefined semantics for data raoes.They would be imvalid for a hypothetical machine that is Dot tolernnt of races or provides hardware race detection.-end note The implememtation may ase that any thread will eventually do oe of the following 一termlnate 一mt满call to a library I/O function -access or modify a volatile object,or -perform a synchronixation operation or an atomi operation. [Note:This is intended to allow compiler transformations such as removal of empty loops,even when termination cannot be proven.-cmd note] An impkmentation should ensure that the last value (in modification order)aseigned by an atomic or wynehronixation operation will become visible to all otber thrends in a finite period of time. 51.10 SOMEC 2011 -All rights teserved 15
18 If a side effect X on an atomic object M happens before a value computation B of M, then the evaluation B shall take its value from X or from a side effect Y that follows X in the modification order of M. [ Note: This requirement is known as write-read coherence. — end note ] 19 [ Note: The four preceding coherence requirements effectively disallow compiler reordering of atomic operations to a single object, even if both operations are relaxed loads. This effectively makes the cache coherence guarantee provided by most hardware available to C++ atomic operations. — end note ] 20 [ Note: The visible sequence of side effects depends on the “happens before” relation, which depends on the values observed by loads of atomics, which we are restricting here. The intended reading is that there must exist an association of atomic loads with modifications they observe that, together with suitably chosen modification orders and the “happens before” relation derived as described above, satisfy the resulting constraints as imposed here. — end note ] 21 The execution of a program contains a data race if it contains two conflicting actions in different threads, at least one of which is not atomic, and neither happens before the other. Any such data race results in undefined behavior. [ Note: It can be shown that programs that correctly use mutexes and memory_order_- seq_cst operations to prevent all data races and use no other synchronization operations behave as if the operations executed by their constituent threads were simply interleaved, with each value computation of an object being taken from the last side effect on that object in that interleaving. This is normally referred to as “sequential consistency”. However, this applies only to data-race-free programs, and data-race-free programs cannot observe most program transformations that do not change single-threaded program semantics. In fact, most single-threaded program transformations continue to be allowed, since any program that behaves differently as a result must perform an undefined operation. — end note ] 22 [ Note: Compiler transformations that introduce assignments to a potentially shared memory location that would not be modified by the abstract machine are generally precluded by this standard, since such an assignment might overwrite another assignment by a different thread in cases in which an abstract machine execution would not have encountered a data race. This includes implementations of data member assignment that overwrite adjacent members in separate memory locations. Reordering of atomic loads in cases in which the atomics in question may alias is also generally precluded, since this may violate the “visible sequence” rules. — end note ] 23 [ Note: Transformations that introduce a speculative read of a potentially shared memory location may not preserve the semantics of the C++ program as defined in this standard, since they potentially introduce a data race. However, they are typically valid in the context of an optimizing compiler that targets a specific machine with well-defined semantics for data races. They would be invalid for a hypothetical machine that is not tolerant of races or provides hardware race detection. — end note ] 24 The implementation may assume that any thread will eventually do one of the following: — terminate, — make a call to a library I/O function, — access or modify a volatile object, or — perform a synchronization operation or an atomic operation. [ Note: This is intended to allow compiler transformations such as removal of empty loops, even when termination cannot be proven. — end note ] 25 An implementation should ensure that the last value (in modification order) assigned by an atomic or synchronization operation will become visible to all other threads in a finite period of time. § 1.10 ISO/IEC 14882:2011(E) © ISO/IEC 2011 – All rights reserved 15