In-Depth Analysis of the Exclusive Mechanism in Arm v8/v9

Click the card below to follow Arm Technology Academy

This article is selected from the “Arm Selection” column of Jishu, authorized to be reprinted from the WeChat public account Arm Selection. The author is ctw, who believes that code changes the world. This article will guide you through the knowledge related to the 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 two states: open and exclusive, managing:

    Load-Exclusive accesses,

    Store-Exclusive accesses,

    Clear-Exclusive (CLREX) instructions.

  • The Load-Exclusive instruction and Store-Exclusive instruction are LDX, 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, with CTR_EL0 defining the size of this block.

LDXR Wt, [base{,#0}]

(1) Reads a number from the base address and stores it in the Wt register;

(2) Changes the state of the Monitor to exclusive.

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

(1) Writes the data in Wt to the base address. If successful, Ws returns 0; otherwise, it returns 1;

(2) Changes 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: To use the exclusive instruction to store a number, you must first execute 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 a number to an address in exclusive mode, I must first acquire the exclusive monitor before I can write data to the relevant address.

Example 1: Accessing Different Locks on the Same Core

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

In-Depth Analysis of the Exclusive Mechanism in Arm v8/v9

(1) Thread1 first calls cpu_spin_lock[&lock1] and reaches 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) Next, thread2 also calls cpu_spin_lock[&lock2] and reaches 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, which succeeds in writing w2 to the [X0] address, and w1 returns 0 indicating success. The Internal Exclusive Monitor will switch from exclusive to open state.

(4) Next, thread2 also calls the stxr operation. Since the Internal Exclusive Monitor is now in open state, this write operation will fail. Thus, w2 will not be written to [X0], and w1 returns 1, indicating to the program that 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 l2 and repeats the process.

In-Depth Analysis of the Exclusive Mechanism in Arm v8/v9

Example 2: Accessing Different Locks on Different Cores

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

(1) Thread1 first calls cpu_spin_lock[&lock1] and reaches ldaxr. At this point, the core1 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) Next, thread2 also calls cpu_spin_lock[&lock2] and reaches ldaxr. At this point, the core2 Internal Exclusive Monitor will also be marked as exclusive. In other words, core2 is also in Exclusive Access state and is about to prepare for a write operation.

(3) Then, thread1 calls the stxr operation, which succeeds in writing w2 to the [X0] address, and w1 returns 0 indicating success. The Internal Exclusive Monitor will switch from exclusive to open state.

(4) Next, thread2 also calls the stxr operation. Since the core2 Internal Exclusive Monitor is still in exclusive state, this write operation will succeed.

In-Depth Analysis of the Exclusive Mechanism in Arm v8/v9

Example 3: Accessing the Same Lock on Different Cores

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

(1) Thread1 first calls cpu_spin_lock[&lock1] and reaches ldaxr. At this point, the core1 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) Next, thread2 also calls cpu_spin_lock[&lock1] and reaches ldaxr. At this point, the core2 Internal Exclusive Monitor will 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 also be in exclusive state.

(3) Then, thread1 calls the stxr operation, which succeeds in writing w2 to the [X0] address, and w1 returns 0 indicating success. The core1 Internal Exclusive Monitor will switch from exclusive to open state. The Global Monitor will also switch from exclusive to open state.

(4) Next, 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. 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 l2 and repeats the process.

Recommended Reading

  • Overview of Arm Compilers

  • Things You Didn’t Know About Arm v7/Arm v8/Arm v9 Architectures

  • Understanding Various Memory Types in Arm

Follow Arm Technology Academy

Leave a Comment