alarm.c 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  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*)
  18. {
  19. Proc *rp;
  20. uint32_t now;
  21. for(;;){
  22. now = sys->ticks;
  23. qlock(&alarms);
  24. while((rp = alarms.head) && rp->alarm <= now){
  25. if(rp->alarm != 0L){
  26. if(canqlock(&rp->debug)){
  27. if(!waserror()){
  28. postnote(rp, 0, "alarm", NUser);
  29. poperror();
  30. }
  31. qunlock(&rp->debug);
  32. rp->alarm = 0L;
  33. }else
  34. break;
  35. }
  36. alarms.head = rp->palarm;
  37. }
  38. qunlock(&alarms);
  39. sleep(&alarmr, return0, 0);
  40. }
  41. }
  42. /*
  43. * called every clock tick
  44. */
  45. void
  46. checkalarms(void)
  47. {
  48. Proc *p;
  49. uint32_t now;
  50. p = alarms.head;
  51. now = sys->ticks;
  52. if(p && p->alarm <= now)
  53. wakeup(&alarmr);
  54. }
  55. uint32_t
  56. procalarm(uint32_t time)
  57. {
  58. Proc **l, *f;
  59. uint32_t when, old;
  60. if(up->alarm)
  61. old = tk2ms(up->alarm - sys->ticks);
  62. else
  63. old = 0;
  64. if(time == 0) {
  65. up->alarm = 0;
  66. return old;
  67. }
  68. when = ms2tk(time)+sys->ticks;
  69. qlock(&alarms);
  70. l = &alarms.head;
  71. for(f = *l; f; f = f->palarm) {
  72. if(up == f){
  73. *l = f->palarm;
  74. break;
  75. }
  76. l = &f->palarm;
  77. }
  78. up->palarm = 0;
  79. if(alarms.head) {
  80. l = &alarms.head;
  81. for(f = *l; f; f = f->palarm) {
  82. if(f->alarm > when) {
  83. up->palarm = f;
  84. *l = up;
  85. goto done;
  86. }
  87. l = &f->palarm;
  88. }
  89. *l = up;
  90. }
  91. else
  92. alarms.head = up;
  93. done:
  94. up->alarm = when;
  95. qunlock(&alarms);
  96. return old;
  97. }