Doc. no. N2298=07-0158
Project: Programming Language C++
Reply to: Beman Dawes <bdawes at acm.org>
Peter Dimov <pdimov at pdimov.com>
Herb Sutter <hsutter at microsoft.com>
With the introduction of multi-threading into the C++ standard, the contract between standard library users and implementors needs to explicitly state the conditions under which standard library components are or are not thread-safe.
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 safety where none exists.
Guaranteeing thread-safety for non-shared objects has little or no impact on performance. It actually does deliver the promised safety. Thus this basic thread-safety is required of implementations.
Guaranteeing thread-safety for shared objects 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, strong thread-safety for shared objects is not specified, and constraints are put on programs accordingly.
Rather than try to define the term thread-safety, the proposed wording simple talks about data races and deadlocks. These terms will be defined in the core language portion of the standard, and/or are well-know terms of art that do not need to be further described in the library clauses.
Consideration was given to specifying rand function and the global locale objects on a per-thread basis. That is not proposed because it does not represent existing practice. Mac OS X, for example, does not support per-thread global locale objects.
As far as is known, the proposed wording reflects existing practice in current implementations of the standard library.
Somewhere in [conforming] add a constraint on implementations:
Unless otherwise specified, access to different objects of types supplied by the standard library from different threads-of-execution shall not result in a data race or deadlock.
[Note: This means, for example, that implementations can't use a private static data member in a standard library class without synchronization because it could cause a data race or deadlock even in programs that do not share objects of that class between threads. --end note]
Unless otherwise specified, calls to standard library functions from different threads-of-execution shall not result in a data race or deadlock if the calls do not access non-const objects shared between the threads [constraints].
[Note: This means, for example, that implementations can't use a static object without synchronization for internal purposes because it could cause a data race or deadlock even in programs that do not explicitly share objects between threads. --end note]
Somewhere in [constraints] add a constraint on programs:
Unless otherwise specified, access to the same object of a standard library type from different threads-of-execution results in undefined behavior if any of the accesses are via a non-const member function of the object or non-const function parameter of any standard library function, and simultaneous access is not prevented by a standard library supplied locking mechanism ([Editor to supply reference]).
[Note: This lack of strong thread-safety guarantee means that sharing an object of a standard library type between threads without using a locking mechanism may result in a data race, deadlock, or other undesirable behavior. --end note]
Add to 19.3 Error numbers [errno] paragraph 1:
errnovalue shall be provided for each thread-of-execution.
Change 20.7 Date and Time [date.time] as indicated:
The contents are the same as the Standard C library header
<time.h>with the addition of the functions
localtime_ras in the POSIX header
localtimeare not require to be thread-safe ([conforming]).
Change 21.4 Null-terminated sequence utilities [c.strings] as indicated:
The contents of these headers shall be the same as the Standard C Library headers <ctype.h>, <wctype.h>,
<string.h>, <wchar.h>, and <stdlib.h> and the C Unicode TR header <uchar.h>, respectively, with the following
<cstring>includes the functions
strtok_ras in the POSIX header
strtokfunctions are not require to be thread-safe ([conforming]).
The headers shall not define the types char16_t, char32_t, and wchar_t (2.11).
Change 26.7 C Library [c.math] paragraph 5 and 6 as indicated:
The contents of these headers are the same as the Standard C library headers
with the following changes:
<cstdlib>includes the function
rand_ras in the POSIX header
randfunction has the semantics specified in the C standard, except that the implementation may specify that particular library functions may call
randfunction is not require to be thread-safe ([conforming]).
N1947, The Memory Model and the C++ Library, Non-Memory Actions etc., Nick Maclaren