(*$R-*) IMPLEMENTATION MODULE Processes [1]; (* Module: Processes From: "Programming in Modula-2", 3rd, corrected edition, by N. Wirth Version: $Header: /cvsup/minix/src/lib/ack/libm2/Processes.mod,v 1.1 2005/10/10 15:27:46 beng Exp $ *) FROM SYSTEM IMPORT ADDRESS, TSIZE, NEWPROCESS, TRANSFER; FROM Storage IMPORT Allocate; FROM Traps IMPORT Message; TYPE SIGNAL = POINTER TO ProcessDescriptor; ProcessDescriptor = RECORD next: SIGNAL; (* ring *) queue: SIGNAL; (* queue of waiting processes *) cor: ADDRESS; ready: BOOLEAN; END; VAR cp: SIGNAL; (* current process *) PROCEDURE StartProcess(P: PROC; n: CARDINAL); VAR s0: SIGNAL; wsp: ADDRESS; BEGIN s0 := cp; Allocate(wsp, n); Allocate(cp, TSIZE(ProcessDescriptor)); WITH cp^ DO next := s0^.next; s0^.next := cp; ready := TRUE; queue := NIL END; NEWPROCESS(P, wsp, n, cp^.cor); TRANSFER(s0^.cor, cp^.cor); END StartProcess; PROCEDURE SEND(VAR s: SIGNAL); VAR s0: SIGNAL; BEGIN IF s # NIL THEN s0 := cp; cp := s; WITH cp^ DO s := queue; ready := TRUE; queue := NIL END; TRANSFER(s0^.cor, cp^.cor); END END SEND; PROCEDURE WAIT(VAR s: SIGNAL); VAR s0, s1: SIGNAL; BEGIN (* insert cp in queue s *) IF s = NIL THEN s := cp ELSE s0 := s; s1 := s0^.queue; WHILE s1 # NIL DO s0 := s1; s1 := s0^.queue END; s0^.queue := cp END; s0 := cp; REPEAT cp := cp^.next UNTIL cp^.ready; IF cp = s0 THEN (* deadlock *) Message("deadlock"); HALT END; s0^.ready := FALSE; TRANSFER(s0^.cor, cp^.cor) END WAIT; PROCEDURE Awaited(s: SIGNAL): BOOLEAN; BEGIN RETURN s # NIL END Awaited; PROCEDURE Init(VAR s: SIGNAL); BEGIN s := NIL END Init; BEGIN Allocate(cp, TSIZE(ProcessDescriptor)); WITH cp^ DO next := cp; ready := TRUE; queue := NIL END END Processes.