INSQUE INSERT ENTRY IN QUEUE
Purpose |
add entry to head or tail of queue |
Format |
opcode entry.ab, pred.ab |
Operation |
If (all memory accesses can be completed) then begin (entry) ß (pred); forward link of entry (entry+4) ß pred; backward link of entry ((pred)+4) ß entry; backward link of successor (pred) ß entry; forward link of predecessor end; else begin {backup instruction}; {initiate fault} end; |
Condition codes |
N ß (entry) LSS (entry+4); Z ß (entry) EQL (entry+4); first entry in queue V ß 0; C ß (entry) LSSU (entry+4); |
Exceptions |
None |
Opcodes |
OE INSQUE Insert Entry in Queue |
Description |
The entry specified by the entry operand is inserted into the queue following the entry specified by the predecessor operand. If the entry inserted was the first one in the queue, the condition code Z-bit is set; otherwise it is cleared. The insertion 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 insertion is non-interruptible, processes running in kernel mode can share queues with interrupt service 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 the insertions and removals are only at the head or trail of the queue. 3. During access validation, any access which cannot be completed results in a memory management exception even though the queue insertion is not started. 4. The instruction is similar to the interlocked sequence MOVL pred, temp ref MOVAB pred, entry + 4 MOVAB entry, 4(tmp reg) MOVL temp reg, entry MOVAB entry, pred |
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