In-Depth Analysis of ARMv8/ARMv9 Exclusive Mechanism

Note: Although this article uses the spinlock function as an example, it will not delve deeply into the spinlock function. The focus of this article is on the exclusive mechanism.

Basic Knowledge

  • Each core has an Internal Exclusive Monitor, which has open and exclusive states, managing: Load-Exclusive accesses, Store-Exclusive accesses, and Clear-Exclusive (CLREX) instructions.

  • Load-Exclusive instruction and Store-Exclusive instruction areLDX, LDAX, STX, STLX

  • These instructions can be used to construct semaphores and spinlocks to ensure synchronization operations between different threads on the same core. The same coherent memory locations can also be used between different cores to ensure synchronization.

  • The Load-Exclusive instruction marks a block for exclusive access to memory, and CTR_EL0 defines the size of this block.

LDXR Wt, [base{,#0}]

(1) Read a number from the <span>base</span> address into the Wt register; (2) Set the Monitor’s state to exclusive.

STXR Ws, Wt, [base{,#0}]

(1) Write the data in Wt to the <span>base</span> address. If successful, Ws returns 0; otherwise, it returns 1; (2) Switch the Monitor from exclusive to open. If the switch is successful, it indicates that the write was successful, and Ws returns 0; if the switch fails, the data will not be written to memory, and Ws returns 1.

Analysis: If you want to use the exclusive instruction to store a number, you must first use the ldx/ldax instruction to set the Monitor to exclusive state. Only then can you proceed with the store operation. After the store is completed, the Monitor will switch from exclusive back to open state. In simpler terms: If I want to write to an address in exclusive mode, I must first take exclusive control of the monitor, and then I can write data to the relevant address.

Example 1: Accessing Different Locks on the Same Core

Here is an implementation of a spinlock. When two threads execute this code on the same core:

FUNC cpu_spin_lock , :
    mov w2, #SPINLOCK_LOCK
    sevl
l1:    wfe
l2:    ldaxr   w1, [x0]
    cbnz    w1, l1
    stxr    w1, w2, [x0]
    cbnz    w1, l2
    ret
END_FUNC __cpu_spin_lock
  • 1. thread1 first calls cpu_spin_lock[&lock1] and executes to ldaxr. At this point, the Internal Exclusive Monitor will be marked as exclusive. In other words, the core is now in Exclusive Access state and is about to prepare for a write operation.

  • 2. Then, thread2 also calls cpu_spin_lock[&lock2] and executes to ldaxr. At this point, the Internal Exclusive Monitor is already in exclusive state and does not need to be reset. In other words, the core remains in Exclusive Access state and is about to prepare for a write operation.

  • 3. Then, thread1 calls the stxr operation, and it succeeds, successfully writing w2 to the [X0] address, with w1 returning 0 to indicate success. The Internal Exclusive Monitor will switch from exclusive to open state.

  • 4. Then, thread2 also calls the stxr operation. Since the Internal Exclusive Monitor is now in open state, this write operation will fail. That is, w2 will not be written to [X0], and w1 will return 1, informing the program: “Hey, this step did not pass.”

  • 5. According to the logic of the above program, after thread2 fails the stxr operation and w1 returns 1, the program jumps back to <span>l2</span> and tries again…

    In-Depth Analysis of ARMv8/ARMv9 Exclusive Mechanism

Example 2: Accessing Different Locks on Different Cores

Continuing with the previous example, what happens if different CPUs acquire the same lock?

  • 1. thread1 first calls cpu_spin_lock[&lock1] and executes to ldaxr. At this point, core1‘s Internal Exclusive Monitor will be marked as exclusive. In other words, core1 is now in Exclusive Access state and is about to prepare for a write operation.

  • 2. Then, thread2 also calls cpu_spin_lock[&lock2] and executes to ldaxr. At this point, core2‘s Internal Exclusive Monitor will also be marked as exclusive, meaning the core is still in Exclusive Access state and is about to prepare for a write operation.

  • 3. Then, thread1 calls the stxr operation, and it succeeds, successfully writing w2 to the [X0] address, with w1 returning 0 to indicate success. The Internal Exclusive Monitor will switch from exclusive to open state.

  • 4. Then, thread2 also calls the stxr operation. Since core2‘s Internal Exclusive Monitor is still in exclusive state, this write operation will succeed.

In-Depth Analysis of ARMv8/ARMv9 Exclusive Mechanism

Example 3: Accessing the Same Lock on Different Cores

Continuing with the previous example, what happens if different CPUs acquire the same lock?

  • 1. thread1 first calls cpu_spin_lock[&lock1] and executes to ldaxr. At this point, core1‘s Internal Exclusive Monitor will be marked as exclusive. In other words, core1 is now in Exclusive Access state and is about to prepare for a write operation.

  • 2. Then, thread2 also calls cpu_spin_lock[&lock1] and executes to ldaxr. At this point, core2‘s Internal Exclusive Monitor will also be marked as exclusive. Since [X0] is marked for exclusive access, it will be cached in coherent memory, which follows the MESI protocol. Therefore, the data at this address will also be synchronized to the Global Monitor’s cache and Core2’s Internal Monitor’s cache. In other words, the Global Exclusive Monitor will also be updated with the data at this address and will be in exclusive state.

  • 3. Then, thread1 calls the stxr operation, and it succeeds, successfully writing w2 to the [X0] address, with w1 returning 0 to indicate success. At this point, core1‘s Internal Exclusive Monitor will switch from exclusive to open state. The Global Monitor will also switch from exclusive to open state.

  • 4. Then, thread2 calls the stxr operation. According to the MESI protocol, core2 must snoop core1’s cache before executing the store operation. At this point, the data at this address will be synchronized to the Global Monitor’s cache and core2’s Internal Monitor’s cache, and the Global Exclusive Monitor will be set to open state. Since the Global Exclusive Monitor has cached the data at this address and is in open state, the stxr operation will fail.

  • 5. If core2 executes ldaxr again and then executes stxr, it will succeed.

  • 6. According to the logic of the above program, after core2 fails the stxr operation and w1 returns 1, the program jumps back to <span>l2</span> and tries again…

Leave a Comment