time.b 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. implement Timerm;
  2. include "common.m";
  3. sys : Sys;
  4. acme : Acme;
  5. utils : Utils;
  6. dat : Dat;
  7. millisec : import sys;
  8. Timer : import dat;
  9. init(mods : ref Dat->Mods)
  10. {
  11. sys = mods.sys;
  12. acme = mods.acme;
  13. utils = mods.utils;
  14. dat = mods.dat;
  15. }
  16. ctimer : chan of ref Timer;
  17. timeproc()
  18. {
  19. i, nt, na, dt : int;
  20. x : ref Timer;
  21. t : array of ref Timer;
  22. old, new : int;
  23. acme->timerpid = sys->pctl(0, nil);
  24. sys->pctl(Sys->FORKFD, nil);
  25. t = array[10] of ref Timer;
  26. na = 10;
  27. nt = 0;
  28. old = millisec();
  29. for(;;){
  30. if (nt == 0) { # don't waste cpu time
  31. x = <-ctimer;
  32. t[nt++] = x;
  33. old = millisec();
  34. }
  35. sys->sleep(1); # will sleep minimum incr
  36. new = millisec();
  37. dt = new-old;
  38. old = new;
  39. if(dt < 0) # timer wrapped; go around, losing a tick
  40. continue;
  41. for(i=0; i<nt; i++){
  42. x = t[i];
  43. x.dt -= dt;
  44. if(x.dt <= 0){
  45. #
  46. # avoid possible deadlock if client is
  47. # now sending on ctimer
  48. #
  49. alt {
  50. x.c <-= 0 =>
  51. t[i:] = t[i+1:nt];
  52. t[nt-1] = nil;
  53. nt--;
  54. i--;
  55. * =>
  56. ;
  57. }
  58. }
  59. }
  60. gotone := 1;
  61. while (gotone) {
  62. alt {
  63. x = <-ctimer =>
  64. if (nt == na) {
  65. ot := t;
  66. t = array[na+10] of ref Timer;
  67. t[0:] = ot[0:na];
  68. ot = nil;
  69. na += 10;
  70. }
  71. t[nt++] = x;
  72. old = millisec();
  73. * =>
  74. gotone = 0;
  75. }
  76. }
  77. }
  78. }
  79. timerinit()
  80. {
  81. ctimer = chan of ref Timer;
  82. spawn timeproc();
  83. }
  84. #
  85. # timeralloc() and timerfree() don't lock, so can only be
  86. # called from the main proc.
  87. #
  88. timer : ref Timer;
  89. timerstart(dt : int) : ref Timer
  90. {
  91. t : ref Timer;
  92. t = timer;
  93. if(t != nil)
  94. timer = timer.next;
  95. else{
  96. t = ref Timer;
  97. t.c = chan of int;
  98. }
  99. t.next = nil;
  100. t.dt = dt;
  101. ctimer <-= t;
  102. return t;
  103. }
  104. timerstop(t : ref Timer)
  105. {
  106. t.next = timer;
  107. timer = t;
  108. }
  109. timerwaittask(timer : ref Timer)
  110. {
  111. <-(timer.c);
  112. timerstop(timer);
  113. }