I found some code in FreeRTOS (FreeRTOSV7.4.0\FreeRTOS\Source\tasks.c):
void vTaskSuspendAll( void )
{
/* A critical section is not required as the variable is of type
portBASE_TYPE. */
++uxSchedulerSuspended;
}
It is explicitly said no need to protect due to the type is "portBASE_TYPE", which is a "long" type. My understood is that it assumes the self-increment to this type is atomic. But after I disassembled it I could not find any proof, its a plain load->add->store. Then is it a problem?
void vTaskSuspendAll( void )
{
/* A critical section is not required as the variable is of type
portBASE_TYPE. */
++uxSchedulerSuspended;
4dc: 4b03 ldr r3, [pc, #12] ; (4ec <vTaskSuspendAll+0x10>)
4de: f8d3 2118 ldr.w r2, [r3, #280] ; 0x118
4e2: 1c50 adds r0, r2, #1
4e4: f8c3 0118 str.w r0, [r3, #280] ; 0x118
4e8: 4770 bx lr
4ea: bf00 nop
4ec: 00000000 .word 0x00000000
000004f0 <xTaskGetTickCount>:
return xAlreadyYielded;
}
++ is not defined as thread-safe.
If you have multiple threads increment or decrementing a variable using the increment or decrement operators, you may not get the desired result. These operators are not thread-safe. Imagine two threads that increment a variable.
The InterlockedIncrement function both increments (increases by one) the value of the specified 32-bit variable and checks the resulting value. The function prevents more than one thread from using the same variable simultaneously.
Short answer: no. Long answer: generally not. While CPython's GIL makes single opcodes thread-safe, this is no general behaviour. You may not assume that even simple operations like an addition is a atomic instruction.
It's not atomic, as you've documented. But it could still be "thread safe" in a less strict sense: a long
can't be in an inconsistent state. The extent of the danger here is that if n
threads call vTaskSuspendAll
then uxSchedulerSuspended
will be incremented by anywhere between 1 and n
.
But this could be perfectly fine if the variable is something that doesn't need to be perfect, like a tracker for how many times the user asked to suspend. There's "thread safe" meaning "this operation produces the same result, no matter how its calls are interleaved" and there's "thread safe" meaning "nothing explodes if you call this from multiple threads".
No, incrementing values in C is not guaranteed to be atomic. You need to provide synchronization, or use a system-specific library to perform atomic increments/decrements.
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