ActiveCellsRunner.mod 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. module ActiveCellsRunner;
  2. import ActiveCellsRuntime, Commands, Modules;
  3. const
  4. EnableTrace = true;
  5. type
  6. Cell = object
  7. var
  8. isCellnet-:boolean;
  9. end Cell;
  10. Fifo=object
  11. var
  12. data: array 64 of longint;
  13. inPos, outPos: longint; length: longint;
  14. inPort: Port; outPort: Port;
  15. procedure &Init(outP: Port; inP: Port; length: longint);
  16. begin
  17. inPos := 0; outPos := 0; self.length := length;
  18. assert(length < len(data));
  19. inPort := inP; outPort := outP;
  20. inPort.SetFifo(self); outPort.SetFifo(self);
  21. end Init;
  22. procedure Put(value: longint);
  23. begin{EXCLUSIVE}
  24. await(inPos+1 # outPos mod len(data));
  25. data[inPos] := value;
  26. inc(inPos); inPos := inPos mod len(data);
  27. end Put;
  28. procedure Get(var value: longint);
  29. begin{EXCLUSIVE}
  30. await(inPos # outPos);
  31. value := data[outPos];
  32. inc(outPos); outPos := outPos mod len(data);
  33. end Get;
  34. end Fifo;
  35. Port= object
  36. var
  37. fifo-: Fifo;
  38. delegatedTo-: Port;
  39. inout-: set;
  40. procedure & InitPort(inout: set; width: longint);
  41. begin
  42. self.inout := inout;
  43. delegatedTo := nil;
  44. end InitPort;
  45. procedure Delegate(toPort: Port);
  46. begin{EXCLUSIVE}
  47. delegatedTo := toPort;
  48. end Delegate;
  49. procedure SetFifo(f: Fifo);
  50. begin{EXCLUSIVE}
  51. if delegatedTo # nil then
  52. delegatedTo.SetFifo(f)
  53. else
  54. fifo := f;
  55. end;
  56. end SetFifo
  57. procedure Send(value: longint);
  58. begin
  59. begin{EXCLUSIVE}
  60. await((fifo # nil) or (delegatedTo # nil));
  61. end;
  62. if delegatedTo # nil then
  63. delegatedTo.Send(value)
  64. else
  65. fifo.Put(value);
  66. end;
  67. end Send;
  68. procedure Receive(var value: longint);
  69. begin
  70. begin{EXCLUSIVE}
  71. await((fifo # nil) or (delegatedTo # nil));
  72. end;
  73. if delegatedTo # nil then
  74. delegatedTo.Receive(value)
  75. else
  76. fifo.Get(value);
  77. end;
  78. end Receive;
  79. end Port;
  80. (* generic context object that can be used by implementers of the active cells runtime *)
  81. Context*= object (ActiveCellsRuntime.Context)
  82. procedure Allocate(scope: any; var c: any; t: Modules.TypeDesc; const name: array of char; isCellnet, isEngine: boolean);
  83. var cel: Cell;
  84. begin
  85. new(cel); c := cel;
  86. cel.isCellnet := isCellnet;
  87. end Allocate;
  88. procedure AddPort*(c: any; var p: any; const name: array of char; inout: set; width: longint);
  89. var por: Port;
  90. begin
  91. if EnableTrace then trace(c,p,name, inout, width); end;
  92. new(por,inout,width); p := por;
  93. end AddPort;
  94. procedure AddPortArray*(c: any; var ports: any; const name: array of char; inout: set; width: longint; const lens: array of longint);
  95. type
  96. Ports1d = array of any;
  97. Ports2d = array of Ports1d;
  98. Ports3d = array of Ports2d;
  99. var
  100. p: any;
  101. p1d: pointer to Ports1d;
  102. p2d: pointer to Ports2d;
  103. p3d: pointer to Ports3d;
  104. i, i0, i1, i2: longint;
  105. begin
  106. if EnableTrace then trace(name, inout, width, len(lens)); end;
  107. (*
  108. There is a slot in the respective cell that can hold a pointer to an n-dimensional array of ports.
  109. This slot is used for the pointer but is not directly accessible any more by the runtime.
  110. So, if information about the array of ports is further required, some metadata should be kept
  111. here. The following is the absolute minimal.
  112. *)
  113. case len(lens,0) of
  114. |1:
  115. new(p1d,lens[0]);
  116. for i0 := lens[0]-1 to 0 by -1 do (*! add ports in reverse order to be consistent with what the runtime does *)
  117. AddPort(c,p1d[i0],name,inout,width);
  118. end;
  119. ports := p1d;
  120. |2:
  121. new(p2d,lens[0],lens[1]);
  122. for i0 := lens[0]-1 to 0 by -1 do (*! add ports in reverse order to be consistent with what the runtime does *)
  123. for i1 := lens[1]-1 to 0 by -1 do
  124. AddPort(c,p2d[i0,i1],name,inout,width);
  125. end;
  126. end;
  127. ports := p2d;
  128. |3:
  129. new(p3d,lens[0],lens[1],lens[2]);
  130. for i0 := lens[0]-1 to 0 by -1 do (*! add ports in reverse order to be consistent with what the runtime does *)
  131. for i1 := lens[1]-1 to 0 by -1 do
  132. for i2 := lens[2]-1 to 0 by -1 do
  133. AddPort(c,p3d[i0,i1,i2],name,inout,width);
  134. end;
  135. end;
  136. end;
  137. ports := p3d;
  138. else
  139. halt(200);
  140. end;
  141. end AddPortArray;
  142. procedure AddStaticPortArray*(c: any; var ports: array of any; const name: array of char; inout: set; width: longint);
  143. var i: longint;
  144. begin
  145. if EnableTrace then trace(name, inout, width, len(ports)); end;
  146. for i := 0 to len(ports)-1 do
  147. AddPort(c, ports[i], name, inout, width);
  148. end;
  149. end AddStaticPortArray;
  150. procedure Connect*(outPort, inPort: any; depth: longint);
  151. var fifo: Fifo;
  152. begin
  153. if EnableTrace then trace(outPort, inPort, outPort, inPort, depth); end;
  154. new(fifo, outPort(Port), inPort(Port), depth);
  155. end Connect;
  156. procedure Delegate*(netPort: any; cellPort: any);
  157. begin
  158. if EnableTrace then trace(netPort, cellPort); end;
  159. netPort(Port).Delegate(cellPort(Port));
  160. end Delegate;
  161. procedure Start*(c: any; proc: procedure{DELEGATE});
  162. var launcher: ActiveCellsRuntime.Launcher;
  163. begin
  164. if EnableTrace then trace(c, proc); end;
  165. if c(Cell).isCellnet then (* synchronous *)
  166. proc
  167. else
  168. new(launcher, self); (* asynchronous *)
  169. launcher.Start(proc, false);
  170. end;
  171. end Start;
  172. procedure Send*(p: any; value: longint);
  173. begin
  174. if EnableTrace then trace(p, value); end;
  175. p(Port).Send(value);
  176. end Send;
  177. procedure Receive*(p: any; var value: longint);
  178. begin
  179. if EnableTrace then trace(p, value); end;
  180. p(Port).Receive(value);
  181. end Receive;
  182. end Context;
  183. procedure Execute*(context: Commands.Context);
  184. var myContext: Context; cmd: array 256 of char;
  185. begin
  186. new(myContext);
  187. if context.arg.GetString(cmd) then
  188. ActiveCellsRuntime.Execute(cmd, myContext, nil)
  189. end;
  190. end Execute;
  191. end ActiveCellsRunner.
  192. ActiveCellsRunner.Execute