| 62 | } |
| 63 | |
| 64 | static int test(int flags, int expected_ctx, int min_wait, int write_delay, |
| 65 | int nr_cqes, int msec_target) |
| 66 | { |
| 67 | struct io_uring_cqe *cqe; |
| 68 | struct io_uring_sqe *sqe; |
| 69 | struct io_uring ring; |
| 70 | struct __kernel_timespec ts; |
| 71 | struct rusage s, e; |
| 72 | pthread_t thread; |
| 73 | struct d d; |
| 74 | struct io_uring_params p = { .flags = flags, }; |
| 75 | int ret, fds[NPIPES][2], i; |
| 76 | struct timeval start_time; |
| 77 | char buf[32]; |
| 78 | void *tret; |
| 79 | long ttime; |
| 80 | |
| 81 | ret = io_uring_queue_init_params(NPIPES, &ring, &p); |
| 82 | if (ret == -EINVAL) |
| 83 | return T_EXIT_SKIP; |
| 84 | if (!(p.features & IORING_FEAT_MIN_TIMEOUT)) { |
| 85 | no_min_timeout = 1; |
| 86 | return T_EXIT_SKIP; |
| 87 | } |
| 88 | |
| 89 | for (i = 0; i < NPIPES; i++) { |
| 90 | if (pipe(fds[i]) < 0) { |
| 91 | perror("pipe"); |
| 92 | return 1; |
| 93 | } |
| 94 | d.fd[i] = fds[i][1]; |
| 95 | } |
| 96 | |
| 97 | d.delay = write_delay; |
| 98 | pthread_create(&thread, NULL, thread_fn, &d); |
| 99 | |
| 100 | for (i = 0; i < NPIPES; i++) { |
| 101 | sqe = io_uring_get_sqe(&ring); |
| 102 | io_uring_prep_read(sqe, fds[i][0], buf, sizeof(buf), 0); |
| 103 | } |
| 104 | |
| 105 | ts.tv_sec = 0; |
| 106 | ts.tv_nsec = WAIT_USEC * 1000LL; |
| 107 | |
| 108 | gettimeofday(&start_time, NULL); |
| 109 | getrusage(RUSAGE_THREAD, &s); |
| 110 | ret = io_uring_submit_and_wait_min_timeout(&ring, &cqe, 8, &ts, min_wait, NULL); |
| 111 | if (ret != NPIPES) |
| 112 | fprintf(stderr, "submit_and_wait=%d\n", ret); |
| 113 | |
| 114 | getrusage(RUSAGE_THREAD, &e); |
| 115 | e.ru_nvcsw -= s.ru_nvcsw; |
| 116 | ttime = mtime_since_now(&start_time); |
| 117 | if (!within_range(msec_target, ttime)) { |
| 118 | fprintf(stderr, "Expected %d msec, got %ld msec\n", msec_target, |
| 119 | ttime); |
| 120 | fprintf(stderr, "flags=%x, min_wait=%d, write_delay=%d\n", |
| 121 | flags, min_wait, write_delay); |
no test coverage detected