Encoding:

EXTEND

11110

00101

0

00000

SHIFT

00110

000

000

sel = 6

SLL

00

5

5

1

5

5

3

3

3

5

Format:

PAUSE 

MIPS16e2

Wait for the LLBit to Clear Extended

Purpose:

Wait for the LLBit to Clear Extended

Description:

Locks implemented using the LL/SC instructions are a common method of synchronization between threads of control. A lock implementation does a load-linked instruction and checks the value returned to determine whether the software lock is set. If it is, the code branches back to retry the load-linked instruction, implementing an active busywait sequence. The PAUSE instruction is intended to be placed into the busy-wait sequence to block the instruction stream until such time as the load-linked instruction has a chance to succeed in obtaining the software lock.

The PAUSE instruction is implementation-dependent, but it usually involves descheduling the instruction stream until the LLBit is zero.

In either case, it is assumed that the instruction stream which gives up the software lock does so via a write to the lock variable, which causes the processor to clear the LLBit as seen by this thread of execution.

Restrictions:

Unpredictable prior to MIPS16e2. The operation of the processor is UNPREDICTABLE if a PAUSE instruction is executed placed in the delay slot of a branch or jump instruction.

Operations:

if LLBit != 0 then
   EPC = PC + 4                 /* Resume at the following instruction */
   DescheduleInstructionStream()
endif

Exceptions:

None

Programming Notes:

The PAUSE instruction is intended to be inserted into the instruction stream after an LL instruction has set the LLBit and found the software lock set. The program may wait forever if a PAUSE instruction is executed and there is no possibility that the LLBit will ever be cleared.

An example use of the PAUSE instruction is included in the following example:

acquire_lock:
   ll    v0, 0(a0)              /* Read software lock, set hardware lock */
   bnez  v0, acquire_lock_retry: /* Branch if software lock is taken */
   addiu v0, v0, 1              /* Set the software lock */
   sc    v0, 0(a0)              /* Try to store the software lock */
   bnez v0, 10f              /* Branch if lock acquired successfully */
   sync
acquire_lock_retry:
   pause                         /* Wait for LLBIT to clear before retry */
   b     acquire_lock           /* and retry the operation */
10:
   Critical region code
release_lock:
   sync
   li    t1, 0                  /* Release software lock, clearing LLBIT */
   sw    t1, 0(a0)              /* for any PAUSEd waiters */