This document proposes to allow implementations to use thread storage duration for the internal state used by the pseudo-random number generator functions and the multibyte/wide conversion functions. It is related to papers N2225, N2226, N2228.
The core observation which motivates this document is that while the standard does not require to detect data races for the affected functions, it does rule out an implementation based on internal state objects with thread storage duration. The reason is that a strictly conforming program can use external synchronization and call these functions from different threads. With internal objects of thread storage duration, the lack of global state sharing would be observable.
	  Many libraries which are thread-aware (because they use
	  synchronization primitives or even create threads
	  themselves) still call rand, which introduces
	  data races.  One way to fix all these libraries is to give
	  the random number generator state optional thread storage
	  duration.
	
Another option would be to encourage implementations to avoid data races, either by using locks or atomic memory accesses internally. However, historically, some benchmarks are quite dependent on random number generator performance, so this change might not be desirable to implementors. The implementation in the GNU C library uses a lock.
	  POSIX suggests the possiblity of a thread-safe
	  implementation of rand and srand,
	  but does not voice any preference for per-thread state or
	  synchronized access to the global state.
	
	  Likewise, the multibyte/wide character and string conversion
	  functions use internal state if the ps argument
	  is a null pointer. For these functions, eliminating the data
	  race would still leave a semantic race condition because the
	  state needs to remain consistent between subsequent calls of
	  these functions.
	
The proposal is to give permission to assign thread storage duration to the internal state. The functions have error return values, so the necessary storage could even be allocated dynamically, on demand, to avoid penalizing programs which use an explicit conversion state argument.
	  A simpler approach would make it undefined to call the
	  conversion functions from a multi-threaded program (similar
	  to what the signal function does today).
	
POSIX suggests that a thread-safe implementation of these functions is possible, but does not go into details. It does not discuss the ability of strictly conforming programs to discover whether the hidden internal state has thread storage duration or not.
rand function), add:
	
	  The rand function is not required to avoid data
	  races with other calls to pseudo-random sequence generation functions.
	  
	    It is implementation-defined whether the internal random
	    number generator state has thread storage duration, and if
	    a newly created thread continues the same sequence of
	    random numbers as the current thread, or if starts again
	    based on the specified seed.
	  
	
	In 7.22.2.2 (The rand function), change:
	If the pseudo-random number generator state has thread-storage duration, theIn J.3.12 (Library functions), add:srandfunction affects subsequent results of therandfunction called by the current thread. Otherwise, theThesrandfunction is not required to avoid data races with other calls to pseudo-random sequence generation functions.
— Whether the random number generator state has thread storage duration, and its initial state in a newly created thread (7.22.2.1, 7.22.2.2).
IfIn 7.29.6.4 (Restartable multibyte/wide string conversion functions), add:psis a null pointer, each function uses its own internalmbstate_tobject instead, which is initialized at program startup to the initial conversion state; the functions are not required to avoid data races with other calls to the same function in this case. It is implementation-defined whether the internalmbstate_tobject has thread-storage definition, and whether a newly created thread has the same state has the current thread at the time of creation, or the initial conversion state. The implementation behaves as if no library function calls these functions with a null pointer forps.
IfIn J.3.12 (Library functions), add:psis a null pointer, each function uses its own internal mbstate_t object instead, which is initialized at program startup to the initial conversion state; the functions are not required to avoid data races with other calls to the same function in this case. It is implementation-defined whether the internalmbstate_tobject has thread-storage definition, and whether a newly created thread has the same state has the current thread at the time of creation, or the initial conversion state. The implementation behaves as if no library function calls these functions with a null pointer forps.
	  — Whether the internal mbstate_t
	  object has thread-storage duration, and its initial value in
	  a newly created thread (7.28.1, 7.29.6.4).