Copyright (C) 1994, Digital Equipment Corp.UNSAFE
MODULE; IMPORT Thread; PROCEDURE Fifo New (proc: SubsumerProc := NIL): T = BEGIN RETURN NEW ( T, subsumerProc := proc, first := NIL, last := NIL, mutex := NEW (MUTEX), condition := NEW (Thread.Condition) ); END New; PROCEDUREInsert (t: T; e: E) = VAR r, s: E; BEGIN LOCK t.mutex DO e.next := NIL; IF t.first=NIL THEN t.first := e; t.last := e; Thread.Signal (t.condition); ELSE IF t.subsumerProc # NIL THEN (* Test for subsumes. *) r := t.subsumerProc (e, t.first); IF r = t.first THEN RETURN; END; IF r = e THEN e.next := t.first.next; t.first := e; IF e.next = NIL THEN t.last := e; END; RETURN; END; s := t.first; WHILE s.next # NIL DO r := t.subsumerProc (e, s.next); IF r = s.next THEN RETURN; END; IF r = e THEN e.next := s.next.next; s.next := e; IF e.next = NIL THEN t.last := e; END; RETURN; END; s := s.next; END; END; (* of IF t.subsumerProc # NIL *) t.last.next := e; t.last := e; END; END; END Insert; PROCEDUREEmpty (t: T): BOOLEAN = BEGIN LOCK t.mutex DO RETURN t.first # NIL; END; END Empty; PROCEDURECount (t: T): INTEGER = VAR ret: INTEGER := 0; VAR ind: E; BEGIN LOCK t.mutex DO ind := t.first; WHILE ind # NIL DO INC (ret); ind := ind.next; END; RETURN ret; END; END Count; PROCEDURERemoveOrNIL (t: T): E = VAR ret: E; BEGIN LOCK t.mutex DO ret := t.first; IF ret # NIL THEN t.first := ret.next; END; RETURN ret; END; END RemoveOrNIL; PROCEDURERemoveOrWait (t: T): E = VAR ret: E; BEGIN LOCK t.mutex DO WHILE t.first = NIL DO Thread.Wait (t.mutex, t.condition); END; ret := t.first; t.first := ret.next; IF t.first = NIL THEN t.last := NIL; END; END; RETURN ret; END RemoveOrWait; BEGIN END Fifo.