Marie-Paule Norini

Hugues Thouin

Lydie Le Forestier

Pascale Gautret

Mikael Motelica-Heino

Louis De Lary De Latour

Fabienne Battaglia-Brunet

Lydie Le

Norini Marie-Paule

Thouin Hugues

Le Forestier Lydie

Gautret Pascale

Motelica- Heino Mikael

De Lary De Latour Louis

Battaglia-Brunet Fabienne

Selection of amendments to decrease the mobility and toxicity of inorganic pollutants (Pb, As, Ba, Zn) in a mine tailing for the development of a phytoremediation process

à la diffusion de documents scientifiques de niveau recherche, publiés ou non, émanant des établissements d'enseignement et de recherche français ou étrangers, des laboratoires publics ou privés.

Selection of amendments to decrease the mobility and toxicity of inorganic pollutants (Pb, As, Ba, Zn) in a mine tailing for the development of a phytoremediation process 1. Introduction

In mining sites, the alteration of tailings induces a risk of dispersion of potentially toxic elements inducinga potential pollution of groundwater and surface water. The development of a vegetal cover is one of the potential options to decrease the risks through mechanical and biogeochemical stabilization of pollutants and attenuation of run-off/on and erosion. However, the growth of plants on mine tailings and associated technosols is generally hampered by several parameters: acidity, lack of nutrients, poor texture and toxicity of metals and metalloids. Thus, amendments are necessary to overcome these limitations prior to vegetalisation. A range of amendments, organic and inorganic, were proposed to improve the phytostabilisation processes [START_REF] Alkorta | Phytostabilization of Metal Contaminated Soils[END_REF]. Here, several amendments were tested for the stabilization of Pb, As, Ba and Zn in tailings from a Pb-Ag former mine. The effects of these treatments on microbial metabolic diversity and on the early growth of ryegrass were evaluated.

Materials and methods

Tailings were sampled on the former silver and lead mining site of Pontgibaud located in medium mountain, Auvergne, France [START_REF] Sabourault | Le district minier de plomb-argentifère de Pontgibaud (France) : vers une résilience des anciens dépôts de ré-sidus de traitement du minerai[END_REF]. Mine residues were recovered from the 0-60 cm depth level of a mine waste dump, in seven discrete zones in a 25 m 2 area, using a power shovel. The tailing is acidic (4<pH<5), siliceous and coarse (76% of particles with size in the range of 315 µm -2 mm). Total concentrations in pollutants were as follow: 26 432 mg.kg -1 Pb, 265 mg.kg -1 Zn, 1 063 mg.kg -1 Ba, 1134 mg.kg -1 As. Previous studies showed that, in absence of amendment, it is not a good substrate for plant growth [START_REF] Norini | Mobility of Pb, Zn, Ba, As and Cd toward soil pore water and plants (willow and ryegrass) from a mine soil amended with biochar[END_REF].

The selected amendments were cow manure and ochre (iron oxide-hydroxide) material produced in the water treatment plant of a coal mine. First of all, they were tested in the laboratory in pot experiments single or in combination, in 10% solids leaching tests, at 5% (weight of dry amendment/weight of tailing). Subsequently, microcosms experiments were performed in 200 mL polystyrene pots, whose bottom was perforated to allow water flow, filled with tailing, amended or not. The different tested conditions were the following: tailing without amendment (T), tailing + 5% ochre (TO), tailing + 5% ochre + 0.15% manure (TOM 0.15%), tailing + 5% ochre + 1% manure (TOM 1%), tailing + 5% ochre + 2% manure (TOM 2%).The microcosms were watered once a week and the percolating water was analyzed to quantify pollutants. The effects of amendments on metabolic microbial activities were evaluated using Ecolog® plates. Soils recovered in microcosm pots after 1 month of incubation were used to test the growth of ryegrass in 200 mL polystyrene pots, 50 mm diameter, whose bottom was perforated to allow water flow. Pots were incubated in a Phytotron with 60 % air water saturation, 16 h of light (white fluorescent light 500-600 µm.m ) at 25°C alternately with 8 h of darkness at 18 °C.

Results and discussion

Immobilization of metal(loid)s

Leaching experiments showed that the best combination of amendments to immobilize Pb while avoiding significant mobilization of As, Zn and Ba was a mixture of ochre and manure at 5% of each amendment. Ochre can contribute to the treatment by increasing pH and by adsorbing As and metals. Manure is necessary to supply nutrients for plant growth. The efficiency of immobilization of pollutants was confirmed during microcosm experiments: Pb concentration, that was higher than 10 mg.L -1 with the not-amended tailing, was decreased by a factor ×100, while As, Zn and Ba concentration did not increase significantly.

Effects of amendments on microbial activity and plants

The average color development (AWCD) in Ecolog® plates is an expression of the microbial activity in the sample and integrates the cell density and the diversity of substrate utilization (Figure 1). Amendments with ochre and manure increased and modified the metabolic activity. Metabolic activities per family of substrates expressed by the AWCD appeared to be higher when amendments were added to the tailing. This activity was the strongest for TOM 2%. Polymers with the highest percentage of utilization are the most used substrates, suggesting the presence of a specialized microbial community. There was a shift in the substrate utilization intensity. Ryegrass created a less favorable environment for certain microbial groups in the soil: With ryegrass, the microbial community preferred to use simpler substrates and no longer seems to be able to use complex substrates like polymers. At the end of the incubation with ryegrass, the most active microbial communities were found for TOM 1%.

Figure 1.Soil microbial activities of the microcosms after 1 month of incubation without (A) and with (B) ryegrass, and picture of the planted microcosms (C).

The germination rate of ray grass varied with the amendment: 83 % for T, 100 % for TO, 97 % for TOM 0.15%, 94 % for TOM 1%, and 78 % for TOM 2%. The growth of plants was significantly improved by the addition of ochre and manure (Figure 1C): the biomass of ryegrass is 3.5 X (TOM 2%) to 4.8 X (TOM 0.15%) times greater than for the condition of plants growing on unamended soil (data not shown).

Conclusions

The combination of ochre (5%) and manure (0.15% to 2%) is efficient to stabilize Pb in the tailing, without mobilizing other pollutants, i.e. As, Zn and Ba at the microcosm scale. Both amendments improved the microbial activity of the tailing and stimulated the development of ryegrass. The next experimental step will include the monitoring of phytostabilization and ecodynamics of contaminants at metric scale, in mesocosm, with a vegetal species naturally present on Pontgibaud mine site, belonging to the Agrostis genus.

Acknowledgement -This research work is performed in the frame of Phytoselect project funded by the Region Centre Val de Loire, contract N°2016-00108485, and by the Labex Voltaire (ANR-10-LABX-100-01). We gratefully acknowledge the financial support pro-vided to the PIVOTS project by the Région Centre -Val de Loire (ARD 2020 program and CPER 2015 -2020) and the French Ministry of Higher Education and Research (CPER 2015 -2020 and public service subsidy to BRGM). This operation is co-funded by European Union. Europe is committed to the Cen-ter-Val de Loire region with the European Regional Development Fund.


Justyna Jońca

R Lai-Cheong

Myrtil L Kahn

Katia Fajerwerg

Céline Combettes

Vincent Bley

Philippe Menini

Pierre Fau

CuO nanostructured sensors for enhanced CO detection

de niveau recherche, publiés ou non, émanant des établissements d'enseignement et de recherche français ou étrangers, des laboratoires publics ou privés.

Summary

In order to increase the selectivity of semi-conducting gas sensors CuO, ZnO nanostructures have been integrated as sensitive layers on silicon substrates. A metalorganic approach has been employed for the preparation of CuO and ZnO anisotropic nanoparticles. Their gas sensing performance towards CO, C 3 H 8 have been tested. The influence of the oxide nature is significant on the sensor response level and its selectivity to the reducing gases. Moreover, at an operating temperature T = 200°C, the sensors present an optimum performance towards CO with fast response and recovery time, unprecedented sensitivity (Rn= ca. 150%, 100 ppm CO, RH 50%) and selectivity as compared to NO 2 , C 3 H 8 and NH 3 . Thus, these results highlight the remarkable role of CuO on the fabrication of very promising CO gas sensors.

Motivation and results

Semiconductor gas sensors have been widely studied due to their important applications in environmental monitoring and medical diagnosis [START_REF] Deng | Reduced graphene oxide conjugated Cu2O nanowire mesocrystals for high-performance NO 2 gas sensor[END_REF]. They have attracted much attention in the field of gas sensing under atmospheric conditions due to their low cost and flexibility in production, simplicity of their use and large number of detectable gases/possible application fields. Semiconducting metal oxide sensors are one of the most widely used gas sensors. However, the main drawback of this type of devices is their lack of selectivity, i.e. their capability to detect a specific gas in a mixture of several gaseous components. Many strategies have been developed in order to achieve a better selectivity, i.e the use of mixed metal oxide layers and/or to dope the sensitive layer with noble metals such as Pt, Pd, …, well control the size and shape of the sensitive layer structures, catalytic filters, etc [START_REF] Shimizu | Improvement of SnO 2 sensing properties of WO 3 by noble metal loading[END_REF][START_REF] Ryzhikov | Organometallic Synthesis of ZnO Nanoparticles for Gas Sensing: Towards Selectivity Through Nanoparticles Morphology[END_REF][START_REF] Jońca | SnO 2 "Russian Doll" octahedra prepared by the metalorganic approach: a new structure for sub-ppm CO gas detection[END_REF]. While a great attention has been focused on n-type semiconducting oxides, few studies have been devoted to the p-type gas sensors. Among p-type oxide semiconductors, single phase, or CuO as part of heterojunction sensors, have demonstrated considerable potential for detection of gases such C 2 H 5 OH, NO 2 , H 2 S, H 2 , CO, NH 3 . Some of these sensors exhibited interesting selectivity properties towards investigated gases. Up to now, various approaches have been reported to fabricate the CuO nanostructures in the literature. We have developed an organometallic approach for the preparation of crystalline copper oxide nanostructures. These CuO nanostructures have been deposited on miniaturized silicon gas sensor substrates by an ink-jet method or by using a screen-printing paste. More recently combining ZnO with a p-type semi-conductor has attracted great attention due to its enhanced sensing performance [START_REF] Chen | A CuO-ZnO nanostructured p-n junction sensor for enhanced Nbutanol detection[END_REF]. Such p-n heterojunction sensor will be tested with organometallic CuO/ZnO nanostructured mixed oxides and will be compared with the parent ZnO and CuO sensors under the same conditions.

Figure 1 :

 1 Figure 1: TEM (a) and HRTEM images and diffraction rings (b) of bare CuO synthesis

Figure 2 :

 2 Figure 2: Semi-manual ink-jet method and silicon platform before sensitive layer deposition

Figure 3 :

 3 Figure 3: Normalized responses of CuO sensitive layer to 100 ppm CO, C 3 H 8 , 5 ppm NH 3 and 1 ppm NO 2 at different operating temperatures (RH 50%).

1 :

 1 Laboratoire de Chimie de Coordination (LCC), CNRS, Toulouse, France 2: Université Paul Sabatier, UT III, Toulouse, France 3 : Laboratoire Plasma et conversion d'énergie (LAPLACE) UT III, CNRS, INP, Toulouse, France 4: Laboratoire d'Analyse et d'Architecture des Systèmes (LAAS), CNRS, Toulouse, France


Jens Gustedt

v 1 Clean up atomics proposal for integration to C2x

Keywords:

Whereas its intent is clear, the text in the C standard that concerns atomics has several consistency problems. There are contradictions and the standard vocabulary is not always applied correctly. This paper attempts to solve these consistency problems, and to provide a path to a straighter and easier to use and to implement specification. Even though individually the identified flaws are simple to repair, all together they form a relatively large batch of changes (spelled out in an appendix). -This is a follow-up of N1955 that resulted from many discussions on the WG14 reflector or elsewhere. In particular, it integrates suggestions by Robert Seacord, Richard Smith, Aaron Ballman, and probably many more.

PROBLEM DESCRIPTION

C17 has still a lot of problems concerning atomic types and synchronization. In the following sections, I list all the oddities that each by itself seem simple to repair. All of this is not meant at all to be substituted for the discussions about atomics that we had on the reflector, in particular with respect to C++. The changes that would result from these discussions are orthogonal to what is proposed here.

Memory order of operators

The following sections on arithmetic operators, all specify that if they are applied to an atomic object as an operand of any arithmetic base type, the memory order sematic is memory_order_seq_cst:

-6.2.6.1 Loads and stores of objects with atomic types are done with memory_order_seq_cst semantics. -6.5.2.4 (postfix ++ and --) -6.5.16.2 Compound assignment. No constraints formulated concerning traps for integer types. In contrast to that, no floating exceptions for floating types are allowed. Also, this defines atomic operations for all arithmetic operands, including some that don't have library calls (*=, /=, %=, <<=, >>=)

No such mention is made for -6.5.3.1 (prefix ++ and --), although it explicitly states that these operators are defined to be equivalent to += 1 and -= 1, respectively. -6.5.16.1 Simple assignment, although the paragraph about store says that such a store should be memory_order_seq_cst.

Integer representations and erroneous operations

Concerning the generic library calls, they state in 7.17.7.5

For signed integer types, arithmetic is defined to use two's complement representation with silent wrap-around on overflow; there are no undefined results.

and

For address types, the result may be an undefined address, but the operations otherwise have no undefined behavior.

If there are atomics at all, atomic versions are required to exist for integer types that optional, namely [u]intptr_t.

There seems to be no reason to allow atomic integer types (such as atomic_int) to be different from the direct types (such as _Atomic(int)). C17 only claims that their representation and alignment must be the same, and the intent is that they should be exchangeable for functions calls. How that would work for border cases (for users) if the types are not exactly the same is a mystery to me.

Generic functions

The selection process for the active prototype of generic functions is not clearly specified.

In particular it is undefined (by omission) what happens if such a function is called and there is no matching prototype. This can in particular happen for atomic_compare_exchange functions that have two pointer arguments that must match to be a valid call.

Since such a situation is easily detectable at compile time, this should not be left undefined but present a constraint violation.

1.11. Facility of using acquire-release consistency on all atomic operations

The default memory order for atomic operations is sequential consistency and therefore the use of atomics with that consistency is straight forward: all arithmetic and bitwise operations are available as compound assignments, and some of them are available as direct generic function calls, without separated order argument.

Unfortunately this default consistency has some drawbacks on the user side.

-On many CPU architectures sequential consistency can be orders of magnitude more expensive than acquire-release consistency. -Other synchronization tools provided by the C library (e.g. mtx_t) only guarantee acquirerelease consistency, so when mixing atomics with mutex based locking, sequential consistency only adds costs for no gain. -Properties of parallel executions are mostly argued with acquire-release consistency because the "happend-before" relation provides a simple thread-local view of causality. The global sequential event ordering that is provided by the default model is mostly unused by programmers.

On the other hand using other consistency models is tedious: we have to use the lengthy generic function forms for operations, if they exist, or we even have to manually synthesize the other operations by mean of atomic_compare_exchange_weak.

1.12. Atomics and VM types DR 495 raised the question if there have to be provision to evaluate or not a size expression that is found as part of the operand of a _Atomic specifier. I found no indication that would suggest that this should be treated differently from the general case:

-Such a declaration can appear in exactly the same scopes as VM types that don't use the _Atomic specifier. -Unless they are themselves part of _Alignof or sizeof expressions these declarations declare a type (either for a typedef or an object) for which the array size must be known at the point of declaration.

On the other hand, I found the formulation after the patching for C17 a bit confusing, since it is not clear with which priority the rules are applied, nor is it stated clearly that for the general case such size expressions are indeed evaluated. So below I propose a patch that clarifies this situation.

N2329:4

Jens Gustedt

Atomics and function parameters

In C17, it is not clear from the text how an array parameter with _Atomic in the [] is rewritten. It says that it rewrites to the "unqualified" pointer type, but by the terminology this does not include atomics. So what happens to _Atomic, here?

1.14. Conclusion

This is

contradictory. (the Note cited above is not normative, but still wrong), confusing. (= is handled different from op=, operators are not mentioned where they should), weird. (the sign representation is described as the result of an operation, not as the value representation of a data type; what is "no undefined behavior" of a address operation?) inconsistent. (operators may result in any sign representation ?, and can trap, generic functions are safe) incomplete. (the set of operators and generic functions are distinct) obsolete. (ATOMIC_VAR_INIT) tedious.

SUGGESTED CHANGES

The suggested changes are appended as diffmarks in the corresponding pages of the latest working paper. Page numbers are only indications as they change by the simultaneous prensence of the old and new text.

Changes can be categorized in -editorial changes, -non-normative changes and -normative changes.

We will not discuss the editorial changes, here. All these changes are not intended to change behavior of existing code or even ABI or C -C++ compatibility. In the contrary, much work has been invested to keep things as they are currently.

If there are normative changes these are extensions, such as by adding better synchronization features, or extending the available user interfaces. Some effort has been made to make these user interfaces consistent and thereby to ease programming with C's atomic interface.

Non-normative changes

The changes that should not change normative aspects are summarized by the following. Headlines are those of the log-entries in the git repository:

2.1.1. streamline env concepts w.r.t atomics. Correctly discuss all clauses that are relevant for synchronization operations in the "data race" clause.

amend lang concepts for atomics

-Summarize the expected properties of implementations that support atomics.

-Summarize the general properties of atomic operations.

-Nail down what "no undefined behavior" probably means for people, that is that these operations are interrupted (in a broad sense) under no circumstances.

2.1.3. amend lang expr for atomics. Add a general text to which operations are read-modifywrite operations, to env-concepts and remove the then superfluous text from the specific operator definitions.

Clean up atomics N2329:5 2.1.4. amend <stdatomic.h> -Extend the text about atomic generic functions to pointer types, and remove the now redundant text about properties of operations. -Correct the infamous "Note" to the real differences from the operator versions and add examples that point out the differences.

2.1.5. remove atomic_int from an example. We should not encourage the use of the typedef atomic integer types anymore but use the specifier version instead.

2.1.6. avoid the singular use of the terms "process" and "communication". "Process" and "communication" are the wrong terminology. Use "execution" and "synchronization", instead.

2.1.7. there is no such thing like a "regular type". Apply the same terminology in the running text for the atomic integer types than in the table.

2.1.8. a new note about the interplay between lock-free and signal. The clause for the lock-free property was almost free of sense.

2.1.9. atomics and volatile qualification. The note explaining why most of the generic functions have volatile qualifications was crude and dubious. Stick to the facts. NB: The note with the change here is completely removed later by a normative change.

2.1.10. strength of ordering constraints. Explain what the "strength" relation between ordering constraints is.

2.1.11. recommend that atomic integer types are the same as the direct type. The whole concept of atomic integer types is a left over from very early formulations of the concept, before the introduction of the _Atomic specifier and the application to general data types. Discourage the use of them and mark them as obsolete.

2.1.12. disambiguate the rules for evaluation of size expressions. Resolve DR 495 by clarifying the rules when size expressions are evaluated or not.

2.1.13. add an example for the ambiguity between _Atomic specifier and qualifier.

Normative changes

2.2.1. add synchronization and sequencing of thrd_exit. In C17, the synchronization properties of thrd_exit are only described indirectly and with some inventive terminology. This patch -complements the synchronization requirements with respect to thrd_join, which were only described, there; -complements with a synchronization requirements towards the execution of atexit and at_quick_exit handlers; -uses the correct terminology to describe unordered execution of destructors.

complement the atomic generic functions with the other scalar operations.

There are compound assignment operations that have not been covered with atomic generic functions. Therefore these operations have no easy way to be executed with other than sequential consistency.

2.2.3. introduce modify and fetch generic functions. Compound assignment operations can only be expressed with sequential consistency with exactly the same sematics as the operator (return the result of the operation). Simply add all generic function interfaces that do the operation first and return the result.

N2329:6

Jens Gustedt 2.2.4. widen the scope of the fetch and modify functions to all arithmetic types. There is no reason that floating point types are excluded from generic functions. These might not be as efficient as integer types, but are easy to synthesize (just as other types without hardware atomics). Just do it.

2.2.5. force the prototype of a atomic generic functions. Write down the rules that lead to the choice of a particular prototype of a generic function that is used in a call and enforce these rules.

2.2.6. remove the volatile crap from atomic generic functions. These are generic functions anyhow, so there is no reason to impose volatile-qualified parameters. The way this was formulated forced implementations to go through a volatile access, even though this might not be necessary. Just relax. (the diffmarks are not very good on this because these volatile are inside code.) 2.2.7. also remove volatile from the atomic_flag functions. Removal of volatile from these family of functions is a bit more complicated because they are not yet specified as type generic functions. On the other hand, if simple unsigned char or int (or _Atomic versions thereof) have sufficient properties to be used as atomic_flag it could be more efficient to avoid a volatile access for the operations. Therefore I propose to make them also type generic functions and leave it to the implementation if they want to have separate functions with and without volatile.

2.2.8. lift ambiguity of what has to be happening for _Atomic inside array paramenters. My interpretation of the current state is that the lack of specification of atomic array parameters is just an overlook. I propose to apply the correct terminology.

IMPACT

The proposed changes are such that they should have no immediate impact on user code.

-The set non-normative changes only clarify the specification, by collecting certain properties to more centralized locations, by adding obvious omissions and by removing erroneous non-normative text. -The normative changes are made such that the only changes imposed are to the implementations, not to users. But even for the implementations, these new interfaces are structured exactly as the existing ones, and present no additional code complexity. -The changes that remove volatile qualifications may simply be ignored by implementations. Implementations would be conforming without them. This is only meant to give leeway to implementations to avoid volatile accesses where this is possible for them. -The additions concerning synchronization should only formulate the obvious existing practice. E.g it should be clear that thread specific storage destructors are sequenced with respect to the just finished thread code. -To ease the transition to a new revision, I also propose a feature test macro that reflects the C standard to which the atomics implementation adheres.

Appendix: diffmarks for the proposed changes

Following are those pages that contain diffmarks for the proposed changed against C2x. The procedure is not perfect, in particular there may be changes inside code blocks that are not visible. since the values for a and b might have been, respectively, 4 and -8 or -17 and 12. However, on a machine in which overflow silently generates some value and where positive and negative overflows cancel, the above expression statement can be rewritten by the implementation in any of the above ways because the same result will occur.

ISO/IEC

EXAMPLE 7

The grouping of an expression does not completely determine its evaluation. In the following fragment Forward references: expressions (6.5), type qualifiers (6.7.3), statements (6.8), floating-point environment <fenv.h> (7.6), the signal function (7.14), files (7.21.3).

#

Multi-threaded executions and data races

Under a hosted implementation, a program can have more than one thread of execution (or thread) running concurrently. The execution of each thread proceeds as defined by the remainder of this document. The execution of the entire program consists of an execution of all of its threads. 14) Under a freestanding implementation, it is implementation-defined whether a program can have more than one thread of execution.

The value of an object visible to a thread T at a particular point is the initial value of the object, a value stored in the object by T , or a value stored in the object by another thread, according to the rules below. NOTE 1 In some cases, there could 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.

Two expression evaluations conflict if one of them modifies a memory location and the other one reads or modifies the same memory location.

The library defines ::::: There ::: are : a number of (7.17) and ::::::::: operations ::::: that :::: are :::::::: specially :::::::::: identified ::

as ::::::::::::::: synchronization ::::::::::: operations: :: if :::: the ::::::::::::::: implementation :::::::: supports :::: the :::::::: atomics ::::::::: extension ::::: these :::: are ::::::::

operators ::::: and ::::::: generic ::::::::: functions :::: that ::: act ::: on ::::::: atomic ::::::: objects :::: (6.5 :::: and ::::: 7.17); :: if :::: the ::::::::::::::: implementation ::::::::

supports ::: the ::::::: thread ::::::::: extension ::::: these ::: are :::: calls ::: to :::::::::::: initialization :::::::: functions :::::::: (7.26.2), operations on mutexes (7.26.4) that are specially identified as synchronization operations. ::::: 7.26.3 :::: and ::::::: 7.26.4), ::: and ::::: calls ::

to :::::: thread ::::::::: functions ::::::: (7.26.5). : These operations play a special role in making assignments :::: side :::::: effects in one thread visible to another. A synchronization operation on one or more memory locations is either an acquire operation, a release operation, both an acquire and release operation, or a consume 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 ::: but :::: still ::: are :::::::::: indivisible, and atomic read-modify-write operations, which have special characteristics. ::: are ::::: those :::::::::: operations ::::::: defined ::: in ::: 6.5 ::: and :::: 7.17 :::: that ::: act ::: on :: an ::::::: atomic ::::: object ::: by ::::::: reading ::: its :::::: value, :: by ::::::::::: performing :: an :::::::: optional ::::::::: operation ::::: with ::: that :::::: value :::: and :: by ::::::: storing ::::: back : a :::::: value :::: into :::: that :::::: object. NOTE 2 For example, a call that acquires a mutex will perform an acquire operation on the locations composing 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 14) The execution can usually be viewed as an interleaving of all of the threads. However, some kinds of atomic operations, for example, allow executions inconsistent with a simple interleaving as described below. 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 B, then A shall precede B in the modification order of M , which is defined below. NOTE 3 This states that the modification orders are expected to respect the "happens before" relation. NOTE 4 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 can observe modifications to different variables in inconsistent orders.

A release sequence headed by a release operation A on an atomic object M is a maximal contiguous sub-sequence of side effects in the modification order of M , where the first operation is A and every subsequent operation either is performed by the same thread that performed the release or is an atomic read-modify-write operation.

Certain library calls ::::::::: operations : synchronize with other library calls ::::::::: operations : performed by another thread. In particular, an atomic operation A that performs a release operation on an object M synchronizes with an atomic operation B that performs an acquire operation on M and reads a value written by any side effect in the release sequence headed by A. NOTE 5 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. NOTE 6 The specifications of the synchronization operations define when one reads the value written by another. For atomic variables, 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.

An evaluation A carries a dependency 15) to an evaluation B if:

-the value of A is used as an operand of B, unless:

• B is an invocation of the kill _ dependency macro,

• A is the left operand of a && or || operator,

• A is the left operand of a ?: operator, or

• A is the left operand of a , operator; or -A writes a scalar object or bit-field M , B reads from M the value written by A, and A is sequenced before B, or -for some evaluation X, A carries a dependency to X and X carries a dependency to B.

An evaluation A is dependency-ordered before 16) 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.

An evaluation A inter-thread happens before an evaluation B if A synchronizes with B, A is dependency-ordered before B, or, for some evaluation X:

-A synchronizes with X and X is sequenced before B, -A is sequenced before X and X inter-thread happens before B, or 15) The "carries a dependency" relation is a subset of the "sequenced before" relation, and is similarly strictly intra-thread. 16) The "dependency-ordered before" relation is analogous to the "synchronizes with" relation, but uses release/consume in place of release/acquire. § 5.1.2.4

Environment 15

:::

diff :::::: marks -December 8, 2018 ISO/IEC 9899:2017 ::

2x (E)

Except for bit-fields, objects are composed of contiguous sequences of one or more bytes, the number, order, and encoding of which are either explicitly specified or implementation-defined.

Values stored in unsigned bit-fields and objects of type unsigned char shall be represented using a pure binary notation. 50) Values stored in non-bit-field objects of any other object type consist of n × CHAR _ BIT bits, where n is the size of an object of that type, in bytes. The value may be copied into an object of type unsigned char [n] (e.g., by memcpy); the resulting set of bytes is called the object representation of the value. Values stored in bit-fields consist of m bits, where m is the size specified for the bit-field. The object representation is the set of m bits the bit-field comprises in the addressable storage unit holding it. Two values (other than NaNs) with the same object representation compare equal, but values that compare equal may have different object representations.

Certain object representations need not represent a value of the object type. If the stored value of an object has such a representation and is read by an lvalue expression that does not have character type, the behavior is undefined. If such a representation is produced by a side effect that modifies all or any part of the object by an lvalue expression that does not have character type, the behavior is undefined. 51) Such a representation is called a trap representation.

When a value is stored in an object of structure or union type, including in a member object, the bytes of the object representation that correspond to any padding bytes take unspecified values. 52) The value of a structure or union object is never a trap representation, even though the value of a member of the structure or union object may be a trap representation.

When a value is stored in a member of an object of union type, the bytes of the object representation that do not correspond to that member but do correspond to other members take unspecified values.

Where an operator is applied to a value that has more than one object representation, which object representation is used shall not affect the value of the result. 53) Where a value is stored in an object using a type that has more than one object representation for that value, it is unspecified which representation is used, but a trap representation shall not be generated.

Loads and stores of objects with atomic types ::: All :::::::::: operations ::: on ::::::: atomic :::::: objects : are done with memory _ order _ seq _ cst semantics. operation :::: may ::: by :::: itself :::::: never ::::: raise : a :::::: signal, :: a :::: trap, :: a ::::::: floating ::::: point ::::::::: exception ::: or ::::: result ::::::::: otherwise ::: in ::

an ::::::::::: interruption ::: of ::: the ::::::: control ::::: flow. 55)

Forward references: declarations (6.7), expressions (6.5), lvalues, arrays, and function designators (6.3.2.1), order and consistency (7.17.3).

Integer types

For unsigned integer types other than unsigned char, the bits of the object representation shall be divided into two groups: value bits and padding bits (there need not be any of the latter). If there are N value bits, each bit shall represent a different power of 2 between 1 and 2 N -1 , so that objects of that type shall be capable of representing values from 0 to 2 N -1 using a pure binary representation; 50) A positional representation for integers that uses the binary digits 0 and 1, in which the values represented by successive bits are additive, begin with 1, and are multiplied by successive integral powers of 2, except perhaps the bit with the highest position. (Adapted from the American National Dictionary for Information Processing Systems.) A byte contains CHAR _ BIT bits, and the values of type unsigned char range from 0 to 2 CHAR _ BIT -1.

51) Thus, an automatic variable can be initialized to a trap representation without causing undefined behavior, but the value of the variable cannot be used until a proper value is stored in it.

52) Thus, for example, structure assignment need not copy any padding bits.

53) It is possible for objects x and y with the same effective type T to have the same value when they are accessed as objects of type T, but to have different values in other contexts. In particular, if == is defined for type T, then x == y does not imply that memcmp(&x, &y, sizeof (T))== 0. Furthermore, x == y does not necessarily imply that x and y have the same value; other operations on values of type T might distinguish between them.

54)

:::

Such :::::::: erroneous :::::::: operations ::: may ::: for :::::: example :::: incur :::::::: arithmetic ::::::: overflow, :::::: division :: by :::: zero : or ::::::: negative ::::: shifts.

55)

::::::

Whether :: or ::: not :: an ::::: atomic ::::::: operation ::: may :: be ::::::::: interrupted :: by : a ::::: signal :::::: depends :: on ::: the ::::::: lock-free :::::: property :: of :: the ::::::::: underlying For signed integer types, the bits of the object representation shall be divided into three groups: value bits, padding bits, and the sign bit. There need not be any padding bits; signed char shall not have any padding bits. There shall be exactly one sign bit. Each bit that is a value bit shall have the same value as the same bit in the object representation of the corresponding unsigned type (if there are M value bits in the signed type and N in the unsigned type, then M ≤ N ). If the sign bit is zero, it shall not affect the resulting value. If the sign bit is one, the value shall be modified in one of the following ways:

-the corresponding value with sign bit 0 is negated (sign and magnitude);

-the sign bit has the value -(2 M ) (two's complement);

-the sign bit has the value -(2 M -1) (ones' complement).

Which of these applies is implementation-defined, as is whether the value with sign bit 1 and all value bits zero (for the first two), or with sign bit and all value bits 1 (for ones' complement), is a trap representation or a normal value. In the case of sign and magnitude and ones' complement, if this representation is a normal value it is called a negative zero.

If the implementation supports negative zeros, they shall be generated only by:

-the &, |, ^, ~, << , and >> operators with operands that produce such a value;

-the + ,-, * , /, and % operators where one operand is a negative zero and the result is zero;

-compound assignment operators based on the above cases.

It is unspecified whether these cases actually generate a negative zero or a normal zero, and whether a negative zero becomes a normal zero when stored in an object.

If the implementation does not support negative zeros, the behavior of the &, |, ^, ~, << , and >> operators with operands that would produce such a value is undefined.

The values of any padding bits are unspecified. 57) A valid (non-trap) object representation of a signed integer type where the sign bit is zero is a valid object representation of the corresponding unsigned type, and shall represent the same value. For any integer type, the object representation where all the bits are zero shall be a representation of the value zero in that type.

The precision of an integer type is the number of bits it uses to represent values, excluding any sign and padding bits. The width of an integer type is the same but including any sign bit; thus for unsigned integer types the two values are the same, while for signed integer types the width is one greater than the precision.

:::::::::::::::

Implementations ::::: that :::::::: support ::: the :::::::: atomics :::::::::: extension ::::::::: represent ::: all ::::::: signed :::::::: integers ::::: with :::::: two's :::::::::::

complement ::::: such :::: that :::: the :::::: object :::::::::::::: representation ::::: with :::: sign :::: bit :: 1 :::: and ::: all :::::: value :::: bits ::::: zero :: is :::: the ::::::::: minimum ::::: value :: of :::: the ::::: type.

Compatible type and composite type

Two types have compatible type if their types are the same. Additional rules for determining whether two types are compatible are described in 6.7.2 for type specifiers, in 6.7.3 for type qualifiers, and in 6.7.6 for declarators. 58) Moreover, two structure, union, or enumerated types declared in separate 56) Some combinations of padding bits might generate trap representations, for example, if one padding bit is a parity bit. Regardless, no arithmetic operation on valid values can generate a trap representation other than as part of an exceptional condition such as an overflow, and this cannot occur with unsigned types. All other combinations of padding bits are alternative object representations of the value specified by the value bits.

57) Some combinations of padding bits might generate trap representations, for example, if one padding bit is a parity bit. Regardless, no arithmetic operation on valid values can generate a trap representation other than as part of an exceptional condition such as an overflow. All other combinations of padding bits are alternative object representations of the value specified by the value bits.

58) Two types need not be identical to be compatible. Forward references: address and indirection operators (6.5.3.2), structure and union specifiers (6.7.2.1).

Postfix increment and decrement operators Constraints

The operand of the postfix increment or decrement operator shall have atomic, qualified, or unqualified real or pointer type, and shall be a modifiable lvalue.

Semantics

The result of the postfix ++ operator is the value of the operand. As a side effect, the value of the operand object is incremented (that is, the value 1 of the appropriate type is added to it). See the discussions of additive operators and compound assignment for information on constraints, types, and conversions and the effects of operations on pointers. The value computation of the result is sequenced before the side effect of updating the stored value of the operand. With respect to an indeterminately-sequenced function call, the operation of postfix ++ is a single evaluation.Postfix ++ on an object with atomic type is a read-modify-write operation with memory _ order _ seq _ cst memory order semantics. 104) The postfix--operator is analogous to the postfix ++ operator, except that the value of the operand is decremented (that is, the value 1 of the appropriate type is subtracted from it).

Forward references: additive operators (6.5.6), compound assignment (6.5.16.2).

Compound literals Constraints

The type name shall specify a complete object type or an array of unknown size, but not a variable length array type.

All the constraints for initializer lists in 6.7.9 also apply to compound literals.

Semantics

A postfix expression that consists of a parenthesized type name followed by a brace-enclosed list of initializers is a compound literal. It provides an unnamed object whose value is given by the initializer list. 105) 104) Where a pointer to an atomic object can be formed and E has integer type, E++ is equivalent to the following code sequence where T is the type of E:

T * addr = &E; T old = * addr; T new; do { new = old + 1; } while (!atomic _ compare _ exchange _ weak(addr, &old, new)); with old being the result of the operation.

Special care is necessary if E has floating type; see 6.5.16.2. 105) Note that this differs from a cast expression. For example, a cast specifies a conversion to scalar types or void only, and the result of a cast expression is not an lvalue. § 6.5. The first assignment is unsafe because it would allow the following valid code to attempt to change the value of the const object c.

Compound assignment Constraints

For the operators += and-= only, either the left operand shall be an atomic, qualified, or unqualified pointer to a complete object type, and the right shall have integer type; or the left operand shall have atomic, qualified, or unqualified arithmetic type, and the right shall have arithmetic type.

For the other operators, the left operand shall have atomic, qualified, or unqualified arithmetic type, and (considering the type the left operand would have after lvalue conversion) each operand shall have arithmetic type consistent with those allowed by the corresponding binary operator.

Semantics

A compound assignment of the form E1 op= E2 is equivalent to the simple assignment expression E1 = E1 op (E2), except that the lvalue E1 is evaluated only once, and with respect to an indeterminately-sequenced function call, the operation of a compound assignment is a single evaluation. If E1 has an atomic type, compound assignment is a read-modify-write operation with memory _ order _ seq _ cst memory order semantics. NOTE Where a pointer to an atomic object can be formed and E1 and E2 have integer type, this is equivalent to the following code sequence where T1 is the type of E1 and T2 is the type of E2:

T1 * addr = &E1; T2 val = (E2); T1 old = * addr; T1 new; do { new = old op val; } while (!atomic _ compare _ exchange _ weak(addr, &old, new));

with new being the result of the operation.

If E1 or E2 has floating type, then exceptional conditions or floating-point exceptions encountered during discarded evaluations of new would also be discarded in order to satisfy the equivalence of E1 op= E2 and E1 = E1 op (E2). For example, if Annex F is in effect, the floating types involved have IEC 60559 formats, and FLT _ EVAL _ METHOD is 0, the equivalent code would be: specify a pair of structures that contain pointers to each other. Note, however, that if s2 were already declared as a tag in an enclosing scope, the declaration D1 would refer to it, not to the tag s2 declared in D2. To eliminate this context sensitivity, the declaration struct s2;

can be inserted ahead of D1. This declares a new tag s2 in the inner scope; the declaration D2 then completes the specification of the new type.

Forward references: declarators (6.7.6), type definitions (6.7.8).

Atomic type specifiers Syntax

atomic-type-specifier: _ Atomic ( type-name )

Constraints

Atomic type specifiers shall not be used if the implementation does not support atomic types (see 6.10.8.3).

The type name in an atomic type specifier shall not refer to an array type, a function type, an atomic type, or a qualified type.

Semantics

The properties associated with atomic types are meaningful only for expressions that are lvalues. If the _ Atomic keyword is immediately followed by a left parenthesis, it is interpreted as a type specifier (with a type name), not as a type qualifier. EXAMPLE 1 ::: This :::::::::::: disambiguation : of ::: the ::::::: grammar :: is ::::::: necessary, :::::: because :: in ::::::: marginal :::: cases :: a :::::: qualifier :::: may :: be ::::::: followed :: by ::

an :::::: opening ::::::::: parenthesis.

Constraints

Types other than pointer types whose referenced type is an object type shall not be restrict-qualified.

The _ Atomic qualifier shall not be used if the implementation does not support atomic types (see 6.10.8.3).

The type modified by the the keyword static shall appear only in a declaration of a function parameter with an array type, and then only in the outermost array type derivation.

If an identifier is declared as having a variably modified type, it shall be an ordinary identifier (as defined in 6.2.3), have no linkage, and have either block scope or function prototype scope. If an identifier is declared to be an object with static or thread storage duration, it shall not have a variable length array type.

Semantics

If, in the declaration "T D1", D1 has one of the forms: and the type specified for ident in the declaration "T D" is "derived-declarator-type-list T", then the type specified for ident is "derived-declarator-type-list array of T". 147) (See 6.7.6.3 for the meaning of the optional type qualifiers and the keyword static.)

If the size is not present, the array type is an incomplete type. If the size is * instead of being an expression, the array type is a variable length array type of unspecified size, which can only be used in declarations or type names with function prototype scope; 148) such arrays are nonetheless complete types. If the size is an integer constant expression and the element type has a known constant size, the array type is not a variable length array type; otherwise, the array type is a variable length array type. (Variable length arrays are a conditional feature that implementations need not support; see 6.10.8.3.)

If the size is an expression that is not an integer constant expression: if it occurs in a declaration at function prototype scope, it is treated as if it were replaced by * ; otherwise, each time it is evaluated it shall have a value greater than zero. The size of each instance of a variable length array type does not change during its lifetime. Where a size expression is part of the operand of :: an :::::::::: _ Alignof :::::::: operator, :::

that ::::::::::: expression :: is ::: not :::::::::: evaluated. ::::::::::: Otherwise, :::::: where :: a :::: size :::::::::: expression :: is :::: part ::: of ::: the :::::::: operand :: of : a sizeof operator and changing the value of the size expression would not affect the result of the operator, it is unspecified whether or not the size expression is evaluated. Where a size expression is part of the operand of an _ Alignof operator ::::::::: Otherwise, that expression is not evaluated :::::::::: evalutated.

For two array types to be compatible, both shall have compatible element types, and if both size specifiers are present, and are integer constant expressions, then both size specifiers shall have the same constant value. If the two array types are used in a context which requires them to be compatible, it is undefined behavior if the two size specifiers evaluate to unequal values. The first declares x to be a pointer to int; the second declares y to be an array of int of unspecified size (an incomplete type), the storage for which is defined elsewhere.

147) When several "array of" specifications are adjacent, a multidimensional array is declared. and the type specified for ident in the declaration "T D" is "derived-declarator-type-list T", then the type specified for ident is "derived-declarator-type-list function returning the unqualified version of T".

A parameter type list specifies the types of, and may declare identifiers for, the parameters of the function.

A declaration of a parameter as "array of type" shall be adjusted to "qualified :::::: atomic :: or ::::::::::: non-atomic, ::::::::

qualified :: or ::::::::::: unqualified pointer to type", where the type qualifiers (if any) are those specified within the [ and ] of the array type derivation. If the keyword static also appears within the [ and ] of the array type derivation, then for each call to the function, the value of the corresponding actual argument shall provide access to the first element of an array with at least as many elements as specified by the size expression.

A declaration of a parameter as "function returning type" shall be adjusted to "pointer to function returning type", as in 6.3.2.1.

If the list terminates with an ellipsis (, ...), no information about the number or types of the parameters after the comma is supplied. 149)

The special case of an unnamed parameter of type void as the only item in the list specifies that the function has no parameters.

If, in a parameter declaration, an identifier can be treated either as a typedef name or as a parameter name, it shall be taken as a typedef name.

If the function declarator is not part of a definition of that function, parameters may have incomplete type and may use the [ * ] notation in their sequences of declarator specifiers to specify variable length array types.

The storage-class specifier in the declaration specifiers for a parameter declaration, if present, is ignored unless the declared parameter is one of the members of the parameter type list for a function definition.

An identifier list declares only the identifiers of the parameters of the function. An empty list in a function declarator that is part of a definition of that function specifies that the function has no parameters. The empty list in a function declarator that is not part of a definition of that function specifies that no information about the number or types of the parameters is supplied. 150) For two function types to be compatible, both shall specify compatible return types. 151) Moreover, the parameter type lists, if both are present, shall agree in the number of parameters and in use of the ellipsis terminator; corresponding parameters shall have compatible types. If one type has a parameter type list and the other type is specified by a function declarator that is not part of a function definition and that contains an empty identifier list, the parameter list shall not have an ellipsis terminator and the type of each parameter shall be compatible with the type that results from the application of the default argument promotions. If one type has a parameter type list and the other type is specified by a function definition that contains a (possibly empty) identifier list, both shall agree in the number of parameters, and the type of each prototype parameter shall be compatible with the type that results from the application of the default argument promotions to the type of the corresponding identifier. (In the determination of type compatibility and of a composite type, each parameter declared with function or array type is taken as having the adjusted type and each parameter declared with qualified type is taken as having the unqualified version of its declared type.)

149) The macros defined in the <stdarg.h> header (7.16) can be used to access arguments that correspond to the ellipsis. 150) See "future language directions" (6.11.6). When a signal occurs and func points to a function, it is implementation-defined whether the equivalent of signal(sig, SIG _ DFL); is executed or the implementation prevents some implementation-defined set of signals (at least including sig) from occurring until the current signal handling has completed; in the case of SIGILL, the implementation may alternatively define that no action is taken. Then the equivalent of ( * func)(sig); is executed. If and when the function returns, if the value of sig is SIGFPE, SIGILL, SIGSEGV, or any other implementation-defined value corresponding to a computational exception, the behavior is undefined; otherwise the program will resume execution at the point it was interrupted.

If the signal occurs as the result of calling the abort or raise function, the signal handler shall not call the raise function.

If the signal occurs other than as the result of calling the abort or raise function, the behavior is undefined if the signal handler refers to any object with static or thread storage duration that is not a lock-free atomic object other than by assigning a value to an object declared as is executed for all other signals defined by the implementation.

Use of this function in a multi-threaded program results in undefined behavior. The implementation shall behave as if no library function calls the signal function.

Returns

If the request can be honored, the signal function returns the value of func for the most recent successful call to signal for the specified signal sig. Otherwise, a value of SIG _ ERR is returned and a positive value is stored in errno.

Forward references: the abort function (7.22.4.1), the exit function (7.22.4.4), the Implementations that define the macro __ STDC _ NO _ ATOMICS __ need not provide this header nor support any of its facilities.

The macros defined are

__ STDC _ STDATOMIC _ VERSION __
which expands to the same token as __ STDC _ VERSION __ (yyyymmL) 262) and the atomic lock-free macros

ATOMIC _ BOOL _ LOCK _ FREE ATOMIC _ CHAR _ LOCK _ FREE ATOMIC _ CHAR16 _ T _ LOCK _ FREE ATOMIC _ CHAR32 _ T _ LOCK _ FREE ATOMIC _ WCHAR _ T _ LOCK _ FREE ATOMIC _ SHORT _ LOCK _ FREE ATOMIC _ INT _ LOCK _ FREE ATOMIC _ LONG _ LOCK _ FREE ATOMIC _ LLONG _ LOCK _ FREE ATOMIC _ POINTER _ LOCK _ FREE

which expand to constant expressions suitable for use in #if preprocessing directives and which indicate the lock-free property of the corresponding atomic types (both signed and unsigned); and

ATOMIC _ FLAG _ INIT

which expands to an initializer for an object of type atomic _ flag.

The types include memory _ order

which is an enumerated type whose enumerators identify memory ordering constraints;

atomic _ flag which is a structure type representing a lock-free, primitive atomic flag; and several atomic analogs of integer types.

In the following synopses:

-An A refers to an atomic type :::: that :: is ::: not ::::::::::::::: const-qualified.

-A C refers to its corresponding non-atomic :::::::::: unqualified : type.

-An M refers to the type of the other argument for arithmetic operations. For atomic integer :::::::::

arithmetic : types, M is C. For atomic pointer types, M is ptrdiff _ t.
-The functions not ending in _ explicit have the same semantics as the corresponding _ explicit function with memory _ order _ seq _ cst for the memory _ order argument.

:::

The ::::::::: prototype ::: for :: a ::: call ::: to : a ::::::: generic :::::::: function :::::::: specified :: in :::: this :::::: clause :: is :::::::::: determined ::: by ::: the :::::::::: pointed-to ::::

type :: A :: of :::: the :::: first ::::::::: argument :: of ::: the :::: call :::: and ::: the ::::: types :: C ::: and ::: M ::: are :::::::: deduced ::::::::: according ::: to ::: the :::::: above 261) See "future library directions" (7.31.8).

262) The intent of this macro is to keep track of the version of this document to which a particular C library implementation of <stdatomic.h> adheres. This is meant to facilitate the transition to a new standard for users, not as a leeway for implementations to delay an upgrade.

204 Library § 7.17.1

:::

diff :::::: marks -December 8, 2018 ISO/IEC 9899:2017 :: 2x (E)

:::::

rules. :::::: Other :::::::::: arguments :: to :::: the ::: call ::::: shall ::: be ::::::::: implicitly ::::::::::: convertable :: to ::: the :::::: types :::: that ::: are :::::::: required ::: by :::

the :::::: chosen :::::::::: prototype ::: and :::: are ::::::::: converted ::::::::::: accordingly :::::: before ::: the :::: call. :

It is unspecified whether any generic function declared in :::::::: specified :: in :::: this :::::: clause is a macro or an identifier declared with external linkage. If a macro definition is suppressed in order to access an actual function, or a program defines an external identifier with the name of a generic function, the behavior is undefined.

Many operations are volatile-qualified. The "volatile as device register" semantics have not changed in the standard. This qualification means that volatility is preserved when applying these operations to volatile objects.

Initialization

The expands to a token sequence suitable for initializing an atomic object of a type that is initialization-compatible with value. An atomic object with automatic storage duration that is not explicitly initialized is initially in an indeterminate state; however, the default (zero) initialization for objects with static or thread-local storage duration is guaranteed to produce a valid state.See "future library directions" (7.31.8).

Concurrent access to the variable being initialized, even via an atomic operation, constitutes a data race.

EXAMPLE 1 :::

The ::::::: following :::::::: definitions ::::: ensure :::: valid :::: states ::: for ::::: guide ::: and :::: head ::::::: regardless :: if :::: these :: are ::::: found :: in :: file ::::: scope :: or ::::

block ::::: scope. :::: Thus ::: any ::::: atomic ::::::: operation ::: that :: is :::::::: performed :: on :::: them :::: after ::: their :::::::::: initialization ::: has ::: been ::: met :: is ::: well ::::::: defined.

_ Atomic int guide = 42;

static void * _ Atomic head; EXAMPLE 2 :::: With :: the :::::::: following :::::::: definition :: in :::: block ::::: scope, ::::::::: concurrent :::::: accesses :: to ::::: cumul ::: are :::::::: undefined ::::: unless :: a :::: prior :::::: race-free :::::::::: initialization, :::: either ::: by : a ::: call : to ::::::::::: atomic _ init, : a :::: store ::::::: operation :: or :: by ::::::::: assignment, ::: has ::: been ::::::::: performed.

_ Atomic double cumul;

7.17.2.1 The atomic _ init generic function Synopsis #include <stdatomic.h> void atomic _ init(A * obj, C value);

Description

The atomic _ init generic function initializes the atomic object pointed to by obj to the value value, while also initializing any additional state that the implementation might need to carry for the atomic object.

Although this function initializes an atomic object, it does not avoid data races; concurrent access to the variable being initialized, even via an atomic operation, constitutes a data race.

If a signal occurs other than as the result of calling the abort or raise functions, the behavior is undefined if the signal handler calls the atomic _ init generic function.

Returns

The atomic _ init generic function returns no value. EXAMPLE _ Atomic int guide; atomic _ init(&guide, 42);

Order and consistency

The enumerated type memory _ order specifies the detailed regular (non-atomic) memory synchronization operations as defined in 5.1.2.4 and may provide for operation ordering. Its enumeration § 7.17. For memory _ order _ relaxed, no operation orders memory.

For memory _ order _ release, memory _ order _ acq _ rel, and memory _ order _ seq _ cst, a store operation performs a release operation on the affected memory location.

For memory _ order _ acquire, memory _ order _ acq _ rel, and memory _ order _ seq _ cst, a load operation performs an acquire operation on the affected memory location.

For memory _ order _ consume, a load operation performs a consume operation on the affected memory location.

There shall be a single total order S on all memory _ order _ seq _ cst operations, consistent with the "happens before" order and modification orders for all affected locations, such that each memory _ order _ seq _ cst operation B that loads a value from an atomic object M observes one of the following values:

-the result of the last modification A of M that precedes B in S, if it exists, or -if A exists, the result of some modification of M that is not memory _ order _ seq _ cst and that does not happen before A, or -if A does not exist, the result of some modification of M that is not memory _ order _ seq _ cst. NOTE 1 Although it is not explicitly required that S include lock operations, it can always be extended to an order that does include lock and unlock operations, since the ordering between those is already included in the "happens before" ordering. NOTE 2 Atomic operations specifying memory _ order _ relaxed are relaxed only with respect to memory ordering. Implementations still guarantee that any given atomic access to a particular atomic object is indivisible with respect to all other atomic accesses to that object.

For an atomic operation B that reads the value of an atomic object M , if there is a memory _ order _ seq _ cst fence X sequenced before B, then B observes either the last memory _ order _ seq _ cst modification of M preceding X in the total order S or a later modification of M in its modification order.

For atomic operations A and B on an atomic object M , where A modifies M and B takes its value, if there is a memory _ order _ seq _ cst fence X such that A is sequenced before X and B follows X in S, then B observes either the effects of A or a later modification of M in its modification order.

For atomic modifications A and B of an atomic object M , B occurs later than A in the modification order of M if:

-there is a memory _ order _ seq _ cst fence X such that A is sequenced before X, and X precedes B in S, or -there is a memory _ order _ seq _ cst fence Y such that Y is sequenced before B, and A precedes Y in S, or -there are memory _ order _ seq _ cst fences X and Y such that A is sequenced before X, Y is sequenced before B, and X precedes Y in S.

Description

The order argument shall not be memory _ order _ acquire, memory _ order _ consume, nor memory _ order _ acq _ rel. Atomically replace the value pointed to by object with the value of desired. Memory is affected according to the value of order.

Returns

The atomic _ store generic functions return no value.

Description

The order argument shall not be memory _ order _ release nor memory _ order _ acq _ rel. Memory is affected according to the value of order.

Returns

Atomically returns the value pointed to by object.

Description

Atomically replace the value pointed to by object with desired. Memory is affected according to the value of order. These operations are read-modify-write operations (5.1.2.4).

Returns

Atomically returns the value pointed to by object immediately before the effects.

Description

The failure argument shall not be memory _ order _ release nor memory _ order _ acq _ rel. The failure argument shall be no stronger than the success ::: not ::::::: impose ::::: more ::::::::::: constraints ::: on :::: the A weak compare-and-exchange operation may fail spuriously. That is, even when the contents of memory referred to by expected and object are equal, it may return zero and store back to expected the same memory contents that were originally there. NOTE 2 This spurious failure enables implementation of compare-and-exchange on a broader class of machines, e.g. load-locked store-conditional machines. EXAMPLE A consequence of spurious failure is that nearly all uses of weak compare-and-exchange will be in a loop. When a compare-and-exchange is in a loop, the weak version will yield better performance on some platforms. When a weak compare-and-exchange would require a loop and a strong one would not, the strong one is preferable.

Returns

The result of the comparison.

The atomic fetch and modify generic functions

The following operations perform arithmetic and bitwise computations. All of these ::::: These : operations are applicable to an object of any atomic integer type . None of these operations is applicable to atomic _ bool. : floating ::::: point :::: types, ::: and :::: only :::: "add" ::: and ::::: "sub" :::::: variants :: are :::::::: permitted :: for ::::: atomic :::::: pointer ::::: types. :: For ::: the :::: latter ::: the ::: type ::: for :: M : is ::::::::: ptrdiff _ t, :: see ::::: 7.17.1.

Description

Atomically replaces the value pointed to by object with the result of the computation applied to the value pointed to by object and the given operand. Memory is affected according to the value of order. These operations are atomic read-modify-write operations (5.1.2.4). For signed integer types, arithmetic is defined to use two's complement representation with silent wrap-around on overflow; there are no undefined results. For address types, the result may be an undefined address, but the operations otherwise have no undefined behavior.

Returns

Atomically, the value pointed to by object immediately before the effects . key ::::::: _ fetch :::::::: variants). : NOTE The ::: For :::: many :::::: aspects ::: the operation of the atomic fetch and modify generic functions are nearly equivalent to the operation of the corresponding op= compound assignment operators. The only differences arethat the compound assignment operators are not guaranteed to operate atomically, and the value yielded by a compound assignment operator is the updated :::::

Notable :::::::: differences ::: are: :::::::: according :: to :: the :::::: variant :: the ::::: value :::::: returned :: by ::: the atomic fetch and modify generic functions : is ::: the ::::::: previous value of the object, whereas the value returned by the is the previous value of ::::: atomic ::::: object; ::: the :::::: memory :::: order ::: can :: be ::::::: specified :: to :: be ::: less :::: strict ::: than ::: the ::::::: operator; :: the ::::::: possible :::: range :: of ::::: values :: for ::::::: operand ::: can :: be ::::::: narrower for ::: the ::::: generic :::::: function :: is ::: first :::::::: converted : to ::::::::: UCHAR _ MAX. :

Atomic flag type and operations

The atomic _ flag type provides the classic test-and-set functionality. It has two states, set and clear.

Operations on an object of type atomic _ flag shall be lock free. NOTE Hence, as per 7.17.5, the operations should also be address-free. No other type requires lock-free operations, so the atomic _ flag type is the minimum hardware-implemented type needed to conform to this document. The remaining types can be emulated with atomic _ flag, though with less than ideal properties.

The macro ATOMIC _ FLAG _ INIT may be used to initialize an atomic _ flag to the clear state. An atomic _ flag that is not explicitly initialized with In ::: the ::::::::: following :::::::: synopsis :: A ::::::: denotes ::::::::::::: atomic _ flag, ::::::: possibly :::::::::: volatile :::::::: qualified. :: It :: is ::::::::::: unspecified :: if :::

any :: of :::: the :::: type ::::::: generic ::::::::: functions ::: has ::::: only ::: one ::::::: variant ::::: with ::::::::: volatile ::::::::::: qualification ::: or :::: also : a ::::::: second

Description

Atomically places the atomic flag pointed to by object in the set state and returns the value corresponding to the immediately preceding state. Memory is affected according to the value of order. These operations are atomic read-modify-write operations (5.1.2.4).

Returns

The atomic _ flag _ test _ and _ set generic functions return the value that corresponds to the state of the atomic flag immediately before the effects.

Description

The order argument shall not be memory _ order _ acquire nor memory _ order _ acq _ rel. Atomically places the atomic flag pointed to by object into the clear state. Memory is affected according to the value of order.

Returns

The atomic _ flag _ clear generic functions return no value. First, all functions registered by the atexit function are called, in the reverse order of their registration, 308) except that a function is called after any previously registered functions that had already been called at the time it was registered. If, during the call to any such function, a call to the longjmp function is made that would terminate the call to the registered function, the behavior is undefined.

::

A ::::::::: sequence :::::: point ::::::: occurs :: at :::: the ::::::::::: beginning ::: of :::: that :::::::::: procedure ::::: and :::::::::::: immediately ::::::: before ::::: and :::::::::::

immediately ::::: after :::: each :::: call :: to :: a ::::::: function :::::::::: registered :::: with :::::::: atexit.

Next, all open streams with unwritten buffered data are flushed, all open streams are closed, and all files created by the tmpfile function are removed.

Finally, control is returned to the host environment. If the value of status is zero or EXIT _ SUCCESS, an implementation-defined form of the status successful termination is returned. If the value of status is EXIT _ FAILURE, an implementation-defined form of the status unsuccessful termination is returned. Otherwise the status returned is implementation-defined.

Returns

The exit function cannot return to its caller.

Returns

The _ Exit function cannot return to its caller.

Description

The getenv function searches an environment list, provided by the host environment, for a string that matches the string pointed to by name. The set of environment names and the method for altering the environment list are implementation-defined. The getenv function need not avoid data races with other threads of execution that modify the environment list. 309) The implementation shall behave as if no library function calls the getenv function.

Returns

The getenv function returns a pointer to a string associated with the matched list member. The string pointed to shall not be modified by the program, but may be overwritten by a subsequent call to the getenv function. If the specified name cannot be found, a null pointer is returned. The quick _ exit function first calls all functions registered by the at _ quick _ exit function, in the reverse order of their registration, 310) except that a function is called after any previously registered functions that had already been called at the time it was registered. If, during the call to any such function, a call to the longjmp function is made that would terminate the call to the registered function, the behavior is undefined.

::

A ::::::::: sequence :::::: point ::::::: occurs :: at :::: the ::::::::::: beginning ::: of :::: that :::::::::: procedure ::::: and :::::::::::: immediately ::::::: before ::::: and :::::::::::

immediately ::::: after :::: each :::: call :: to :: a ::::::: function :::::::::: registered :::: with ::::::::::::::: at _ quick _ exit. :

Then control is returned to the host environment by means of the function call _ Exit(status).

Returns

The quick _ exit function cannot return to its caller.

7.22.4.8

The system function Synopsis #include <stdlib.h> int system(const char * string);

Description

If string is a null pointer, the system function determines whether the host environment has a command processor. If string is not a null pointer, the system function passes the string pointed to by string to that command processor to be executed in a manner which the implementation shall document; this might then cause the program calling system to behave in a non-conforming manner or to terminate.

Returns

If the argument is a null pointer, the system function returns nonzero only if a command processor is available. If the argument is not a null pointer, and the system function does return, it returns an 309) Many implementations provide non-standard functions that modify the environment list. 310) Each function is called as many times as it was registered, and in the correct order with respect to other registered functions.

264 Library § 7.22.4.8

  ::: that ::: do :::: not ::::::: specify ::::::::: otherwise ::::: have ::::::::::::::::::::::: memory _ order _ seq _ cst ::::::: memory :::::::::::: consistency. :: If :: an :::::::::: operation :::: with :::::::: identical ::::::: values :: on :::: the :::::::::: non-atomic ::::: type :: is :::::::::: erroneous, 54) ::: the ::::::: atomic ::::::::: operation ::::::: results :: in ::: an :::::::::: unspecific :::::: object :::::::::::::: representation, :::: that ::::: may ::: or :::: may :::: not ::: be ::: an :::::: invalid :::::: value ::: for :::: the ::::: type, ::::: such :: as ::: an ::::::: invalid ::::::: address ::: or :: a ::::::: floating :::::: point ::::: NaN. :::::::: Thereby ::::: such ::: an :::::::::

  i is converted to the type of the assignment expression c = i, that is, char type. The value of the expression enclosed in parentheses is then converted to the type of the outer assignment expression, that is, long int type. EXAMPLE 3 Consider the fragment:

EXAMPLE 1 float

 1 fa[11], * afp[17]; declares an array of float numbers and an array of pointers to float numbers. EXAMPLE 2 Note the distinction between the declarations extern int * x; extern int y[];

  volatile sig _ atomic _ t, or the signal handler calls any function in the standard library other than -the abort function, -the _ Exit function, -the quick _ exit function, -the functions :::: and ::::::: generic :::::::: functions : in <stdatomic.h> (except where explicitly stated otherwise) when the atomic arguments are lock-free, -the atomic _ is _ lock _ free ::::::: generic function with any atomic argument, or -the signal function with the first argument equal to the signal number corresponding to the signal that caused the invocation of the handler. Furthermore, if such a call to the signal function results in a SIG _ ERR return, the value of errno is indeterminate. 259) At program startup, the equivalent of signal(sig, SIG _ IGN); may be executed for some signals selected in an implementation-defined manner; the equivalent of signal(sig, SIG _ DFL);

NOTE 3 :

 3 :: The ::::::: memory :::::::: orderings :: of ::::::::::: memory _ order :::::: impose ::::::: different :::::::: ordering :::::::: constraints ::: on :::::: certain ::::::::: operations. :: :::::::::::::::::: memory _ order _ relaxed, :::::::::::::::::::: memory _ order _ consume, ::::::::::::::::::::: memory _ order _ acquire, :::::::::::::::::::: memory _ order _ acq _ rel ::::: and ::: ::::::::::::::::: memory _ order _ seq _ cst :::: form ::: an :::::: inclusive ::::: chain :: of ::: such ::::::::: constraints, :::: from :::::: weakest :: to :::::::: strongest. :::::::::::::::::: memory _ order _ release

  atomic _ compare _ exchange generic functions Synopsis #include <stdatomic.h> _ Bool atomic _ compare _ exchange _ strong(A * object, C * expected, C desired); _ Bool atomic _ compare _ exchange _ strong _ explicit(A * object, C * expected, C desired, memory _ order success, memory _ order failure); _ Bool atomic _ compare _ exchange _ weak(A * object, C * expected, C desired); _ Bool atomic _ compare _ exchange _ weak _ explicit(A * object, C * expected, C desired, memory _ order success, memory _ order failure);

  exp = atomic _ load(&cur); do { des = function(exp); } while (!atomic _ compare _ exchange _ weak(&cur, &exp, des));

  as ::::: long ::: as ::: the ::::::::::: non-atomic ::::::: version :: of :::: the :::: type :::: can ::: be ::: the :::: left :::::::: operand ::of ::: the ::::::::::::: corresponding :::: op= :::::::::: compound ::::::::::: assignment.267) The key, operator, and computation correspon->> : :::: right ::::: shift 267):::Thus ::::: these :::::::: operations :: are ::: not ::::::: permitted ::: for :::::: pointers :: to ::::: atomic ::::::_ Bool, :::::bitwise :::::::: operations ::: are :: not :::::::: permitted :: for :::::: atomic :::::

  ::: (for ::::::::::::::: atomic _ fetch _ ::: key :::::::: variants) :: or ::::: after ::: the :::::: effects :::: (for :::::::: atomic _ :::

  larger :::: than :: for ::: the :::::: operator. : EXAMPLE 1 ::::::Provided :::: that ::: the ::::::::::: implementation ::::: allows :::: such :::: large ::::: array :::: sizes, : the atomic object. ::::::: following ::: use :: of :: the ::: += :::::: operator :: is :::: valid. ::::: Before ::: the ::::: generic ::::::: function ::: call, : a :::::::: conversion :: of ::::: large :: to :::::::: ptrdiff _ t ::: has :: to :: be :::::::: performed. :::: This ::: may :::: trap :::: before ::: the ::: call :: or ::: will ::: give :: an :::::::::::: implementation :::::: defined :::: result :::: that :::: differs :::: from ::: the :::::: operator :::::: version. : static const size _ t large = PTRDIFF _ MAX + 1ULL static unsigned char block[large+1]; static unsigned char * _ Atomic cp = block; cp += large; // valid, equivalent to cp = &block[large] atomic _ fetch _ add(&cp, large); // invalid EXAMPLE 2 :::::::: Performing :::::: integer :::::::: promotion :::::: instead :: of : a :::::::: conversion :: to ::: an ::::::: unsigned :::: type ::: can :::: have ::: the ::::: inverse ::::: effect :: of ::::::: narrowing ::: the :::::: possible ::::: range :: for ::: the :::::::: compound ::::::::: assignment. _ Atomic unsigned char one = 1; one += INT _ MAX; // invalid atomic _ fetch _ add(&one, INT _ MAX); // valid, equivalent to ((one = 0), 1) ::: Here ::: the :::::::::: intermediate :::: value :::::::: 1+INT _ MAX :::::::: overflows ::: and :::: either :::: traps :: or ::::::: provides :: an :::::::::::: implementation :::::: defined :::: value, ::::::: whereas ::the :::::::: argument ::

  function causes normal program termination to occur and control to be returned to the host environment. No functions registered by the atexit function, the at _ quick _ exit function, or signal handlers registered by the signal function are called. The status returned to the host environment is determined in the same way as for the exitfunction (7.22.4.4). Whether open streams with unwritten buffered data are flushed, open streams are closed, or temporary files are removed is implementation-defined.

9899:2017 :: 2x (E)

	::: diff :::::: marks -December 8, 2018	C2x CHANGES N2329
	or
	a = (a + (b + 32765));

  but the actual increment of p can occur at any time between the previous sequence point and the next sequence point (the ;), and the call to getchar can occur at any point prior to the need of its returned value.

	include <stdio.h>
	int sum;
	char * p; / * ... * / sum = sum * 10 -'0' + ( * p++ = getchar());
	the expression statement is grouped as if it were written as
	sum = (((sum * 10) -'0') + (( * (p++)) = (getchar())));

IEC 9899:2017 :: 2x (E) that

  later perform an acquire or consume operation on A. Relaxed atomic operations are not included as synchronization operations although, like synchronization operations, they cannot contribute to data races.

		::: diff :::::: marks -December 8, 2018	ISO/
	14	Environment	§ 5.1.2.4

  December 8, 2018 C2x CHANGES N2329 this shall be known as the value representation. The values of any padding bits are unspecified.56)

	type. § 6.2.6.2 Language ISO/IEC 9899:2017 :: 2x (E)

:::: ::: diff :::::: marks -

  D [ type-qualifier-list opt assignment-expression opt ] D [ type-qualifier-list opt assignment-expression ] D [ type-qualifier-list static assignment-expression ] D [ type-qualifier-list opt * ]

  The header <stdatomic.h> defines several macros and declares several types and functions for performing atomic operations on data shared between threads.261)

	7.17 Atomics <stdatomic.h>
	7.17.1 Introduction
	(7.22.4.5), the quick _ exit function (7.22.4.7).		_ Exit function
	7.14.2 Send signal
	7.14.2.1 The raise function
	Synopsis
	#include <signal.h>
	int raise(int sig);
	198	Library	§ 7.14.2.1

259)

If any signal is generated by an asynchronous signal handler, the behavior is undefined.

  the contents of the memory pointed to by object for equality with that pointed to by expected, and if true, replaces the contents of the memory pointed to by object with desired, and if false, updates the contents of the memory pointed to by expected with that pointed to by object. Further, if the comparison is true, memory is affected according to the value of success, and if the comparison is false, memory is affected according to the value of failure.

	ISO/IEC 9899:2017 :: 2x (E)	::: diff :::::: marks -December 8, 2018	C2x CHANGES N2329
	Atomically, compares These operations are atomic read-modify-write operations (5.1.2.4).
	NOTE 1 For example, the effect of atomic _ compare _ exchange _ strong is
	if (memcmp(object, expected, sizeof ( * object)) == 0) memcpy(object, &desired, sizeof ( * object)); else
	memcpy(expected, object, sizeof ( * object));
	§ 7.17.7.4	Library	211

::::::::: operation :::: than ::: the :::::::: success : argument.

2 The atomic _ flag _ clear generic functions Synopsis

  The return value true :::: true : corresponds to the set state and the return value false :::::false : corresponds to the clear state.

	7.17.8.

#include <stdatomic.h> void atomic _ flag _ clear(A * object); void atomic _ flag _ clear _ explicit(A * object, memory _ order order);

  The at _ quick _ exit function returns zero if the registration succeeds, nonzero if it fails.DescriptionThe exit function causes normal program termination to occur. No functions registered by the at _ quick _ exit function are called. If a program calls the exit function more than once, or calls the quick _ exit function in addition to the exit function, the behavior is undefined.

	N2329 C2x CHANGES	::: diff :::::: marks -December 8, 2018	ISO/IEC 9899:2017 :: 2x (E)
	Returns
	Forward references: the quick _ exit function (7.22.4.7).
	7.22.4.4 The exit function
	Synopsis
	#include <stdlib.h> _ Noreturn void exit(int status);
	214	Library	§ 7.17.8.2

  Each function is called as many times as it was registered, and in the correct order with respect to other registered functions.§ 7.22.4.6

	ISO/IEC 9899:2017 :: 2x (E)	::: diff :::::: marks -December 8, 2018	C2x CHANGES N2329
	7.22.4.6 The getenv function
	Synopsis
	#include <stdlib.h>
	char * getenv(const char * name);
	308) Library	263

  DescriptionThe quick _ exit function causes normal program termination to occur. No functions registered by the atexit function or signal handlers registered by the signal function are called. If a program calls the quick _ exit function more than once, or calls the exit function in addition to the quick _ exit function, the behavior is undefined. If a signal is raised while the quick _ exit function is executing, the behavior is undefined.

	7.22.4.7 The quick _ exit function
	Synopsis
	#include <stdlib.h> _ Noreturn void quick _ exit(int status);

::: diff :::::: marks -December 8, 2018 ISO/IEC 9899:2017 :: 2x (E)

::::::

imposes :::::::: constraints ::: that ::: are ::::::::: incompatible :::: with :::::::::::::::::: memory _ order _ consume ::: and :::::::::::::::::: memory _ order _ acquire, ::: and ::: that :: are ::::::: stronger :::

than :::::::::::::::::: memory _ order _ relaxed ::: and :::::: weaker ::: than :::::::::::::::::: memory _ order _ acq _ rel. :

Atomic read-modify-write operations shall always read the last value (in the modification order) stored before the write associated with the read-modify-write operation.

An atomic store shall only store a value that has been computed from constants and program input values by a finite sequence of program evaluations, such that each evaluation observes the values of variables as computed by the last prior assignment in the sequence. The ordering of evaluations in this sequence shall be such that -If an evaluation B observes a value computed by A in a different thread, then B does not happen before A.

-If an evaluation A is included in the sequence, then all evaluations that assign to the same variable and happen before A are also included. NOTE 4 The second requirement disallows "out-of-thin-air", or "speculative" stores of atomics when relaxed atomics are used. Since unordered operations are involved, evaluations can appear in this sequence out of thread order. For example, with x and y initially zero, // Thread 1: r1 = atomic _ load _ explicit(&y, memory _ order _ relaxed); atomic _ store _ explicit(&x, r1, memory _ order _ relaxed); // Thread 2: r2 = atomic _ load _ explicit(&x, memory _ order _ relaxed); atomic _ store _ explicit(&y, 42, memory _ order _ relaxed); is allowed to produce r1 == 42 && r2 == 42. The sequence of evaluations justifying this consists of: atomic _ store _ explicit(&y, 42, memory _ order _ relaxed); r1 = atomic _ load _ explicit(&y, memory _ order _ relaxed); atomic _ store _ explicit(&x, r1, memory _ order _ relaxed); r2 = atomic _ load _ explicit(&x, memory _ order _ relaxed);

On the other hand, // Thread 1: r1 = atomic _ load _ explicit(&y, memory _ order _ relaxed); atomic _ store _ explicit(&x, r1, memory _ order _ relaxed); // Thread 2: r2 = atomic _ load _ explicit(&x, memory _ order _ relaxed); atomic _ store _ explicit(&y, r2, memory _ order _ relaxed);

is not allowed to produce r1 == 42 && r2 == 42, since there is no sequence of evaluations that results in the computation of 42. In the absence of "relaxed" operations and read-modify-write operations with weaker than memory _ order _ acq _ rel ordering, the second requirement has no impact.

Recommended practice

The requirements do not forbid r1 == 42 && r2 == 42 in the following example, with x and y initially zero:

Returns

The atomic _ signal _ fence function returns no value.

Lock-free property

The atomic lock-free macros indicate the lock-free property of integer and address atomic :::::: atomic ::::::

integer :::: and ::::::: pointer types. A value of 0 indicates that the type is never lock-free; a value of 1 indicates that the type is sometimes lock-free; a value of 2 indicates that the type is always lock-free. NOTE 1 :: In ::::::: addition :: to :: the :::::::::::: synchronization :::::::: properties ::::::: between :::::: threads, ::: the ::::::: lock-free :::::: property :: of :: a ::: type ::::::: warrants :::: that ::::::::

operations :: are ::::::: perceived :::::::: indivisible :: in ::: the :::::: presence :: of :::::::: interrupts, ::: see ::::: 5.1.2.3.

Recommended practice

Operations that are lock-free should also be address-free. That is, atomic operations on the same memory location via two different addresses will communicate atomically. ::::::::::: synchronize. :: The implementation should not depend on any per-process ::::::::: execution :::::::::: dependent state. This restriction enables communication via memory mapped into a process :::::::::::::: synchronization ::: via :::::::: memory ::::: that :: is ::::::: mapped :::: into ::: an ::::::::: execution : more than once and memory shared between two processes :::::::::: concurrent ::::::::

program :::::::::: executions.

The atomic _ is _ lock _ free generic function Synopsis

Description

The atomic _ is _ lock _ free generic function indicates whether or not atomic operations on objects of the type pointed to by obj are lock-free.

Returns

The atomic _ is _ lock _ free generic function returns nonzero (true) if and only if atomic operations on objects of the type pointed to by the argument are lock-free. In any given program execution, the result of the lock-free query shall be consistent for all pointers of the same type. 264)

Atomic integer types

For : If ::: the ::::::::::: non-atomic ::::::: version ::: of ::: the :::::: direct :::: type :::::: exists, ::: for : each line in the following table, 265) the atomic type name is declared as a type that has the same representation and alignment requirements as the corresponding direct type. 266) 264) obj can be a null pointer. 265) See "future library directions" (7.31.8). 266) The same representation and alignment requirements are meant to imply interchangeability as arguments to functions, return values from functions, and members of unions. § 7.17

Recommended practice

2

The representation of an atomic integer type is not required to have the same size as the corresponding regular :::::::::: non-atomic ::::::: version ::: of ::: the ::::: direct : type but it should have the same size whenever possible, as it eases effort required to port existing code. : It :: is :::::::::::::: recommended :::: that ::: the ::::::: atomic ::::

type ::::: name ::::::: defines ::::::: exactly ::: the :::::::::::::: corresponding ::::: direct ::::: type. :

Operations on atomic types

1 There are only a few kinds of :: In :::::::: addition :: to :::: the operations on atomic types, though there are many instances of those kinds :::::: objects :::: that :::: are ::::::::: described :: by :::::::::: operators, ::::: there ::: are : a :::: few :::::: kinds :: of :::::::::: operations :::

that :::: are :::::::: specified :: as ::::::: generic ::::::::: functions. This subclause specifies each general kind ::::::: generic :::::::: function.

:::::

After :::::::::: evaluation :: of ::: its ::::::::::: arguments, ::::: each :: of :::::: these ::::::: generic ::::::::: functions :::::: forms : a :::::: single :::::: read, ::::: write ::: or ::::::::::::::::

read-modify-write ::::::::: operation ::::: with ::::: same ::::::: general :::::::::: properties :: as ::::::::: described :: in :::::: 5.1.2.4 :::: and :::::: 6.2.6.

Description

The thrd _ detach function tells the operating system to dispose of any resources allocated to the thread identified by thr when that thread terminates. The thread identified by thr shall not have been previously detached or joined with another thread.

Returns

The thrd _ detach function returns thrd _ success on success or thrd _ error if the request could not be honored.

The

Description

The thrd _ equal function will determine whether the thread identified by thr0 refers to the thread identified by thr1.

Returns

The thrd _ equal function returns zero if the thread thr0 and the thread thr1 refer to different threads. Otherwise the thrd _ equal function returns a nonzero value.

Description

For every thread-specific storage key which was created with a non-null destructor and for which the value is non-null, thrd _ exit sets the value associated with the key to a null pointer value and then invokes :::: calls : the destructor with its previous value. The order in which destructors are invoked is unspecified. ::::: These :::::::::: destructor :::: calls ::: are ::::::::::::::: indeterminately :::::::::: sequenced. :

If after this process there remain keys with both non-null destructors and values, the implementation repeats this process up to TSS _ DTOR _ ITERATIONS times.

Following this, the thrd _ exit function terminates execution of the calling thread and sets its result code to res. The program terminates normally after the last thread has been terminated. The behavior is as if the program called the exit function with the status EXIT _ SUCCESS at thread termination time.

Returns

The thrd _ exit function returns no value. and the same names suffixed with f or l may be added to the declarations in the <complex.h> header.

Character handling <ctype.h>

Function names that begin with either is or to, and a lowercase letter may be added to the declarations in the <ctype.h> header.

Errors <errno.h>

Macros that begin with E and a digit or E and an uppercase letter may be added to the macros defined in the <errno.h> header.

Floating-point environment <fenv.h>

Macros that begin with FE _ and an uppercase letter may be added to the macros defined in the <fenv.h> header.

Format conversion of integer types <inttypes.h>

Macros that begin with either PRI or SCN, and either a lowercase letter or X may be added to the macros defined in the <inttypes.h> header.

Localization <locale.h>

Macros that begin with LC _ and an uppercase letter may be added to the macros defined in the <locale.h> header.

Signal handling <signal.h>

Macros that begin with either SIG and an uppercase letter or SIG _ and an uppercase letter may be added to the macros defined in the <signal.h> header.

Atomics <stdatomic.h>

Macros that begin with ATOMIC _ and an uppercase letter may be added to the macros defined in the <stdatomic.h> header. Typedef names that begin with either atomic _ or memory _ , and a lowercase letter may be added to the declarations in the <stdatomic.h> header. Enumeration constants that begin with memory _ order _ and a lowercase letter may be added to the definition of the memory _ order type in the <stdatomic.h> header. Function names that begin with atomic _ and a lowercase letter may be added to the declarations in the <stdatomic.h> header.

The macro ATOMIC _ VAR _ INIT ::::::::: possibility :::: that ::: an :::::: atomic ::::: type ::::: name :: of ::: an :::::: atomic ::::::: integer :::: type ::::::: defines : a :::::::: different ::::: type :::: than ::: the :::::::::::::: corresponding ::::: direct ::::: type is an obsolescent feature.

Boolean type and values <stdbool.h>

The ability to undefine and perhaps then redefine the macros bool, true, and false is an obsolescent feature.

Integer types <stdint.h>

Typedef names beginning with int or uint and ending with _ t may be added to the types defined in the <stdint.h> header. Macro names beginning with INT or UINT and ending with _ MAX, _ MIN, § 7.31.10 Library