I used to think all reentrant functions are thread-safe. But I read Reentrancy page in Wiki, it posts code that is "perfectly reentrant, but not thread-safe. because it does not ensure the global data is in a consistent state during execution"
int t;
void swap(int *x, int *y)
{
int s;
s = t; // save global variable
t = *x;
*x = *y;
// hardware interrupt might invoke isr() here!
*y = t;
t = s; // restore global variable
}
void isr()
{
int x = 1, y = 2;
swap(&x, &y);
}
I don't understand its explanation. Why is this function not thread-safe? Is it because the global variable int t
will be changed during threads execution?
The trick with this type of reentrancy is that the execution of the first call stops while the second call is executed. Just like a subfunction call. The first call continues after the second call completely finished. Because the function saves the state of t at entry and restores it at exit, nothing has changed for the first call when it continues. Therefore you always have a defined and strict order of execution, no matter where exactly the first call is interrupted.
When this function runs in multiple threads, all executions are done in parallel, even in true parallel with a multicore CPU. There is no defined order of execution over all threads, only within a single thread. So the value of t can be changed at any time by one of the other threads.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With