| 234 | } |
| 235 | |
| 236 | static int test_race(int flags) |
| 237 | { |
| 238 | struct io_uring_cqe *cqe; |
| 239 | struct io_uring_sqe *sqe; |
| 240 | struct io_uring ring; |
| 241 | struct d d; |
| 242 | struct epoll_event ev; |
| 243 | struct epoll_event out[NPIPES]; |
| 244 | pthread_t thread; |
| 245 | int i, efd, ret; |
| 246 | void *tret; |
| 247 | int sqe_id = 0; |
| 248 | int submitted = 0, completed = 0; |
| 249 | int sqe_ids[MAX_QE]; |
| 250 | int cqe_ids[MAX_QE]; |
| 251 | |
| 252 | ret = t_create_ring(32, &ring, flags); |
| 253 | if (ret == T_SETUP_SKIP) { |
| 254 | return 0; |
| 255 | } else if (ret != T_SETUP_OK) { |
| 256 | fprintf(stderr, "ring create failed %x -> %d\n", flags, ret); |
| 257 | return 1; |
| 258 | } |
| 259 | |
| 260 | for (i = 0; i < NPIPES; i++) { |
| 261 | if (pipe(d.pipes[i]) < 0) { |
| 262 | perror("pipe"); |
| 263 | return 1; |
| 264 | } |
| 265 | } |
| 266 | |
| 267 | efd = epoll_create1(0); |
| 268 | if (efd < 0) { |
| 269 | perror("epoll_create"); |
| 270 | return T_EXIT_FAIL; |
| 271 | } |
| 272 | |
| 273 | for (i = 0; i < NPIPES; i++) { |
| 274 | ev.events = EPOLLIN; |
| 275 | ev.data.fd = d.pipes[i][0]; |
| 276 | ret = epoll_ctl(efd, EPOLL_CTL_ADD, d.pipes[i][0], &ev); |
| 277 | if (ret < 0) { |
| 278 | perror("epoll_ctl"); |
| 279 | return T_EXIT_FAIL; |
| 280 | } |
| 281 | } |
| 282 | |
| 283 | sqe = io_uring_get_sqe(&ring); |
| 284 | io_uring_prep_epoll_wait(sqe, efd, out, NPIPES, 0); |
| 285 | io_uring_submit(&ring); |
| 286 | |
| 287 | atomic_store(&keep_running, true); |
| 288 | pthread_create(&thread, NULL, thread_fn, &d); |
| 289 | |
| 290 | while (completed < 1000) { |
| 291 | io_uring_submit_and_wait(&ring, 1); |
| 292 | sqe_ids[submitted] = sqe->user_data; |
| 293 | ret = io_uring_wait_cqe(&ring, &cqe); |
no test coverage detected