alarm.c 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include "u.h"
  10. #include "../port/lib.h"
  11. #include "mem.h"
  12. #include "dat.h"
  13. #include "fns.h"
  14. static Alarms alarms;
  15. static Rendez alarmr;
  16. void
  17. alarmkproc(void* v)
  18. {
  19. Proc *up = externup();
  20. Proc *rp;
  21. uint32_t now;
  22. for(;;){
  23. now = sys->ticks;
  24. qlock(&alarms);
  25. while((rp = alarms._head) && rp->alarm <= now){
  26. if(rp->alarm != 0L){
  27. if(canqlock(&rp->debug)){
  28. if(!waserror()){
  29. postnote(rp, 0, "alarm", NUser);
  30. poperror();
  31. }
  32. qunlock(&rp->debug);
  33. rp->alarm = 0L;
  34. }else
  35. break;
  36. }
  37. alarms._head = rp->palarm;
  38. }
  39. qunlock(&alarms);
  40. sleep(&alarmr, return0, 0);
  41. }
  42. }
  43. /*
  44. * called every clock tick
  45. */
  46. void
  47. checkalarms(void)
  48. {
  49. Proc *p;
  50. uint32_t now;
  51. p = alarms._head;
  52. now = sys->ticks;
  53. if(p && p->alarm <= now)
  54. wakeup(&alarmr);
  55. }
  56. uint32_t
  57. procalarm(uint32_t time)
  58. {
  59. Proc *up = externup();
  60. Proc **l, *f;
  61. uint32_t when, old;
  62. if(up->alarm)
  63. old = tk2ms(up->alarm - sys->ticks);
  64. else
  65. old = 0;
  66. if(time == 0) {
  67. up->alarm = 0;
  68. return old;
  69. }
  70. when = ms2tk(time)+sys->ticks;
  71. qlock(&alarms);
  72. l = &alarms._head;
  73. for(f = *l; f; f = f->palarm) {
  74. if(up == f){
  75. *l = f->palarm;
  76. break;
  77. }
  78. l = &f->palarm;
  79. }
  80. up->palarm = 0;
  81. if(alarms._head) {
  82. l = &alarms._head;
  83. for(f = *l; f; f = f->palarm) {
  84. if(f->alarm > when) {
  85. up->palarm = f;
  86. *l = up;
  87. goto done;
  88. }
  89. l = &f->palarm;
  90. }
  91. *l = up;
  92. }
  93. else
  94. alarms._head = up;
  95. done:
  96. up->alarm = when;
  97. qunlock(&alarms);
  98. return old;
  99. }