Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is self increment in C thread safe?

Tags:

c

freertos

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;
}
like image 260
user1603164 Avatar asked Mar 20 '13 01:03

user1603164


People also ask

Is ++ thread-safe in C?

++ is not defined as thread-safe.

Is incrementing 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.

What is interlocked increment?

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.

Is += atomic in Python?

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.


2 Answers

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".

like image 121
Nathaniel Waisbrot Avatar answered Nov 03 '22 08:11

Nathaniel Waisbrot


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.

like image 34
Sergey Kalinichenko Avatar answered Nov 03 '22 07:11

Sergey Kalinichenko