Atomicity of Naturally Aligned Variable Reads/Writes Across Tasks for Different Data Types

ma_ma_ma
Posts: 5
Joined: Sun Apr 25, 2021 3:34 am

Atomicity of Naturally Aligned Variable Reads/Writes Across Tasks for Different Data Types

Postby ma_ma_ma » Thu May 08, 2025 9:45 am

Hello everyone,

I'm working on a project using ESP32 with FreeRTOS where multiple tasks share and modify various types of global variables. My question is about the atomicity of read/write operations on naturally aligned variables in this environment.

Let’s say we have a shared variable that is accessed by two different tasks:

Code: Select all

#include <stdint.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

// Naturally aligned global variable (aligned to its natural boundary)
volatile int16_t global_state = 0;

void task1(void *pvParameters) {
    while (1) {
        vTaskDelay(pdMS_TO_TICKS(1000));
        global_state = 1;  // Write operation
    }
}

void task2(void *pvParameters) {
    while (1) {
        if (global_state == 1) {  // Read operation
            printf("Task1 completed, executing Task2\n");
            global_state = 0;
        }
        vTaskDelay(pdMS_TO_TICKS(100));
    }
}
Assuming all variables are naturally aligned (e.g., int32_t aligned to 4-byte boundaries, int16_t to 2-byte, etc.),
my questions are:

Which data types guarantee atomic reads and writes on the ESP32 platform?
Does the Xtensa LX6 architecture ensure atomic access for 16-bit, 32-bit, or 64-bit types when they are naturally aligned?
What about floating-point types like float (32-bit) or double (64-bit)?
I understand that synchronization primitives like mutexes or critical sections are the correct way to protect shared resources. But I'm specifically interested in understanding what the baseline behavior is at the hardware level on ESP32 — especially for variables that are properly aligned.

Any insights into:

Which types can be safely accessed without synchronization,
Architecture-specific guarantees,
Or official documentation from Espressif or Xtensa specs regarding atomicity of memory accesses
would be greatly appreciated.

Thank you in advance for your help!

Best regards

Sprite
Espressif staff
Espressif staff
Posts: 10612
Joined: Thu Nov 26, 2015 4:08 am

Re: Atomicity of Naturally Aligned Variable Reads/Writes Across Tasks for Different Data Types

Postby Sprite » Fri May 09, 2025 12:35 am

Anything 32-bit is aligned, but please use C's atomic support (#include <stdatomic.h>) rather than assuming something volatile must be atomic.

MicroController
Posts: 2669
Joined: Mon Oct 17, 2022 7:38 pm
Location: Europe, Germany

Re: Atomicity of Naturally Aligned Variable Reads/Writes Across Tasks for Different Data Types

Postby MicroController » Fri May 09, 2025 7:17 am

Which data types guarantee atomic reads and writes on the ESP32 platform?
Does the Xtensa LX6 architecture ensure atomic access for 16-bit, 32-bit, or 64-bit types when they are naturally aligned?
What about floating-point types like float (32-bit) or double (64-bit)?
AFAICT, by the hardware, all 8-, 16-, and 32-bit accesses to RAM are atomic on the Xtensa ESPs, no alignment required; no 64-bit access is atomic. (Different for the S3's SIMD/PIE instructions.)

(gcc, however, assumes fields in packed structures are unaligned and that unaligned accesses may be invalid, so, playing it safe, it splits accesses to 'packed' 16- and 32-bit fields into multiple 8-bit accesses.)

ma_ma_ma
Posts: 5
Joined: Sun Apr 25, 2021 3:34 am

Re: Atomicity of Naturally Aligned Variable Reads/Writes Across Tasks for Different Data Types

Postby ma_ma_ma » Mon May 12, 2025 6:43 am

Thank you so much for all the helpful responses and suggestions!

I just wanted to clarify that I do understand volatile doesn't guarantee atomicity; it was simply an example I used to illustrate my point. Thanks for the reminder though!

On a curious note, could anyone kindly direct me to any official documentation or resources where the atomicity guarantees for 8-bit, 16-bit, and floating-point types on the ESP32 platform are discussed? It would be really interesting to learn more about how these data types behave in terms of atomic access when naturally aligned. While we know that 32-bit accesses are atomic, having more details on other types would be super helpful.

Especially considering whether dual-core CPUs might have cache issues, is the atomicity problem of data read and write actually more complex?

Really appreciate all your help and insights!

Best regards,

MicroController
Posts: 2669
Joined: Mon Oct 17, 2022 7:38 pm
Location: Europe, Germany

Re: Atomicity of Naturally Aligned Variable Reads/Writes Across Tasks for Different Data Types

Postby MicroController » Mon May 12, 2025 11:08 am

I have no official source of information, but I do know that 1. the internal RAM of the Xtensa ESPs is byte-addressable and 2. a memory access (8, 16, or 32 bits) always(*) takes the same number of CPU clock cycles (1+1 for a read on the S3) no matter the (mis-)alignment.
Especially considering whether dual-core CPUs might have cache issues, is the atomicity problem of data read and write actually more complex?
The ESP Xtensas don't have an actual cache between CPU and internal RAM, so no coherency issues in this regard. They do appear to have a kind of pipeline in front of the memory interface which is 'flushed' via the MEMW instruction (that gcc uses for accesses to 'volatilies'), but that's a memory-order issue rather than atomicity.

(*) assuming an empty memory 'pipeline'

Who is online

Users browsing this forum: Applebot, Baidu [Spider], Bytespider and 2 guests