REMQUE REMOVE ENTRY IN QUEUE
Purpose |
remove entry from head or tail of queue |
Format |
opcode entry.ab, addr.wl |
Operation |
If (all memory accesses can be completed) then begin ((entry+4)) ß (entry); forward link of predecessor ((entry)+4) ß (entry+4); backward link of successor addr ß entry; end; else begin {backup instruction}; {initiate fault} end; |
Condition codes |
N ß (entry) LSS (entry+4); Z ß (entry) EQL (entry+4); removed last entry V ß entry EQL (entry+4); no entry to remove C ß (entry) LSSU (entry+4); |
Exceptions |
None |
Opcodes |
OF REMQUE Remove Entry from Queue |
Description |
The queue entry specified by the entry operand is removed from the queue. The address operand is replaced by the ad dress of the entry removed. If there was no entry in the queue to be removed, the condition code V bit is set; otherwise it is cleared, If the queue is empty at the end of this instruction, the condition code Z-bit is set; otherwise it is cleared. The removal is a non-interruptible operation. Before performing any part of the operation, the processor validates that the entire operation can be completed. This ensures that if a memory management exception occurs, the queue is left in a consistent state. |
Notes |
1. Because the removal is non-interruptible, processes running in kernel mode can share queues with interrupt ser vice routines. 2. The INSQUE and REMQUE instructions are implemented such that cooperating software processes in a single processor may access a shared list without additional synchronization if insertions and removals are only at the head or tail of the queue. 3. During access validation, any access which cannot be completed results in a memory management exception even though the queue removal is not started. |
Example 1
.text
main: .word 0
remque head,temp #removing an member from empty queue works!
insque mem1,head
insque mem2,head
insque mem3,mem2 # now the queue should be mem2,mem3,mem1
remque mem3,temp # now queue should ne mem2,mem1
remque mem2,temp # only mem1 left
remque mem1,temp # empty again
pushl $0
calls $1,.exit
.data
# queue head. first long is the head pointer, second long is the tail pointer.
# initialize to empty queue, i.e. both pointers point to the head.
head: .long head,head
# queue menebers. first long is NEXT pointer, second long is the PREV pointer
mem1: .long 0,0
mem2: .long 0,0
mem3: .long 0,0
temp: .long 0,0