• AVR Freaks

Hot!Understanding MIPS disassembly - Is "__sync_lock_test_and_set" atomic?

Author
sebmadgwick
Super Member
  • Total Posts : 152
  • Reward points : 0
  • Joined: 2012/07/08 09:56:59
  • Location: 0
  • Status: offline
2019/04/10 12:58:45 (permalink)
0

Understanding MIPS disassembly - Is "__sync_lock_test_and_set" atomic?

I have a function that is called from multiple, potentially nested interrupts. Critical code in the function must never interrupt itself. I intend to achieve this with the following code.
void function() {
    static int lockVariable;
    if (__sync_lock_test_and_set(&lockVariable, 1) == 1) {
        return;
    }
    // CRITICAL CODE GOES HERE
    __sync_lock_release(&lockVariable);
}

This solution will only work if the interactions of __sync_lock_test_and_set with lockVariable are atomic from the perspective of interrupting code. This solution will not work if it is possible for this function to interrupt itself between the 'test' and 'set' operations of __sync_lock_test_and_set so that both the interrupting and interrupted function calls test lockVariable to be zero.
 
I believe the solution will work with correct use of the LL and SC instructions. I suspect that the following MIPS disassembly of the above code achieves this. However, I am not familiar enough with MIPS to be sure.
 
121: static int lock;
122: if (__sync_lock_test_and_set(&lock, 1) == 1) {
9D02C498 278280E0 ADDIU V0, GP, -32544
9D02C49C C0430000 LL V1, 0(V0)
9D02C4A0 24010001 ADDIU AT, ZERO, 1
9D02C4A4 E0410000 SC AT, 0(V0)
9D02C4A8 1020FFFC BEQ AT, ZERO, 0x9D02C49C
9D02C4AC 00000000 NOP
9D02C4B0 0000000F SYNC
9D02C4B4 24020001 ADDIU V0, ZERO, 1
9D02C4B8 10620008 BEQ V1, V0, 0x9D02C4DC
9D02C4BC 2402FFFF ADDIU V0, ZERO, -1
123: return;
124: }
 
I'm hoping someone might be kind enough to explain the above instruction sequence. Descriptions of MIPS instructions are readily available but I'm struggling to interpret these alongside the specific arguments.
post edited by sebmadgwick - 2019/04/10 13:16:59
#1

1 Reply Related Threads

    andersm
    Super Member
    • Total Posts : 2637
    • Reward points : 0
    • Joined: 2012/10/07 14:57:44
    • Location: 0
    • Status: offline
    Re: Understanding MIPS disassembly - Is "__sync_lock_test_and_set" atomic? 2019/04/10 14:49:50 (permalink)
    5 (1)
    They are called "atomic builtins" for a reason.
     

     
    9D02C498 278280E0 ADDIU V0, GP, -32544      // $V0 = &lock
    9D02C49C C0430000 LL V1, 0(V0)              // $V1 = linked load from *($V0)
    9D02C4A0 24010001 ADDIU AT, ZERO, 1         // $1 = 1
    9D02C4A4 E0410000 SC AT, 0(V0)              // Try storing $1 to *($V0)
    9D02C4A8 1020FFFC BEQ AT, ZERO, 0x9D02C49C  // If $1 == 0, the sequence was interrupted and the store aborted, try again
    9D02C4AC 00000000 NOP
    9D02C4B0 0000000F SYNC                      // Sync is only really required for SMP
    9D02C4B4 24020001 ADDIU V0, ZERO, 1         // $V0 = 1
    9D02C4B8 10620008 BEQ V1, V0, 0x9D02C4DC    // If $V1 (ie. lock) == 1, branch ahead (to function exit?)
    9D02C4BC 2402FFFF ADDIU V0, ZERO, -1        // $V0 = -1
     

     
    Edit: On single-processor machines, "sequence was interrupted" in practice means the exception return instruction ERET was executed, but on shared-memory multicore machines this also includes writes detected from other CPUs. This detection is not perfect, which is why the documentation for LL/SC includes caveats about distance between the load and stores, not executing other memory access instructions and so on.
    post edited by andersm - 2019/04/10 14:57:57
    #2
    Jump to:
    © 2019 APG vNext Commercial Version 4.5