103 lines
		
	
	
	
		
			1.8 KiB
		
	
	
	
		
			Modula-2
		
	
	
	
	
	
			
		
		
	
	
			103 lines
		
	
	
	
		
			1.8 KiB
		
	
	
	
		
			Modula-2
		
	
	
	
	
	
(*$R-*)
 | 
						|
IMPLEMENTATION MODULE Processes [1];
 | 
						|
(*
 | 
						|
  Module:       Processes
 | 
						|
  From:         "Programming in Modula-2", 3rd, corrected edition, by N. Wirth
 | 
						|
  Version:      $Header$
 | 
						|
*)
 | 
						|
 | 
						|
  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.
 |