Page 1 of 1

How to do atomic operations like atomic_fetch_add on ESP32 in ESP-IDF?

Posted: Fri Jan 16, 2026 8:59 am
by ma_ma_ma
Hi,

I’m using ESP32(xtensa) with ESP-IDF and I’d like to perform atomic operations such as atomic_fetch_add on shared variables (instead of always using mutexes or critical sections).

I checked the ESP-IDF Programming Guide and the Miscellaneous System APIs section, and I only found esp_cpu_compare_and_set() which does an atomic compare‑and‑set on a volatile uint32_t * and returns whether the value was updated.[ESP32 misc API]

From the ESP-IDF release notes I also see that additional atomic builtins like __atomic_OP_fetch_n and __sync_OP_and_fetch_n were implemented in newlib for ESP-IDF, but there is no clear example of how to use them in user code.[v4.3.3 changelog; v4.4 changelog]

My questions are:

- On ESP32, what is the recommended way in ESP-IDF to implement something equivalent to atomic_fetch_add on a shared counter?
- Should I build it myself using esp_cpu_compare_and_set() (CAS loop)?[ESP32 misc API]
- Or should I directly use the compiler/newlib builtins like __atomic_fetch_add / __sync_fetch_and_add that are mentioned in the changelog?[v4.3.3 changelog; v4.4 changelog]
- Are there any official examples or documentation from Espressif that show how to use these atomic builtins (or other ESP-IDF APIs) to implement operations like atomic_fetch_add, atomic_exchange, etc.?
- Do these atomic operations on ESP32 map to hardware support, or are they implemented via software (locks/critical sections) under the hood?

I’ve read the Programming Guide but couldn’t find a concrete API for atomic_fetch_add, so any guidance or example code would be very helpful.

Thanks!

Re: How to do atomic operations like atomic_fetch_add on ESP32 in ESP-IDF?

Posted: Fri Jan 16, 2026 12:14 pm
by MicroController
You can just use C standard (or C++) atomic types and functions.
They are implemented via hardware compare+exchange ("S32C1I") on the Xtensas where possible.

The hardware instructions do not work on variables in PSRAM though, which is why by default, if you have PSRAM enabled, the implementation will check for PSRAM addresses and fall back to a critical section when accessing atomics in PSRAM.