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