armarm64memory-modeltransactional-memoryintel-tsx

Understanding ARM Transactional Memory Extensions


The ARM Transactional Memory Extensions have a fairly straightforward description of how one would use them:

sem_post:
    TSTART X0         // Start of outer transaction
    CBNZ   test_fail  // No reason for this routine to cancel or fail
    LDR    X1, [X2]   // X2 points to semaphore
    ADD    X1, X1, #1 // Increment semaphore value
    STR    X1, [X2].  // Store incremented value
    TCOMMIT           // Commit transaction and exit

What I'm trying to figure out is whether these transactions replay based on collisions with transaction in other parts of the code, and whether they replay based on collisions with any sort of accesses. To elaborate, let's say we have this routine:

sem_wait:
    TSTART X0          // Start of outer transaction
    CBNZ   retry_check // This routine checks for retry (RTRY) and restarts transaction
    LDR    X1, [X2]   // X2 points to semaphore
    CMP    X1, #0     // Check if semaphore is already used
    CBNZ   decrement  // If it's non-zero, we can decrement the semaphore
    TCANCEL #0xFF     // If it's zero, we gotta retry
decrement:
    SUB    X1, X1, #1 // Decrement semaphore value
    STR    X1, [X2].  // Store decremented value
    TCOMMIT           // Commit transaction and exit

So this transaction would be in another part of the code, but would be accessing the locations in memory as the sem_post transaction.

My first question: would a thread executing the sem_post transaction potentially replay due to a thread executing the sem_wait transaction concurrently?

For the second part of my question, let's say we have a simple routine like this:

break_semaphore:
    MOV X0, #0xFF
    STR X0, [X1]  // X1 points to semaphore

The above routine isn't a transaction at all, it's just messing with the semaphore.

My second question: Would the thread executing the sem_post transaction potentially replay due to any concurrent access to locations that are to be updated and committed in the sem_post transaction?

For clarity, I fully understand that this isn't really how the TME instructions are supposed to be used, and that locks would be implemented more like this: https://www.gem5.org/project/2020/10/27/tme.html

I'm more wondering what it is that transactions actually linearize: two transactions with common regions of code, all transactions with each other, or the transaction with respect to all other accesses to memory?


Solution

  • TME definitely linearizes accesses to shared memory regions. In the case of your example, the reason why these transactions are aborting is not due to the fact that they are executing the same code, but due to the shared memory address.

    From the ARM TME documentation, any conflicting state to a memory address will cause TSTART to fail with the MEM bit set. In the context of your semaphore example, because there is no fallback code for the call to sem_post, the transaction would cancel program execution state would revert back to non-Transactional state.

    For a similar reason, transactions do not necessarily linearize by executing the same code because they may refer to different regions of memory (i.e., multiple semaphores with different pointers), which is perfectly legal.

    Whether or not transactions linearize amongst each other is more difficult to answer, because it is typically hardware dependent. For example, two transactions could be legally executing on different cores with different memory objects, but if two transactions are attempting the be executed on the same core and registers (i.e., with hyper-threading), this behavior would be more difficult to define.