Processes.mod 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. (*$R-*)
  2. IMPLEMENTATION MODULE Processes [1];
  3. (*
  4. Module: Processes
  5. From: "Programming in Modula-2", 3rd, corrected edition, by N. Wirth
  6. Version: $Id$
  7. *)
  8. FROM SYSTEM IMPORT ADDRESS, TSIZE, NEWPROCESS, TRANSFER;
  9. FROM Storage IMPORT Allocate;
  10. FROM Traps IMPORT Message;
  11. TYPE SIGNAL = POINTER TO ProcessDescriptor;
  12. ProcessDescriptor =
  13. RECORD next: SIGNAL; (* ring *)
  14. queue: SIGNAL; (* queue of waiting processes *)
  15. cor: ADDRESS;
  16. ready: BOOLEAN;
  17. END;
  18. VAR cp: SIGNAL; (* current process *)
  19. PROCEDURE StartProcess(P: PROC; n: CARDINAL);
  20. VAR s0: SIGNAL;
  21. wsp: ADDRESS;
  22. BEGIN
  23. s0 := cp;
  24. Allocate(wsp, n);
  25. Allocate(cp, TSIZE(ProcessDescriptor));
  26. WITH cp^ DO
  27. next := s0^.next;
  28. s0^.next := cp;
  29. ready := TRUE;
  30. queue := NIL
  31. END;
  32. NEWPROCESS(P, wsp, n, cp^.cor);
  33. TRANSFER(s0^.cor, cp^.cor);
  34. END StartProcess;
  35. PROCEDURE SEND(VAR s: SIGNAL);
  36. VAR s0: SIGNAL;
  37. BEGIN
  38. IF s # NIL THEN
  39. s0 := cp;
  40. cp := s;
  41. WITH cp^ DO
  42. s := queue;
  43. ready := TRUE;
  44. queue := NIL
  45. END;
  46. TRANSFER(s0^.cor, cp^.cor);
  47. END
  48. END SEND;
  49. PROCEDURE WAIT(VAR s: SIGNAL);
  50. VAR s0, s1: SIGNAL;
  51. BEGIN
  52. (* insert cp in queue s *)
  53. IF s = NIL THEN
  54. s := cp
  55. ELSE
  56. s0 := s;
  57. s1 := s0^.queue;
  58. WHILE s1 # NIL DO
  59. s0 := s1;
  60. s1 := s0^.queue
  61. END;
  62. s0^.queue := cp
  63. END;
  64. s0 := cp;
  65. REPEAT
  66. cp := cp^.next
  67. UNTIL cp^.ready;
  68. IF cp = s0 THEN
  69. (* deadlock *)
  70. Message("deadlock");
  71. HALT
  72. END;
  73. s0^.ready := FALSE;
  74. TRANSFER(s0^.cor, cp^.cor)
  75. END WAIT;
  76. PROCEDURE Awaited(s: SIGNAL): BOOLEAN;
  77. BEGIN
  78. RETURN s # NIL
  79. END Awaited;
  80. PROCEDURE Init(VAR s: SIGNAL);
  81. BEGIN
  82. s := NIL
  83. END Init;
  84. BEGIN
  85. Allocate(cp, TSIZE(ProcessDescriptor));
  86. WITH cp^ DO
  87. next := cp;
  88. ready := TRUE;
  89. queue := NIL
  90. END
  91. END Processes.