Unix.Environment.Mod 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. (* Runtime environment for Unix *)
  2. (* Copyright (C) Florian Negele *)
  3. MODULE Environment;
  4. IMPORT SYSTEM, Activities, Counters, Unix, Processors, Queues, Timer, Trace;
  5. CONST IsNative* = FALSE;
  6. CONST Running* = 0; ShuttingDown* = 1; Rebooting* = 2;
  7. VAR status* := 0: WORD;
  8. VAR clock: Timer.Counter;
  9. VAR milliseconds: Timer.Counter;
  10. VAR sleepingQueue: Queues.Queue;
  11. VAR activity: Unix.Key_t;
  12. PROCEDURE {NORETURN} Abort-;
  13. BEGIN {UNCOOPERATIVE, UNCHECKED}
  14. IF Activities.GetCurrentActivity () # NIL THEN Activities.TerminateCurrentActivity END;
  15. Exit (1);
  16. END Abort;
  17. PROCEDURE Shutdown*;
  18. BEGIN {UNCOOPERATIVE, UNCHECKED}
  19. IF CAS (status, Running, ShuttingDown) # Running THEN RETURN END;
  20. Trace.StringLn ("system: shutting down...");
  21. END Shutdown;
  22. PROCEDURE Reboot*;
  23. BEGIN {UNCOOPERATIVE, UNCHECKED}
  24. Shutdown;
  25. ASSERT (CAS (status, ShuttingDown, Rebooting) = ShuttingDown);
  26. END Reboot;
  27. PROCEDURE {NORETURN} Exit- (status: WORD);
  28. BEGIN {UNCOOPERATIVE, UNCHECKED}
  29. Unix.exit (status);
  30. END Exit;
  31. PROCEDURE Clock- (): LONGINT;
  32. BEGIN {UNCOOPERATIVE, UNCHECKED}
  33. RETURN LONGINT ((Timer.GetCounter () - clock) / milliseconds);
  34. END Clock;
  35. PROCEDURE Sleep- (milliseconds: LONGINT);
  36. VAR nextActivity: Activities.Activity;
  37. BEGIN {UNCOOPERATIVE, UNCHECKED}
  38. INC (milliseconds, Clock ());
  39. Counters.Inc (Activities.awaiting);
  40. WHILE Clock () - milliseconds < 0 DO
  41. IF Activities.Select (nextActivity, Activities.IdlePriority) THEN
  42. Activities.SwitchTo (nextActivity, Enqueue, NIL);
  43. Activities.FinalizeSwitch;
  44. END;
  45. END;
  46. Counters.Dec (Activities.awaiting);
  47. END Sleep;
  48. PROCEDURE Allocate- (size: SIZE): ADDRESS;
  49. VAR result, address: ADDRESS;
  50. BEGIN {UNCOOPERATIVE, UNCHECKED}
  51. result := Unix.malloc (size);
  52. IF result = NIL THEN RETURN NIL END;
  53. FOR address := result TO result + size - 1 DO SYSTEM.PUT8 (address, 0) END;
  54. RETURN result;
  55. END Allocate;
  56. PROCEDURE Deallocate- (address: ADDRESS);
  57. BEGIN {UNCOOPERATIVE, UNCHECKED}
  58. Unix.free (address);
  59. END Deallocate;
  60. PROCEDURE Enqueue (previous {UNTRACED}: Activities.Activity; argument: ADDRESS);
  61. VAR item: Queues.Item;
  62. BEGIN {UNCOOPERATIVE, UNCHECKED}
  63. Queues.Enqueue (previous, sleepingQueue);
  64. END Enqueue;
  65. PROCEDURE GetInit- (n: SIZE; VAR val: LONGINT);
  66. BEGIN val := 0;
  67. END GetInit;
  68. PROCEDURE GetString- (CONST name: ARRAY OF CHAR; VAR result: ARRAY OF CHAR);
  69. BEGIN {UNCOOPERATIVE, UNCHECKED}
  70. result := "";
  71. END GetString;
  72. PROCEDURE StoreActivity-;
  73. BEGIN {UNCOOPERATIVE, UNCHECKED}
  74. Unix.WriteKey (activity, SYSTEM.GetActivity ());
  75. END StoreActivity;
  76. PROCEDURE RestoreActivity-;
  77. BEGIN {UNCOOPERATIVE, UNCHECKED}
  78. SYSTEM.SetActivity(SYSTEM.VAL(Activities.Activity,Unix.ReadKey (activity)));
  79. END RestoreActivity;
  80. PROCEDURE Initialize-;
  81. BEGIN {UNCOOPERATIVE, UNCHECKED}
  82. clock := Timer.GetCounter ();
  83. milliseconds := Timer.GetFrequency () DIV 1000;
  84. activity := Unix.NewKey ();
  85. END Initialize;
  86. PROCEDURE Terminate-;
  87. BEGIN {UNCOOPERATIVE, UNCHECKED}
  88. END Terminate;
  89. END Environment.