blob: e9d612edd8ff7dffe1c4689822d80443363e4496 [file] [log] [blame]
Jens Axboee5024352020-02-11 20:34:12 -07001/* SPDX-License-Identifier: MIT */
Jens Axboeda869dc2019-11-14 17:24:19 -07002/*
3 * Description: test massive amounts of poll with cancel
4 *
5 */
6#include <errno.h>
7#include <stdio.h>
8#include <unistd.h>
9#include <stdlib.h>
10#include <string.h>
11#include <inttypes.h>
12#include <sys/poll.h>
13#include <sys/wait.h>
14#include <sys/signal.h>
15
16#include "liburing.h"
17
Jens Axboe84b89ca2019-12-04 20:53:01 -070018#define POLL_COUNT 30000
19
20static void *sqe_index[POLL_COUNT];
21
Jens Axboe2454d632020-02-13 09:25:44 -070022static int reap_events(struct io_uring *ring, unsigned nr_events, int nowait)
Jens Axboeda869dc2019-11-14 17:24:19 -070023{
24 struct io_uring_cqe *cqe;
25 int i, ret = 0;
26
27 for (i = 0; i < nr_events; i++) {
Jens Axboe2454d632020-02-13 09:25:44 -070028 if (!i && !nowait)
Jens Axboeda869dc2019-11-14 17:24:19 -070029 ret = io_uring_wait_cqe(ring, &cqe);
30 else
31 ret = io_uring_peek_cqe(ring, &cqe);
32 if (ret) {
33 if (ret != -EAGAIN)
34 fprintf(stderr, "cqe peek failed: %d\n", ret);
35 break;
36 }
37 io_uring_cqe_seen(ring, cqe);
38 }
39
40 return i ? i : ret;
41}
42
43static int del_polls(struct io_uring *ring, int fd, int nr)
44{
Jens Axboe8f24d3c2019-12-02 08:33:07 -070045 int batch, i, ret;
Jens Axboeda869dc2019-11-14 17:24:19 -070046 struct io_uring_sqe *sqe;
47
48 while (nr) {
49 batch = 1024;
50 if (batch > nr)
51 batch = nr;
52
53 for (i = 0; i < batch; i++) {
Jens Axboe84b89ca2019-12-04 20:53:01 -070054 void *data;
55
Jens Axboeda869dc2019-11-14 17:24:19 -070056 sqe = io_uring_get_sqe(ring);
Jens Axboe84b89ca2019-12-04 20:53:01 -070057 data = sqe_index[lrand48() % nr];
58 io_uring_prep_poll_remove(sqe, data);
Jens Axboeda869dc2019-11-14 17:24:19 -070059 }
60
61 ret = io_uring_submit(ring);
62 if (ret != batch) {
63 fprintf(stderr, "%s: failed submit, %d\n", __FUNCTION__, ret);
64 return 1;
65 }
66 nr -= batch;
Jens Axboe2454d632020-02-13 09:25:44 -070067 ret = reap_events(ring, 2 * batch, 0);
Jens Axboeda869dc2019-11-14 17:24:19 -070068 }
69 return 0;
70}
71
72static int add_polls(struct io_uring *ring, int fd, int nr)
73{
74 int pending, batch, i, count, ret;
75 struct io_uring_sqe *sqe;
76
77 pending = count = 0;
78 while (nr) {
79 batch = 1024;
80 if (batch > nr)
81 batch = nr;
82
83 for (i = 0; i < batch; i++) {
84 sqe = io_uring_get_sqe(ring);
85 io_uring_prep_poll_add(sqe, fd, POLLIN);
Jens Axboe84b89ca2019-12-04 20:53:01 -070086 sqe_index[count++] = sqe;
87 sqe->user_data = (unsigned long) sqe;
Jens Axboeda869dc2019-11-14 17:24:19 -070088 }
89
90 ret = io_uring_submit(ring);
91 if (ret != batch) {
92 fprintf(stderr, "%s: failed submit, %d\n", __FUNCTION__, ret);
93 return 1;
94 }
95 nr -= batch;
96 pending += batch;
Jens Axboe2454d632020-02-13 09:25:44 -070097 reap_events(ring, batch, 1);
Jens Axboeda869dc2019-11-14 17:24:19 -070098 }
99 return 0;
100}
101
102int main(int argc, char *argv[])
103{
104 struct io_uring ring;
Jens Axboeccfe96e2021-02-07 09:19:14 -0700105 struct io_uring_params p = { };
Jens Axboeda869dc2019-11-14 17:24:19 -0700106 int pipe1[2];
107 int ret;
108
Jens Axboea2141fc2020-05-19 17:36:19 -0600109 if (argc > 1)
110 return 0;
111
Jens Axboeda869dc2019-11-14 17:24:19 -0700112 if (pipe(pipe1) != 0) {
Jens Axboea8dc4972020-02-01 09:58:07 -0700113 perror("pipe");
Jens Axboeda869dc2019-11-14 17:24:19 -0700114 return 1;
115 }
116
Jens Axboeccfe96e2021-02-07 09:19:14 -0700117 p.flags = IORING_SETUP_CQSIZE;
118 p.cq_entries = 16384;
119 ret = io_uring_queue_init_params(1024, &ring, &p);
Jens Axboeda869dc2019-11-14 17:24:19 -0700120 if (ret) {
Jens Axboeccfe96e2021-02-07 09:19:14 -0700121 if (ret == -EINVAL) {
122 fprintf(stdout, "No CQSIZE, trying without\n");
123 ret = io_uring_queue_init(1024, &ring, 0);
124 if (ret) {
125 fprintf(stderr, "ring setup failed: %d\n", ret);
126 return 1;
127 }
128 }
Jens Axboeda869dc2019-11-14 17:24:19 -0700129 }
130
131 add_polls(&ring, pipe1[0], 30000);
132#if 0
133 usleep(1000);
134#endif
135 del_polls(&ring, pipe1[0], 30000);
136
137 io_uring_queue_exit(&ring);
138 return 0;
139}