| |||
| Home > The C and C++ Libraries > Writing reentrant and thread-safe code > Thread-safety in the ARM C libraries | |||
In the ARM libraries, functions can be thread-safe as follows:
Some functions are never thread-safe, for example setlocale().
Some functions are always thread-safe, for example fopen().
Other functions are only thread-safe if you pass
the appropriate arguments, for example tmpnam().
Threading problems might occur when your application makes use of the ARM libraries in a way that is hidden, for example, if you are using the language helper functions. Integer divide uses a helper function because there is no divide instruction in the ARM instruction set. Integer division by zero throws a signal by default, so you must either:
re-implement __rt_raise() to
deal with the signal in a thread-safe manner
re-implement __aeabi_idiv0 so
that division by zero returns some standard result (such as 0)
rather than raising a signal.
For details on which C library functions are thread-safe and when, see:
Table 5.1 shows those C library functions that are thread-safe.
Table 5.1. Functions that are thread-safe
| Functions | Description |
|---|---|
calloc(), free(), malloc(), realloc() | The heap functions are thread-safe. A single heap is shared between all threads, and mutexes are used to avoid data corruption when there is concurrent access. Each heap implementation is responsible for doing its own locking. If you supply your own allocator, it must also do its own locking. This enables it to do fine-grained locking, if required, rather than simply protecting the entire heap with a single mutex (coarse-grained locking). |
| The The NoteBe aware that the |
abort(), raise(), signal()
fenv.h functions | The ARM signal handling functions and FP exception traps are thread-safe. The settings for
signal handlers and FP traps are global across the entire process
and are protected by locks. Data corruption does not occur if multiple
threads call |
| The Each individual stream is protected
by a lock, so two threads can each open their own If two
threads both want to read or write the same stream, locking at the NoteBe aware that |
| When using these functions:
|
| clock() contains static
data that is written once at program startup and then only ever
read. Therefore, clock() is thread-safe provided
no extra threads are already running at the time that the library
is initialized. |
|
Each
thread has its own |
atexit() | The list of exit functions maintained
by In the worst case, if more than one thread
calls |
| These functions are thread-safe. |
| Although |
| These use SWIs that communicate with the ARM debugging environments. Typically, you have to re-implement these for a real-world application. |
| When using these functions, the string-based functions read the locale settings. Typically, they are thread-safe. However, if you change locale in mid-session, you should ensure that these functions are not affected. The string-based functions, such as |
stdin, stdout, stderr | These are thread-safe. |
The FP status word is safe to use in a multithreaded environment,
even in software floating-point. Here, a status word for each thread
is stored in its own __user_perthread_libspace block.
Be aware that, in hardware floating-point, the FP status word is stored in a VFP register. In this case, your thread-switching mechanism must keep a separate copy of this register for each thread.
Table 5.2 shows the C library functions that are not thread-safe.
Table 5.2. Functions that are not thread-safe
| Functions | Description |
|---|---|
| The locale settings are global across
all threads, and are not protected by a lock. If two threads call ARM recommends that you choose the locale you want
and call Be aware that |
| 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 versions, NoteThese reentrant versions take additional parameters that are pointers to a char pointer to the next token. |
gamma(), lgamma() | These extended mathlib functions, defined in math.h, use
a global variable, signgam, and so are not thread-safe.
ARM recommends that you use gamma_r() and lgamma_r() instead.
These write the sign of the result into memory pointed to by a supplied int
* argument. |
| The C89 multibyte conversion functions
(defined in However, the extended restartable
versions (defined in |
exit() | Do not call In this case, |
rand(), srand() | These functions keep internal state that
is both global and unprotected. This means that calls to ARM recommends that you use your own locking
to ensure that only one thread ever calls Alternatively, do one of the following:
|