A clone of btpd with my configuration changes.
Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.

132 wiersze
2.6 KiB

  1. #include <time.h>
  2. #include "evloop.h"
  3. #include "timeheap.h"
  4. #if defined(HAVE_CLOCK_MONOTONIC)
  5. #ifdef CLOCK_MONOTONIC_FAST
  6. #define TIMER_CLOCK CLOCK_MONOTONIC_FAST
  7. #else
  8. #define TIMER_CLOCK CLOCK_MONOTONIC
  9. #endif
  10. int
  11. evtimer_gettime(struct timespec *ts)
  12. {
  13. return clock_gettime(TIMER_CLOCK, ts);
  14. }
  15. #elif defined(HAVE_MACH_ABSOLUTE_TIME)
  16. #include <mach/mach_time.h>
  17. int
  18. evtimer_gettime(struct timespec *ts)
  19. {
  20. uint64_t nsecs;
  21. static mach_timebase_info_data_t nsratio = { 0, 0 };
  22. if (nsratio.denom == 0)
  23. mach_timebase_info(&nsratio);
  24. nsecs = mach_absolute_time() * nsratio.numer / nsratio.denom;
  25. ts->tv_sec = nsecs / 1000000000;
  26. ts->tv_nsec = nsecs - ts->tv_sec * 1000000000;
  27. return 0;
  28. }
  29. #else
  30. #error No supported time mechanism
  31. #endif
  32. static struct timespec
  33. addtime(struct timespec a, struct timespec b)
  34. {
  35. struct timespec ret;
  36. ret.tv_sec = a.tv_sec + b.tv_sec;
  37. ret.tv_nsec = a.tv_nsec + b.tv_nsec;
  38. if (ret.tv_nsec >= 1000000000) {
  39. ret.tv_sec += 1;
  40. ret.tv_nsec -= 1000000000;
  41. }
  42. return ret;
  43. }
  44. static struct timespec
  45. subtime(struct timespec a, struct timespec b)
  46. {
  47. struct timespec ret;
  48. ret.tv_sec = a.tv_sec - b.tv_sec;
  49. ret.tv_nsec = a.tv_nsec - b.tv_nsec;
  50. if (ret.tv_nsec < 0) {
  51. ret.tv_sec -= 1;
  52. ret.tv_nsec += 1000000000;
  53. }
  54. return ret;
  55. }
  56. void
  57. evtimer_init(struct timeout *h, evloop_cb_t cb, void *arg)
  58. {
  59. h->cb = cb;
  60. h->arg = arg;
  61. h->th.i = -1;
  62. h->th.data = h;
  63. }
  64. int
  65. evtimer_add(struct timeout *h, struct timespec *t)
  66. {
  67. struct timespec now, sum;
  68. evtimer_gettime(&now);
  69. sum = addtime(now, *t);
  70. if (h->th.i == -1)
  71. return timeheap_insert(&h->th, &sum);
  72. else {
  73. timeheap_change(&h->th, &sum);
  74. return 0;
  75. }
  76. }
  77. void
  78. evtimer_del(struct timeout *h)
  79. {
  80. if (h->th.i >= 0) {
  81. timeheap_remove(&h->th);
  82. h->th.i = -1;
  83. }
  84. }
  85. void
  86. evtimers_run(void)
  87. {
  88. struct timespec now;
  89. evtimer_gettime(&now);
  90. while (timeheap_size() > 0) {
  91. struct timespec diff = subtime(timeheap_top(), now);
  92. if (diff.tv_sec < 0) {
  93. struct timeout *t = timeheap_remove_top();
  94. t->th.i = -1;
  95. t->cb(-1, EV_TIMEOUT, t->arg);
  96. } else
  97. break;
  98. }
  99. }
  100. struct timespec
  101. evtimer_delay(void)
  102. {
  103. struct timespec now, diff;
  104. if (timeheap_size() == 0) {
  105. diff.tv_sec = -1;
  106. diff.tv_nsec = 0;
  107. } else {
  108. evtimer_gettime(&now);
  109. diff = subtime(timeheap_top(), now);
  110. if (diff.tv_sec < 0) {
  111. diff.tv_sec = 0;
  112. diff.tv_nsec = 0;
  113. }
  114. }
  115. return diff;
  116. }