poll-cancel-ton.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. #include "../config-host.h"
  2. /* SPDX-License-Identifier: MIT */
  3. /*
  4. * Description: test massive amounts of poll with cancel
  5. *
  6. */
  7. #include <errno.h>
  8. #include <stdio.h>
  9. #include <unistd.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <inttypes.h>
  13. #include <poll.h>
  14. #include <sys/wait.h>
  15. #include <signal.h>
  16. #include "liburing.h"
  17. #define POLL_COUNT 30000
  18. static void *sqe_index[POLL_COUNT];
  19. static int reap_events(struct io_uring *ring, unsigned nr_events, int nowait)
  20. {
  21. struct io_uring_cqe *cqe;
  22. int i, ret = 0;
  23. for (i = 0; i < nr_events; i++) {
  24. if (!i && !nowait)
  25. ret = io_uring_wait_cqe(ring, &cqe);
  26. else
  27. ret = io_uring_peek_cqe(ring, &cqe);
  28. if (ret) {
  29. if (ret != -EAGAIN)
  30. fprintf(stderr, "cqe peek failed: %d\n", ret);
  31. break;
  32. }
  33. io_uring_cqe_seen(ring, cqe);
  34. }
  35. return i ? i : ret;
  36. }
  37. static int del_polls(struct io_uring *ring, int fd, int nr)
  38. {
  39. int batch, i, ret;
  40. struct io_uring_sqe *sqe;
  41. while (nr) {
  42. batch = 1024;
  43. if (batch > nr)
  44. batch = nr;
  45. for (i = 0; i < batch; i++) {
  46. void *data;
  47. sqe = io_uring_get_sqe(ring);
  48. data = sqe_index[lrand48() % nr];
  49. io_uring_prep_poll_remove(sqe, (__u64)(uintptr_t)data);
  50. }
  51. ret = io_uring_submit(ring);
  52. if (ret != batch) {
  53. fprintf(stderr, "%s: failed submit, %d\n", __FUNCTION__, ret);
  54. return 1;
  55. }
  56. nr -= batch;
  57. ret = reap_events(ring, 2 * batch, 0);
  58. }
  59. return 0;
  60. }
  61. static int add_polls(struct io_uring *ring, int fd, int nr)
  62. {
  63. int batch, i, count, ret;
  64. struct io_uring_sqe *sqe;
  65. count = 0;
  66. while (nr) {
  67. batch = 1024;
  68. if (batch > nr)
  69. batch = nr;
  70. for (i = 0; i < batch; i++) {
  71. sqe = io_uring_get_sqe(ring);
  72. io_uring_prep_poll_add(sqe, fd, POLLIN);
  73. sqe_index[count++] = sqe;
  74. sqe->user_data = (unsigned long) sqe;
  75. }
  76. ret = io_uring_submit(ring);
  77. if (ret != batch) {
  78. fprintf(stderr, "%s: failed submit, %d\n", __FUNCTION__, ret);
  79. return 1;
  80. }
  81. nr -= batch;
  82. reap_events(ring, batch, 1);
  83. }
  84. return 0;
  85. }
  86. int main(int argc, char *argv[])
  87. {
  88. struct io_uring ring;
  89. struct io_uring_params p = { };
  90. int pipe1[2];
  91. int ret;
  92. if (argc > 1)
  93. return 0;
  94. if (pipe(pipe1) != 0) {
  95. perror("pipe");
  96. return 1;
  97. }
  98. p.flags = IORING_SETUP_CQSIZE;
  99. p.cq_entries = 16384;
  100. ret = io_uring_queue_init_params(1024, &ring, &p);
  101. if (ret) {
  102. if (ret == -EINVAL) {
  103. fprintf(stdout, "No CQSIZE, trying without\n");
  104. ret = io_uring_queue_init(1024, &ring, 0);
  105. if (ret) {
  106. fprintf(stderr, "ring setup failed: %d\n", ret);
  107. return 1;
  108. }
  109. }
  110. }
  111. add_polls(&ring, pipe1[0], 30000);
  112. del_polls(&ring, pipe1[0], 30000);
  113. io_uring_queue_exit(&ring);
  114. return 0;
  115. }