asctime(), localtime(), strtok()
These functions are all
thread-unsafe. Each contains a static buffer that might be overwritten
by another thread between a call to the function and the subsequent
use of its return value.
Arm supplies reentrant
Arm recommends that you use
these functions instead to ensure safety.
Note These reentrant versions take additional parameters.
_asctime_r() takes an additional parameter that is a
pointer to a buffer that the output string is written into.
_localtime_r() takes an additional parameter that is a
pointer to a
struct tm, that the result is
_strtok_r() takes an additional
parameter that is a pointer to a
char pointer to the next token.
gamma(), lgamma(), lgammaf(), lgammal() a
|These extended mathlib functions
use a global variable, _signgam, so are not thread-safe.
mbrlen(), mbsrtowcs(), mbrtowc(), wcrtomb(), wcsrtombs()
The C90 multibyte conversion functions (defined in stdlib.h) are not thread-safe, for example
mbtowc(), because they
contain internal static state that is shared between all threads without
However, the extended restartable
versions (defined in wchar.h) are thread-safe,
provided you pass in a pointer to your own mbstate_t object.
You must exclusively use these functions with non-NULL mbstate_t
* parameters if you want to ensure thread-safety when
handling multibyte strings.
These functions keep internal
state that is both global and unprotected. This means that calls
rand() are never thread-safe.
Arm recommends that you do
one of the following:
Use the reentrant versions
_srand_r() supplied by Arm. These use user-provided
buffers instead of static data within the C library.
Use your own locking to ensure that only one thread
rand() at a time, for example, by
$Sub$$rand() if you want to avoid
changing your code.
Arrange that only one thread ever needs to generate
Supply your own random number generator that can
have multiple independent instances.
_srand_r() both take an additional parameter that
is a pointer to a buffer storing the state of the random number generator.
used for setting and reading locale settings. The locale settings
are global across all threads, and are not protected by a lock.
If two threads call
setlocale() to simultaneously
modify the locale settings, or if one thread reads the settings
while another thread is modifying them, data corruption might occur.
Also, many other functions, for example
read the current locale settings. Therefore, if one thread calls
with another thread calling such a function, there might be unexpected
Multiple threads reading the
settings simultaneously is thread-safe in simple cases and if no
other thread is simultaneously modifying those settings, but where internally
an intermediate buffer is required for more complicated returned
results, unexpected results can occur unless you use a reentrant
Arm recommends that you
Choose the locale
you want and call
setlocale() once to initialize
it. Do this before creating any additional threads in your program
so that any number of threads can read the locale settings concurrently
without interfering with one another.
Use the reentrant version
supplied by Arm. This
returns a string that is either a pointer to a constant string, or a pointer
to a string stored in a user-supplied buffer that can be used for thread-local
storage, rather than using memory within the C library. The buffer must be at
_SETLOCALE_R_BUFSIZE bytes long,
including space for a trailing
Be aware that
_setlocale_r() is not fully thread-safe when accessed concurrently
to change locale settings. This access is not lock-protected.
Also, be aware that
localeconv() is not
thread-safe. Call the Arm
_get_lconv() with a pointer to a
user-supplied buffer instead.