<html>

<head>
<meta http-equiv="Content-Language" content="en-us">
<meta name="GENERATOR" content="Microsoft FrontPage 5.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<title>Thread-Safety in the Standard Libary</title>
</head>

<body>

<p>Doc. no.&nbsp;&nbsp; 
N2669=08-0179<br>
Date:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%Y-%m-%d" startspan -->2008-06-13<!--webbot bot="Timestamp" endspan i-checksum="12409" --><br>
Project:&nbsp;&nbsp;&nbsp;&nbsp; Programming Language C++<br>
Reply to:&nbsp;&nbsp; Beman Dawes &lt;bdawes at acm.org&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
Peter Dimov &lt;pdimov at pdimov.com&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
Herb Sutter &lt;hsutter at microsoft.com&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Hans Boehm &lt;Hans.Boehm at hp.com&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Lawrence Crowl &lt;crowl at google.com&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Paul E. McKenney &lt;paulmck at linux.vnet.ibm.com&gt;<span style="background-color: rgb(255, 255, 0)"><br>
</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
Jeffrey Yasskin &lt;jyasskin at google.com&gt;</p>

<h1>Thread-Safety in the Standard Library (Rev 2)</h1>

<p><a href="#Executive-summary">Executive summary</a><br>
<a href="#Introduction">Introduction</a><br>
<a href="#Rationale">Rationale</a><br>
<a href="#Existing-practice">Existing practice</a><br>
<a href="#Proposed-Wording">Proposed wording</a><br>
<a href="#Revision-history">Revision history</a><br>
<a href="#References">References</a></p>

<h2><a name="Executive-summary">Executive summary</a></h2>
<blockquote>

<p align="left">Unless otherwise specified,  standard library classes may safely 
be instantiated from multiple threads and standard library functions are reentrant, 
but non-const use of objects of standard library types 
is not safe if shared between threads. Use of non-constness 
to determine thread-safety requirements ensures consistent thread-safety 
specifications without having to add additional wording to each and every 
standard library type.</p>
</blockquote>
<h2><a name="Introduction">Introduction</a></h2>
<p>With the introduction of multi-threading into the C++ standard, the contract 
between standard library users and implementers needs to explicitly state the 
conditions under which standard library components are or are not thread-safe.</p>
<h2><a name="Rationale">Rationale</a></h2>
<p>The objective is to offer users of the standard library as much thread-safety 
as is possible without impacting performance or creating an illusion of <u>
<font color="#228822">thread-</font></u>safety 
where none exists.</p>
<h3>Basic thread-safety guarantee</h3>
<p align="left">The basic thread-safety guarantee&nbsp; would be that standard library functions are required to be 
reentrant, and non-mutating uses of objects of standard library types are 
required to not introduce data races. This has little or no impact on performance. 
It  does actually deliver the promised safety. Thus this basic thread-safety 
guarantee is 
required of implementations.</p>
<h3>Strong thread-safety guarantee</h3>
<p align="left">The strong thread-safety guarantee would be that mutating uses of objects of 
standard library types are required to not introduce data races. This would have a severe negative 
impact on performance. Furthermore, real safety often requires locking across several 
member function calls, so providing per function-call locking would 
create a illusion of safety that did in fact not exist. For these reasons, a blanket strong thread-safety 
guarantee for 
mutating 
shared objects is not provided, and constraints are put on programs 
accordingly.</p>
<h3>Meaning of <i>thread-safety</i></h3>
<p>The proposed wording 
talks in terms of data races and expression evaluation conflicts. <i>Data races</i> 
and <i>expression evaluation conflicts</i> are defined in the core language 
portion of the standard, so do 
not need to be further described in the library clauses.</p>
<h3>Standard library components not given strong guarantee</h3>
<p>Consideration was given to specifying rand function and the global locale 
objects on a per-thread basis. That is not required because it does not 
represent existing practice. Mac OS X, for example, does not support per-thread 
global locale objects.</p>
<h2><a name="Existing-practice">Existing practice</a></h2>
<p>As far as is known, the proposed wording reflects existing practice in 
current implementations of the standard library.</p>
<h2><a name="Proposed-Wording">Proposed Wording</a></h2>
<p><i>Add a new paragraph after 17.4 Library-wide requirements [requirements] 
paragraph 1:</i></p>
<blockquote>
<p>Requirements specified in terms of interactions 
between threads do not apply to programs having only a single thread of 
execution.</p>
</blockquote>
<p><i>Change 17.4.4 Conforming implementations [conforming] as indicated:</i></p>
<blockquote>
<p>This subclause describes the constraints upon, and latitude of, 
implementations of the C++ Standard library. The following subclauses describe 
an implementations use of headers (17.4.4.1), macros (17.4.4.2), global 
functions (17.4.4.3), member functions (17.4.4.4), <font color="#FF0000">
<strike>reentrancy</strike></font> 
<font color="#228822"><u>data race avoidance </u></font>(17.4.4.5), access specifiers (17.4.4.6), class derivation (17.4.4.7), 
and&nbsp; exceptions (17.4.4.8).</p>
</blockquote>
<p><i>Change 17.4.4.5 Reentrancy [reentrancy] from: </i> </p>
<blockquote>
<p>17.4.4.5 Reentrancy [reentrancy]</p>
<p>Which of the functions in the C++ Standard Library are not <i>reentrant 
subroutines</i> is implementation-defined.</p>
</blockquote>
<p><i>To:</i></p>
<blockquote>
  <p>17.4.4.5 Data race avoidance [res.on.data.races]</p>
  <p>This subclause specifies requirements implementations shall meet to prevent 
  data races ([intro.multithread]). Each requirement applies to all
  <span class="nfakPe">standard</span> <span class="nfakPe">library</span> 
  functions unless otherwise specified.&nbsp; Implementations are 
  permitted but not required to prevent data races in cases other than those 
  specified below.</p>
  <p>C++ Standard Library 
  functions shall be <i>reentrant subroutines</i>.</p>
  <p>A C++ <span class="nfakPe">Standard</span> <span class="nfakPe">library</span> 
  function shall not directly or indirectly access objects ([intro.multithread]) 
  accessible by threads other than <span class="nfakPe">the</span> current
  <span class="nfakPe">thread</span> unless <span class="nfakPe">the</span> 
  objects are accessed directly or indirectly via <span class="nfakPe">the</span> 
  function's arguments, including <code>this</code>.</p>
  <p>A C++ <span class="nfakPe">Standard</span> <span class="nfakPe">library</span> 
  function shall not directly or indirectly modify objects ([intro.multithread]) 
  accessible by threads other than <span class="nfakPe">the</span> current
  <span class="nfakPe">thread</span> unless <span class="nfakPe">the</span> 
  objects are accessed directly or indirectly via <span class="nfakPe">the</span> 
  function's non-const arguments, including <code>this</code>.</p>
  <p><i>[Note:</i> This  means, for example, that 
  implementations can't use a static object for internal purposes without 
  synchronization because it could cause a data race even in programs that do 
  not explicitly share objects between threads.<i> --end note] </i></p>
  <p>Implementations are permitted to share their own internal objects between 
  threads if <span class="nfakPe">the</span> objects are not visible to users 
  and are protected against data races.</p>
<p>Unless otherwise specified, C++ Standard Library 
functions shall perform all operations with effects visible ([intro.multithread]) 
to users&nbsp; solely within the 
current thread.<br>
<br>
<i>[Note:</i> This allows implementations to parallelize operations if there are 
no visible side effects. <i>--end note]</i></p>
</blockquote>
<p><i>Somewhere in [constraints] add a constraint on programs: </i> </p>
<blockquote>
  <p>It is undefined behavior if calls to standard library functions from 
  different threads:</p>
  <ul>
    <li>share access to an object directly or indirectly via their arguments, 
    including <code>this</code>, and</li>
    <li>at least one of the arguments accessing a shared object is non-const, 
    and</li>
    <li>one call does not happen before the other ([intro.multithread]).</li>
  </ul>
  <p><i>[Note: </i>This prohibition against concurrent non-const access means that 
  modifying an object of a standard library type shared between threads 
  without using a locking mechanism may result in a data race. <i>
  --end note]</i></p>
</blockquote>
  <p><i>To 18.5.1 Storage allocation and deallocation [new.delete], add:</i></p>
<blockquote>
  <p>The library versions of operator <code>new</code> and <code>delete</code>, 
  user replacement versions of global replacement operator <code>new</code> and
  <code>delete</code>, and the Standard C library functions <code>calloc</code>,
  <code>malloc</code>, <code>realloc</code>, and <code>free</code> shall 
  not introduce data races ([intro.multithread]) 
  as a result of concurrent calls from different threads.&nbsp;Calls to these functions that allocate or deallocate a particular unit of storage shall occur in a single total order, 
  and each such deallocation call shall happen before the next allocation (if any) in 
  this order.</p>
</blockquote>
  <p><i>To 19.3 Error numbers [errno] paragraph 1, add:</i></p>
<blockquote>
  <p> A separate <code>errno</code> 
  value shall be provided for each thread.</p>
</blockquote>
  <p><i>To 20.6.1 The default allocator [default.allocator], add:</i></p>
  <blockquote>
  <p>Except for the destructor, member functions of the default allocator shall 
  not introduce data races ([intro.multithread]) 
  as a result of concurrent calls to default allocator object's member functions from different threads.&nbsp;Calls 
  to these functions that allocate or deallocate a 
  particular unit of storage shall occur in a single total order, and each such deallocation call shall happen before the next allocation (if any) in this order.</p>
  </blockquote>
  <p><i>To 20.7 Date and Time [date.time], add:</i></p>
  <blockquote>
  <p>Functions <code>asctime</code><span class="q">,
  </span><code>ctime</code><span class="q">, </span><code>gmtime</code><span class="q">, 
  and </span><code>localtime</code> are not required to avoid data races ([res.on.data.races]).</p>
  </blockquote>
  <p><i>To 21.4 Null-terminated sequence utilities [c.strings], add:</i></p>
  <blockquote>
    <p>Functions <code>
    strerror</code> and <code>strtok</code> are not required to avoid data races ([res.on.data.races]).</p>
  </blockquote>
  <p><i>To 22.1.1 Class locale [locale], add a new paragraph at the end:</i></p>
  <blockquote>
  <p>Whether there is one global locale object for the 
  entire program or one global locale object per thread is implementation 
  defined. Implementations are encouraged but not required to provide one global 
  locale object per thread. If there is a single global locale object for the 
  entire program, implementations are not required to avoid data races on it ([res.on.data.races]).</p>
  </blockquote>
  <p><i>At a location in 23 to be determined by the project editor, add a new paragraph:</i></p>
  <blockquote>
  <p>For purposes of avoiding data races ([res.on.data.races]), 
  implementations shall consider the following functions to be const:<code> 
  begin</code>, <code>end</code>, <code>rbegin</code>, <code>rend</code>, <code>
  front</code>, <code>back</code>, <code>data</code>, <code>find</code>, <code>
  lower_bound</code>, <code>upper_bound</code>, <code>equal_range</code>, and, 
  except in associative containers, <code>operator[]</code>.</p>
  </blockquote>
  <blockquote>
  <p>Notwithstanding ([res.on.data.races]), implementations are required to 
  avoid data races when the contents of the contained object in different elements in the same sequence are modified 
  concurrently.</p>
  <p><i>[Example: </i>For a <code>vector&lt;int&gt; x
  </code>with a size greater than one, <code>x[1] = 5</code> 
  and <code>*x.begin() = 10</code> can be executed concurrently without a data race, but 
  <code>x[0] 
  = 5</code> and <code>*x.begin() = 10</code> executed concurrently may result in a data race. <i>-- 
  end example]</i></p>
  </blockquote>
  <p><i>Change 26.7 C Library [c.math] paragraph 6 as indicated:</i></p>
  <blockquote>
    <p>The <code>rand</code> function has the semantics specified in the C 
    standard, except that the implementation may specify that particular library 
    functions may call <code>rand</code>. It is implementation defined whether or not the
    <code>rand</code> function may introduce data races ([res.on.thread.safety]).</p>
    <p>[<i>Note:</i> The random number generation ([rand]) facilities in this 
    standard are often preferable to <code>rand</code>. <i>--end note</i>]</p>
</blockquote>
  <h2><a name="Revision-history">Revision history</a></h2>
  <p>N2669 - Revision 2:</p>
  <ul>
    <li>Strike &quot;or other undesirable behavior&quot;. Data races are the only case we 
    can thing of, so mention them only.</li>
    <li>Include user supplied global operator new and delete, and the C library 
    memory allocation functions in the prohibition against allocation data 
    races.</li>
    <li>Specify when library implementations may or may not multithread.</li>
    <li>Acknowledge N2519.</li>
    <li>Add additional authors.</li>
    <li>Numerous other changes.</li>
</ul>
  <p>N2410 - Revision 1:</p>
  <ul>
    <li>Provided <a href="#Executive-summary">Executive summary</a>.</li>
    <li>Simplified wording.</li>
    <li>Added wording to cover both direct (i.e. shallow) and indirect (i.e. deep) 
    access.</li>
    <li>Removed mention of deadlocks as unnecessary.</li>
    <li>Added expression evaluation conflict wording as more precise, and well 
    defined by the <i>Multi-threaded executions and data races</i> wording from 
    N2334.</li>
    <li>Added strong exception safety for the default allocator.</li>
    <li>Struck *_r functions from proposal.</li>
</ul>
  <p>N2298 - Initial version.</p>
  <h2><a name="References">References</a></h2>
  <p>
  <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2429.htm">
  N2429</a>, Concurrency memory model (final revision), Clark Nelson and Hans-J. 
  Boehm</p>
  <p>
  <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2480.html">
  N2480</a>, A Less Formal Explanation of the Proposed C++ Concurrency Memory 
  Model, Hans-J. Boehm</p>
  <p>
  <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2519.html">
  N2519</a>, Library thread-safety 
  from a user's point of view, with wording, Jeffrey Yasskin</p>
  <p>
  <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1947.pdf">
  N1947</a>, The Memory Model and the C++ Library, Non-Memory Actions etc., Nick 
  Maclaren</p>
<hr>
  
</body>

</html>