test_timers.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. #include "test_timers.h"
  2. #include "lwip/def.h"
  3. #include "lwip/timeouts.h"
  4. #include "arch/sys_arch.h"
  5. /* Setups/teardown functions */
  6. static struct sys_timeo* old_list_head;
  7. static void
  8. timers_setup(void)
  9. {
  10. struct sys_timeo** list_head = sys_timeouts_get_next_timeout();
  11. old_list_head = *list_head;
  12. *list_head = NULL;
  13. }
  14. static void
  15. timers_teardown(void)
  16. {
  17. struct sys_timeo** list_head = sys_timeouts_get_next_timeout();
  18. *list_head = old_list_head;
  19. lwip_sys_now = 0;
  20. }
  21. static int fired[3];
  22. static void
  23. dummy_handler(void* arg)
  24. {
  25. int index = LWIP_PTR_NUMERIC_CAST(int, arg);
  26. fired[index] = 1;
  27. }
  28. #define HANDLER_EXECUTION_TIME 5
  29. static int cyclic_fired;
  30. static void
  31. dummy_cyclic_handler(void)
  32. {
  33. cyclic_fired = 1;
  34. lwip_sys_now += HANDLER_EXECUTION_TIME;
  35. }
  36. struct lwip_cyclic_timer test_cyclic = {10, dummy_cyclic_handler};
  37. static void
  38. do_test_cyclic_timers(u32_t offset)
  39. {
  40. struct sys_timeo** list_head = sys_timeouts_get_next_timeout();
  41. /* verify normal timer expiration */
  42. lwip_sys_now = offset + 0;
  43. sys_timeout(test_cyclic.interval_ms, lwip_cyclic_timer, &test_cyclic);
  44. cyclic_fired = 0;
  45. sys_check_timeouts();
  46. fail_unless(cyclic_fired == 0);
  47. lwip_sys_now = offset + test_cyclic.interval_ms;
  48. sys_check_timeouts();
  49. fail_unless(cyclic_fired == 1);
  50. fail_unless((*list_head)->time == (u32_t)(lwip_sys_now + test_cyclic.interval_ms - HANDLER_EXECUTION_TIME));
  51. sys_untimeout(lwip_cyclic_timer, &test_cyclic);
  52. /* verify "overload" - next cyclic timer execution is already overdue twice */
  53. lwip_sys_now = offset + 0;
  54. sys_timeout(test_cyclic.interval_ms, lwip_cyclic_timer, &test_cyclic);
  55. cyclic_fired = 0;
  56. sys_check_timeouts();
  57. fail_unless(cyclic_fired == 0);
  58. lwip_sys_now = offset + 2*test_cyclic.interval_ms;
  59. sys_check_timeouts();
  60. fail_unless(cyclic_fired == 1);
  61. fail_unless((*list_head)->time == (u32_t)(lwip_sys_now + test_cyclic.interval_ms));
  62. }
  63. START_TEST(test_cyclic_timers)
  64. {
  65. LWIP_UNUSED_ARG(_i);
  66. /* check without u32_t wraparound */
  67. do_test_cyclic_timers(0);
  68. /* check with u32_t wraparound */
  69. do_test_cyclic_timers(0xfffffff0);
  70. }
  71. END_TEST
  72. /* reproduce bug #52748: the bug in timeouts.c */
  73. START_TEST(test_bug52748)
  74. {
  75. LWIP_UNUSED_ARG(_i);
  76. memset(&fired, 0, sizeof(fired));
  77. lwip_sys_now = 50;
  78. sys_timeout(20, dummy_handler, LWIP_PTR_NUMERIC_CAST(void*, 0));
  79. sys_timeout( 5, dummy_handler, LWIP_PTR_NUMERIC_CAST(void*, 2));
  80. lwip_sys_now = 55;
  81. sys_check_timeouts();
  82. fail_unless(fired[0] == 0);
  83. fail_unless(fired[1] == 0);
  84. fail_unless(fired[2] == 1);
  85. lwip_sys_now = 60;
  86. sys_timeout(10, dummy_handler, LWIP_PTR_NUMERIC_CAST(void*, 1));
  87. sys_check_timeouts();
  88. fail_unless(fired[0] == 0);
  89. fail_unless(fired[1] == 0);
  90. fail_unless(fired[2] == 1);
  91. lwip_sys_now = 70;
  92. sys_check_timeouts();
  93. fail_unless(fired[0] == 1);
  94. fail_unless(fired[1] == 1);
  95. fail_unless(fired[2] == 1);
  96. }
  97. END_TEST
  98. static void
  99. do_test_timers(u32_t offset)
  100. {
  101. struct sys_timeo** list_head = sys_timeouts_get_next_timeout();
  102. lwip_sys_now = offset + 0;
  103. sys_timeout(10, dummy_handler, LWIP_PTR_NUMERIC_CAST(void*, 0));
  104. fail_unless(sys_timeouts_sleeptime() == 10);
  105. sys_timeout(20, dummy_handler, LWIP_PTR_NUMERIC_CAST(void*, 1));
  106. fail_unless(sys_timeouts_sleeptime() == 10);
  107. sys_timeout( 5, dummy_handler, LWIP_PTR_NUMERIC_CAST(void*, 2));
  108. fail_unless(sys_timeouts_sleeptime() == 5);
  109. /* linked list correctly sorted? */
  110. fail_unless((*list_head)->time == (u32_t)(lwip_sys_now + 5));
  111. fail_unless((*list_head)->next->time == (u32_t)(lwip_sys_now + 10));
  112. fail_unless((*list_head)->next->next->time == (u32_t)(lwip_sys_now + 20));
  113. /* check timers expire in correct order */
  114. memset(&fired, 0, sizeof(fired));
  115. lwip_sys_now += 4;
  116. sys_check_timeouts();
  117. fail_unless(fired[2] == 0);
  118. lwip_sys_now += 1;
  119. sys_check_timeouts();
  120. fail_unless(fired[2] == 1);
  121. lwip_sys_now += 4;
  122. sys_check_timeouts();
  123. fail_unless(fired[0] == 0);
  124. lwip_sys_now += 1;
  125. sys_check_timeouts();
  126. fail_unless(fired[0] == 1);
  127. lwip_sys_now += 9;
  128. sys_check_timeouts();
  129. fail_unless(fired[1] == 0);
  130. lwip_sys_now += 1;
  131. sys_check_timeouts();
  132. fail_unless(fired[1] == 1);
  133. sys_untimeout(dummy_handler, LWIP_PTR_NUMERIC_CAST(void*, 0));
  134. sys_untimeout(dummy_handler, LWIP_PTR_NUMERIC_CAST(void*, 1));
  135. sys_untimeout(dummy_handler, LWIP_PTR_NUMERIC_CAST(void*, 2));
  136. }
  137. START_TEST(test_timers)
  138. {
  139. LWIP_UNUSED_ARG(_i);
  140. /* check without u32_t wraparound */
  141. do_test_timers(0);
  142. /* check with u32_t wraparound */
  143. do_test_timers(0xfffffff0);
  144. }
  145. END_TEST
  146. START_TEST(test_long_timer)
  147. {
  148. LWIP_UNUSED_ARG(_i);
  149. memset(&fired, 0, sizeof(fired));
  150. lwip_sys_now = 0;
  151. sys_timeout(LWIP_UINT32_MAX / 4, dummy_handler, LWIP_PTR_NUMERIC_CAST(void*, 0));
  152. fail_unless(sys_timeouts_sleeptime() == LWIP_UINT32_MAX / 4);
  153. sys_check_timeouts();
  154. fail_unless(fired[0] == 0);
  155. lwip_sys_now += LWIP_UINT32_MAX / 8;
  156. sys_check_timeouts();
  157. fail_unless(fired[0] == 0);
  158. lwip_sys_now += LWIP_UINT32_MAX / 8;
  159. sys_check_timeouts();
  160. fail_unless(fired[0] == 0);
  161. lwip_sys_now += 1;
  162. sys_check_timeouts();
  163. fail_unless(fired[0] == 1);
  164. sys_untimeout(dummy_handler, LWIP_PTR_NUMERIC_CAST(void*, 0));
  165. }
  166. END_TEST
  167. /** Create the suite including all tests for this module */
  168. Suite *
  169. timers_suite(void)
  170. {
  171. testfunc tests[] = {
  172. TESTFUNC(test_bug52748),
  173. TESTFUNC(test_cyclic_timers),
  174. TESTFUNC(test_timers),
  175. TESTFUNC(test_long_timer),
  176. };
  177. return create_suite("TIMERS", tests, LWIP_ARRAYSIZE(tests), timers_setup, timers_teardown);
  178. }