Assembly:

PAUSE

nanoMIPS

Pause

Purpose:

Pause. Pause until LL Bit is cleared.

Availability:

nanoMIPS

Format:

100000

00000

x

1100

x

0000

00101

6

5

5

4

3

4

5

Operation:

if C0.LLAddr.LLB:
    CPU.in_pause_state = True

The purpose ofthe PAUSE instruction is halt a thread (rather than entering a spin loop) when itis waiting to acquire an LL/SC lock. This is particularly useful on multi-threaded processors, since the

waiting thread may be using the same instruction pipeline as the thread which currently owns the lock, and hence entering a spin loop will delay the other thread from completing its task and freeing the

lock.

When a thread is in the paused state,it should not issue any instructions. The paused state will be

cleared either if the LLBit for the thread gets cleared, or if the thread takes an interrupt.If an interrupt occurs,

it is implementation dependent whether C0.EPC points to the PAUSE instruction or the

instruction after the PAUSE.

In LL/SC lock software, the LLBit of the waiting thread will always be cleared when the thread which owns the lock does a store instruction to the lock address in order to clear the lock. Thus the paused

thread will always be woken when it has another opportunity to acquire the lock. After the PAUSE instruction completes, software is expected to attempt to acquire the lock again by re-executing the

LL/SC sequence.

It is legal to implement PAUSE as a NOP instruction.In this case, the behavior of LL/SC lock software will be equivalent to executing a spin loop to acquire the lock. Software using PAUSE will still work,

but the benefit of having the waiting thread not consume instruction issue slots will be lost.

PAUSE is encoded as an SLL instruction with a shift value of 5, targeting GPR $0. Hence PAUSE will behave as a NOP instruction if no additional behavior beyond that of SLL is implemented.

The following assembly code example shows how the PAUSE instruction can be used to halt a thread while it is waiting to acquire an LL/SC lock.

acquire_lock:
        ll      t0, 0(a0)    /* Read softwarelock, set LLBit. */
        bnezc  t0, acquire_lock_retry /* Branch if softwarelock is taken.*/
        addiu   t0, t0, 1    /* Set the software lock. */
        sc      t0, 0(a0)    /* Try to store the softwarelock. */
        bnezc  t0, 10f      /* Branchiflockacquired successfully.*/
        sync
acquire_lock_retry:
        pause                /* Wait for LLBITtoclear before retrying. */
        bc      acquire_lock /* Now retrytheoperation. */
10:
        /* Critical Region Code */
        ...
release_lock:
        sync
        sw      zero, 0(a0)  /* Releasesoftwarelock,clearing LLBIT
                                for any PAUSEd waiters */

Exceptions:

None.