test_vfs_eventfd.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  1. /*
  2. * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include <errno.h>
  7. #include <sys/select.h>
  8. #include "freertos/FreeRTOS.h"
  9. #include "unity.h"
  10. #include "driver/gptimer.h"
  11. #include "esp_vfs.h"
  12. #include "esp_vfs_eventfd.h"
  13. TEST_CASE("eventfd create and close", "[vfs][eventfd]")
  14. {
  15. esp_vfs_eventfd_config_t config = ESP_VFS_EVENTD_CONFIG_DEFAULT();
  16. TEST_ESP_OK(esp_vfs_eventfd_register(&config));
  17. int fd = eventfd(0, 0);
  18. TEST_ASSERT_GREATER_OR_EQUAL(0, fd);
  19. TEST_ASSERT_EQUAL(0, close(fd));
  20. fd = eventfd(0, EFD_SUPPORT_ISR);
  21. TEST_ASSERT_GREATER_OR_EQUAL(0, fd);
  22. TEST_ASSERT_EQUAL(0, close(fd));
  23. TEST_ESP_OK(esp_vfs_eventfd_unregister());
  24. }
  25. TEST_CASE("eventfd reject unknown flags", "[vfs][eventfd]")
  26. {
  27. esp_vfs_eventfd_config_t config = ESP_VFS_EVENTD_CONFIG_DEFAULT();
  28. TEST_ESP_OK(esp_vfs_eventfd_register(&config));
  29. int fd = eventfd(0, 1);
  30. TEST_ASSERT_LESS_THAN(0, fd);
  31. TEST_ASSERT_EQUAL(EINVAL, errno);
  32. fd = eventfd(0, INT_MAX);
  33. TEST_ASSERT_LESS_THAN(0, fd);
  34. TEST_ASSERT_EQUAL(EINVAL, errno);
  35. TEST_ESP_OK(esp_vfs_eventfd_unregister());
  36. }
  37. TEST_CASE("eventfd read", "[vfs][eventfd]")
  38. {
  39. esp_vfs_eventfd_config_t config = ESP_VFS_EVENTD_CONFIG_DEFAULT();
  40. TEST_ESP_OK(esp_vfs_eventfd_register(&config));
  41. unsigned int initval = 123;
  42. int fd = eventfd(initval, 0);
  43. TEST_ASSERT_GREATER_OR_EQUAL(0, fd);
  44. uint64_t val = 0;
  45. TEST_ASSERT_EQUAL(sizeof(val), read(fd, &val, sizeof(val)));
  46. TEST_ASSERT_EQUAL(initval, val);
  47. TEST_ASSERT_EQUAL(sizeof(val), read(fd, &val, sizeof(val)));
  48. TEST_ASSERT_EQUAL(0, val);
  49. TEST_ASSERT_EQUAL(0, close(fd));
  50. TEST_ESP_OK(esp_vfs_eventfd_unregister());
  51. }
  52. TEST_CASE("eventfd read invalid size", "[vfs][eventfd]")
  53. {
  54. esp_vfs_eventfd_config_t config = ESP_VFS_EVENTD_CONFIG_DEFAULT();
  55. TEST_ESP_OK(esp_vfs_eventfd_register(&config));
  56. int fd = eventfd(0, 0);
  57. TEST_ASSERT_GREATER_OR_EQUAL(0, fd);
  58. uint32_t val = 0;
  59. TEST_ASSERT_LESS_THAN(0, read(fd, &val, sizeof(val)));
  60. TEST_ASSERT_EQUAL(EINVAL, errno);
  61. TEST_ASSERT_EQUAL(0, close(fd));
  62. TEST_ESP_OK(esp_vfs_eventfd_unregister());
  63. }
  64. TEST_CASE("eventfd write invalid size", "[vfs][eventfd]")
  65. {
  66. esp_vfs_eventfd_config_t config = ESP_VFS_EVENTD_CONFIG_DEFAULT();
  67. TEST_ESP_OK(esp_vfs_eventfd_register(&config));
  68. int fd = eventfd(0, 0);
  69. TEST_ASSERT_GREATER_OR_EQUAL(0, fd);
  70. uint32_t val = 0;
  71. TEST_ASSERT_LESS_THAN(0, write(fd, &val, sizeof(val)));
  72. TEST_ASSERT_EQUAL(EINVAL, errno);
  73. TEST_ASSERT_EQUAL(0, close(fd));
  74. TEST_ESP_OK(esp_vfs_eventfd_unregister());
  75. }
  76. TEST_CASE("eventfd write then read", "[vfs][eventfd]")
  77. {
  78. esp_vfs_eventfd_config_t config = ESP_VFS_EVENTD_CONFIG_DEFAULT();
  79. TEST_ESP_OK(esp_vfs_eventfd_register(&config));
  80. int fd = eventfd(0, 0);
  81. TEST_ASSERT_GREATER_OR_EQUAL(0, fd);
  82. uint64_t val = 123;
  83. TEST_ASSERT_EQUAL(sizeof(val), write(fd, &val, sizeof(val)));
  84. TEST_ASSERT_EQUAL(sizeof(val), read(fd, &val, sizeof(val)));
  85. TEST_ASSERT_EQUAL(123, val);
  86. val = 4;
  87. TEST_ASSERT_EQUAL(sizeof(val), write(fd, &val, sizeof(val)));
  88. val = 5;
  89. TEST_ASSERT_EQUAL(sizeof(val), write(fd, &val, sizeof(val)));
  90. TEST_ASSERT_EQUAL(sizeof(val), read(fd, &val, sizeof(val)));
  91. TEST_ASSERT_EQUAL(9, val);
  92. TEST_ASSERT_EQUAL(0, close(fd));
  93. TEST_ESP_OK(esp_vfs_eventfd_unregister());
  94. }
  95. TEST_CASE("eventfd instant select", "[vfs][eventfd]")
  96. {
  97. esp_vfs_eventfd_config_t config = ESP_VFS_EVENTD_CONFIG_DEFAULT();
  98. TEST_ESP_OK(esp_vfs_eventfd_register(&config));
  99. int fd = eventfd(0, 0);
  100. TEST_ASSERT_GREATER_OR_EQUAL(0, fd);
  101. struct timeval zero_time;
  102. fd_set read_fds, write_fds, error_fds;
  103. zero_time.tv_sec = 0;
  104. zero_time.tv_usec = 0;
  105. FD_ZERO(&read_fds);
  106. FD_ZERO(&write_fds);
  107. FD_ZERO(&error_fds);
  108. FD_SET(fd, &read_fds);
  109. int ret = select(fd + 1, &read_fds, &write_fds, &error_fds, &zero_time);
  110. TEST_ASSERT_EQUAL(0, ret);
  111. TEST_ASSERT(!FD_ISSET(fd, &read_fds));
  112. uint64_t val = 1;
  113. TEST_ASSERT_EQUAL(sizeof(val), write(fd, &val, sizeof(val)));
  114. FD_ZERO(&read_fds);
  115. FD_ZERO(&write_fds);
  116. FD_ZERO(&error_fds);
  117. FD_SET(fd, &read_fds);
  118. ret = select(fd + 1, &read_fds, &write_fds, &error_fds, &zero_time);
  119. TEST_ASSERT_EQUAL(1, ret);
  120. TEST_ASSERT(FD_ISSET(fd, &read_fds));
  121. TEST_ASSERT_EQUAL(sizeof(val), read(fd, &val, sizeof(val)));
  122. FD_ZERO(&read_fds);
  123. FD_ZERO(&write_fds);
  124. FD_ZERO(&error_fds);
  125. FD_SET(fd, &read_fds);
  126. ret = select(fd + 1, &read_fds, &write_fds, &error_fds, &zero_time);
  127. TEST_ASSERT_EQUAL(0, ret);
  128. TEST_ASSERT(!FD_ISSET(fd, &read_fds));
  129. TEST_ASSERT_EQUAL(0, close(fd));
  130. TEST_ESP_OK(esp_vfs_eventfd_unregister());
  131. }
  132. static void signal_task(void *arg)
  133. {
  134. int fd = *((int *)arg);
  135. vTaskDelay(pdMS_TO_TICKS(1000));
  136. uint64_t val = 1;
  137. TEST_ASSERT_EQUAL(sizeof(val), write(fd, &val, sizeof(val)));
  138. vTaskDelete(NULL);
  139. }
  140. TEST_CASE("eventfd signal from task", "[vfs][eventfd]")
  141. {
  142. esp_vfs_eventfd_config_t config = ESP_VFS_EVENTD_CONFIG_DEFAULT();
  143. TEST_ESP_OK(esp_vfs_eventfd_register(&config));
  144. int fd0 = eventfd(0, 0);
  145. int fd1 = eventfd(0, 0);
  146. int max_fd = fd1 > fd0 ? fd1 : fd0;
  147. TEST_ASSERT_GREATER_OR_EQUAL(0, fd0);
  148. TEST_ASSERT_GREATER_OR_EQUAL(0, fd1);
  149. xTaskCreate(signal_task, "signal_task", 2048, &fd0, 5, NULL);
  150. struct timeval wait_time;
  151. struct timeval zero_time;
  152. fd_set read_fds;
  153. FD_ZERO(&read_fds);
  154. FD_SET(fd0, &read_fds);
  155. FD_SET(fd1, &read_fds);
  156. wait_time.tv_sec = 2;
  157. wait_time.tv_usec = 0;
  158. zero_time.tv_sec = 0;
  159. zero_time.tv_usec = 0;
  160. int ret = select(max_fd + 1, &read_fds, NULL, NULL, &wait_time);
  161. TEST_ASSERT_EQUAL(1, ret);
  162. TEST_ASSERT(FD_ISSET(fd0, &read_fds));
  163. uint64_t val = 1;
  164. TEST_ASSERT_EQUAL(sizeof(val), write(fd1, &val, sizeof(val)));
  165. FD_ZERO(&read_fds);
  166. FD_SET(fd0, &read_fds);
  167. FD_SET(fd1, &read_fds);
  168. ret = select(max_fd + 1, &read_fds, NULL, NULL, &zero_time);
  169. TEST_ASSERT_EQUAL(2, ret);
  170. TEST_ASSERT(FD_ISSET(fd0, &read_fds));
  171. TEST_ASSERT(FD_ISSET(fd1, &read_fds));
  172. TEST_ASSERT_EQUAL(0, close(fd0));
  173. TEST_ASSERT_EQUAL(0, close(fd1));
  174. TEST_ESP_OK(esp_vfs_eventfd_unregister());
  175. }
  176. static bool eventfd_select_test_isr(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_ctx)
  177. {
  178. gptimer_stop(timer);
  179. int fd = *((int *)user_ctx);
  180. uint64_t val = 1;
  181. int ret = write(fd, &val, sizeof(val));
  182. assert(ret == sizeof(val));
  183. return true;
  184. }
  185. TEST_CASE("eventfd signal from ISR", "[vfs][eventfd]")
  186. {
  187. esp_vfs_eventfd_config_t config = ESP_VFS_EVENTD_CONFIG_DEFAULT();
  188. TEST_ESP_OK(esp_vfs_eventfd_register(&config));
  189. int fd = eventfd(0, EFD_SUPPORT_ISR);
  190. TEST_ASSERT_GREATER_OR_EQUAL(0, fd);
  191. gptimer_handle_t gptimer = NULL;
  192. gptimer_config_t timer_config = {
  193. .clk_src = GPTIMER_CLK_SRC_DEFAULT,
  194. .direction = GPTIMER_COUNT_UP,
  195. .resolution_hz = 1000000,
  196. };
  197. TEST_ESP_OK(gptimer_new_timer(&timer_config, &gptimer));
  198. gptimer_alarm_config_t alarm_config = {
  199. .reload_count = 0,
  200. .alarm_count = 200000,
  201. };
  202. gptimer_event_callbacks_t cbs = {
  203. .on_alarm = eventfd_select_test_isr,
  204. };
  205. TEST_ESP_OK(gptimer_register_event_callbacks(gptimer, &cbs, &fd));
  206. TEST_ESP_OK(gptimer_set_alarm_action(gptimer, &alarm_config));
  207. TEST_ESP_OK(gptimer_enable(gptimer));
  208. TEST_ESP_OK(gptimer_start(gptimer));
  209. struct timeval wait_time;
  210. fd_set read_fds, write_fds, error_fds;
  211. FD_ZERO(&read_fds);
  212. FD_ZERO(&write_fds);
  213. FD_ZERO(&error_fds);
  214. FD_SET(fd, &read_fds);
  215. wait_time.tv_sec = 2;
  216. wait_time.tv_usec = 0;
  217. FD_SET(fd, &read_fds);
  218. int ret = select(fd + 1, &read_fds, &write_fds, &error_fds, &wait_time);
  219. TEST_ASSERT_EQUAL(1, ret);
  220. TEST_ASSERT(FD_ISSET(fd, &read_fds));
  221. TEST_ASSERT_EQUAL(0, close(fd));
  222. TEST_ESP_OK(esp_vfs_eventfd_unregister());
  223. TEST_ESP_OK(gptimer_disable(gptimer));
  224. TEST_ESP_OK(gptimer_del_timer(gptimer));
  225. }
  226. static void close_task(void *arg)
  227. {
  228. int fd = *((int *)arg);
  229. vTaskDelay(pdMS_TO_TICKS(1000));
  230. TEST_ASSERT_EQUAL(0, close(fd));
  231. vTaskDelete(NULL);
  232. }
  233. TEST_CASE("eventfd select closed fd", "[vfs][eventfd]")
  234. {
  235. esp_vfs_eventfd_config_t config = ESP_VFS_EVENTD_CONFIG_DEFAULT();
  236. TEST_ESP_OK(esp_vfs_eventfd_register(&config));
  237. int fd = eventfd(0, 0);
  238. TEST_ASSERT_GREATER_OR_EQUAL(0, fd);
  239. xTaskCreate(close_task, "close_task", 2048, &fd, 5, NULL);
  240. struct timeval wait_time;
  241. fd_set read_fds, write_fds, error_fds;
  242. FD_ZERO(&read_fds);
  243. FD_ZERO(&write_fds);
  244. FD_ZERO(&error_fds);
  245. FD_SET(fd, &read_fds);
  246. FD_SET(fd, &error_fds);
  247. wait_time.tv_sec = 2;
  248. wait_time.tv_usec = 0;
  249. int ret = select(fd + 1, &read_fds, &write_fds, &error_fds, &wait_time);
  250. TEST_ASSERT_EQUAL(1, ret);
  251. TEST_ASSERT(FD_ISSET(fd, &error_fds));
  252. TEST_ESP_OK(esp_vfs_eventfd_unregister());
  253. }
  254. typedef struct {
  255. QueueHandle_t queue;
  256. int fd;
  257. } select_task_args_t;
  258. static void select_task(void *arg)
  259. {
  260. select_task_args_t *select_arg = (select_task_args_t *)arg;
  261. int fd = select_arg->fd;
  262. struct timeval wait_time;
  263. fd_set read_fds;
  264. FD_ZERO(&read_fds);
  265. FD_SET(fd, &read_fds);
  266. wait_time.tv_sec = 2;
  267. wait_time.tv_usec = 0;
  268. int ret = select(fd + 1, &read_fds, NULL, NULL, &wait_time);
  269. assert(ret == 1);
  270. xQueueSend(select_arg->queue, select_arg, 0);
  271. vTaskDelete(NULL);
  272. }
  273. TEST_CASE("eventfd multiple selects", "[vfs][eventfd]")
  274. {
  275. esp_vfs_eventfd_config_t config = ESP_VFS_EVENTD_CONFIG_DEFAULT();
  276. TEST_ESP_OK(esp_vfs_eventfd_register(&config));
  277. int fd = eventfd(0, 0);
  278. TEST_ASSERT_GREATER_OR_EQUAL(0, fd);
  279. select_task_args_t args = {
  280. .queue = xQueueCreate(10, sizeof(select_task_args_t)),
  281. .fd = fd,
  282. };
  283. select_task_args_t ret_args;
  284. xTaskCreate(select_task, "select_task0", 2048, &args, 5, NULL);
  285. xTaskCreate(select_task, "select_task1", 2048, &args, 5, NULL);
  286. uint64_t val = 1;
  287. TEST_ASSERT_EQUAL(sizeof(val), write(fd, &val, sizeof(val)));
  288. vTaskDelay(pdMS_TO_TICKS(100));
  289. TEST_ASSERT(xQueueReceive(args.queue, &ret_args, 0));
  290. TEST_ASSERT_EQUAL(ret_args.fd, fd);
  291. TEST_ASSERT(xQueueReceive(args.queue, &ret_args, 0));
  292. TEST_ASSERT_EQUAL(ret_args.fd, fd);
  293. vQueueDelete(args.queue);
  294. TEST_ASSERT_EQUAL(0, close(fd));
  295. TEST_ESP_OK(esp_vfs_eventfd_unregister());
  296. }