alarm.c 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  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 "lib.h"
  11. #include "mem.h"
  12. #include "dat.h"
  13. #include "fns.h"
  14. #include "io.h"
  15. #define MAXALARM 10
  16. Alarm alarmtab[MAXALARM];
  17. /*
  18. * Insert new into list after where
  19. */
  20. void
  21. insert(List **head, List *where, List *new)
  22. {
  23. if(where == 0){
  24. new->next = *head;
  25. *head = new;
  26. }else{
  27. new->next = where->next;
  28. where->next = new;
  29. }
  30. }
  31. /*
  32. * Delete old from list. where->next is known to be old.
  33. */
  34. void
  35. delete(List **head, List *where, List *old)
  36. {
  37. if(where == 0){
  38. *head = old->next;
  39. return;
  40. }
  41. where->next = old->next;
  42. }
  43. Alarm*
  44. newalarm(void)
  45. {
  46. int i;
  47. Alarm *a;
  48. for(i=0,a=alarmtab; i < nelem(alarmtab); i++,a++)
  49. if(a->busy==0 && a->f==0){
  50. a->f = 0;
  51. a->arg = 0;
  52. a->busy = 1;
  53. return a;
  54. }
  55. panic("newalarm");
  56. return 0; /* not reached */
  57. }
  58. Alarm*
  59. alarm(int ms, void (*f)(Alarm*), void *arg)
  60. {
  61. Alarm *a, *w, *pw;
  62. uint32_t s;
  63. if(ms < 0)
  64. ms = 0;
  65. s = splhi();
  66. a = newalarm();
  67. a->dt = MS2TK(ms);
  68. a->f = f;
  69. a->arg = arg;
  70. pw = 0;
  71. for(w=m->alarm; w; pw=w, w=w->next){
  72. if(w->dt <= a->dt){
  73. a->dt -= w->dt;
  74. continue;
  75. }
  76. w->dt -= a->dt;
  77. break;
  78. }
  79. insert(&m->alarm, pw, a);
  80. splx(s);
  81. return a;
  82. }
  83. void
  84. cancel(Alarm *a)
  85. {
  86. a->f = 0;
  87. }
  88. void
  89. alarminit(void)
  90. {
  91. }
  92. #define NA 10 /* alarms per clock tick */
  93. void
  94. checkalarms(void)
  95. {
  96. int i, n, s;
  97. Alarm *a;
  98. void (*f)(Alarm*);
  99. Alarm *alist[NA];
  100. s = splhi();
  101. a = m->alarm;
  102. if(a){
  103. for(n=0; a && a->dt<=0 && n<NA; n++){
  104. alist[n] = a;
  105. delete(&m->alarm, 0, a);
  106. a = m->alarm;
  107. }
  108. if(a)
  109. a->dt--;
  110. for(i = 0; i < n; i++){
  111. f = alist[i]->f; /* avoid race with cancel */
  112. if(f)
  113. (*f)(alist[i]);
  114. alist[i]->busy = 0;
  115. }
  116. }
  117. splx(s);
  118. }