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 do 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?