Page 1 of 1

atomic test and modify uint32_t

Posted: Thu Mar 15, 2018 12:29 pm
by MarkZi
Hello,

what is the best way to do a atomic uint32_t operation. The uint32_t variable is only accessed by different freertos tasks, not by HW-ISR.

I do not know if the stdatomic.h stuff works.

I tried

Code: Select all

  
uint32_t Can_ModifyUInt(uint32_t volatile *pUInt, uint32_t CompareValue, uint32_t NewValue)
{
  taskDISABLE_INTERRUPTS();
  uint32_t result = *pUInt;
  if (result == CompareValue)
    *pUInt = NewValue;
  taskENABLE_INTERRUPTS();
  return result;
}
but I'm unsure if that enough protection if the tasks runs on different ESP32-cores. And probably there is a more efficent solution than my code... :?

Any help is appreciated,

Mark

Re: atomic test and modify uint32_t

Posted: Thu Mar 15, 2018 10:05 pm
by ESP_Angus
Hi Mark,

C stdatomic will work correctly, including across cores.

The code you posted will only work if all accesses are made from tasks running on the same core.

You can also use our port-specific FreeRTOS uxPortCompareSet() macro:
https://github.com/espressif/esp-idf/bl ... cro.h#L273

(This macro uses the same Xtensa atomic test-and-set instruction that the compiler will generate for stdatomic operations.)

If you need higher level concurrency primitives, take a look at FreeRTOS mutexes, semaphores, etc.

Re: atomic test and modify uint32_t

Posted: Sat Jan 25, 2020 11:29 am
by raldone01
Hi ESP_Angus,
Don't point links to files in the master branch as it changes. (The line is not correct anymore.)

Re: atomic test and modify uint32_t

Posted: Mon Jul 12, 2021 8:10 am
by rustyx
Too bad ESP8266 doesn't seem to fully support std::atomic. Atomic loads/stores work fine, but compare_exchange_weak(), compare_exchange_strong(), ++, etc, end up with a link error "undefined reference to `__atomic_compare_exchange_2`".

Of course it's not an issue on a single-core system. But it requires conditional compilation in portable ESP8266/ESP32 code.

Re: atomic test and modify uint32_t

Posted: Mon Jul 12, 2021 8:30 am
by ESP_igrr
Hi rustyx,
The recent version of stdatomic.c from ESP-IDF provides all necessary atomic built-in functions also on single core chips: https://github.com/espressif/esp-idf/bl ... tdatomic.c
You can try to copy this file to your ESP8266 project. It might need a few tweaks to spinlock-related macros (portENTER_CRITICAL) for the ESP8266 RTOS SDK or non-OS SDK, depending on what you are using.