Blame test/poll-cancel-ton.c

Packit d3489f
/* SPDX-License-Identifier: MIT */
Packit d3489f
/*
Packit d3489f
 * Description: test massive amounts of poll with cancel
Packit d3489f
 *
Packit d3489f
 */
Packit d3489f
#include <errno.h>
Packit d3489f
#include <stdio.h>
Packit d3489f
#include <unistd.h>
Packit d3489f
#include <stdlib.h>
Packit d3489f
#include <string.h>
Packit d3489f
#include <inttypes.h>
Packit d3489f
#include <sys/poll.h>
Packit d3489f
#include <sys/wait.h>
Packit d3489f
#include <sys/signal.h>
Packit d3489f
Packit d3489f
#include "liburing.h"
Packit d3489f
Packit d3489f
#define POLL_COUNT	30000
Packit d3489f
Packit d3489f
static void *sqe_index[POLL_COUNT];
Packit d3489f
Packit d3489f
static int reap_events(struct io_uring *ring, unsigned nr_events, int nowait)
Packit d3489f
{
Packit d3489f
	struct io_uring_cqe *cqe;
Packit d3489f
	int i, ret = 0;
Packit d3489f
Packit d3489f
	for (i = 0; i < nr_events; i++) {
Packit d3489f
		if (!i && !nowait)
Packit d3489f
			ret = io_uring_wait_cqe(ring, &cqe);
Packit d3489f
		else
Packit d3489f
			ret = io_uring_peek_cqe(ring, &cqe);
Packit d3489f
		if (ret) {
Packit d3489f
			if (ret != -EAGAIN)
Packit d3489f
				fprintf(stderr, "cqe peek failed: %d\n", ret);
Packit d3489f
			break;
Packit d3489f
		}
Packit d3489f
		io_uring_cqe_seen(ring, cqe);
Packit d3489f
	}
Packit d3489f
Packit d3489f
	return i ? i : ret;
Packit d3489f
}
Packit d3489f
Packit d3489f
static int del_polls(struct io_uring *ring, int fd, int nr)
Packit d3489f
{
Packit d3489f
	int batch, i, ret;
Packit d3489f
	struct io_uring_sqe *sqe;
Packit d3489f
Packit d3489f
	while (nr) {
Packit d3489f
		batch = 1024;
Packit d3489f
		if (batch > nr)
Packit d3489f
			batch = nr;
Packit d3489f
Packit d3489f
		for (i = 0; i < batch; i++) {
Packit d3489f
			void *data;
Packit d3489f
Packit d3489f
			sqe = io_uring_get_sqe(ring);
Packit d3489f
			data = sqe_index[lrand48() % nr];
Packit d3489f
			io_uring_prep_poll_remove(sqe, data);
Packit d3489f
		}
Packit d3489f
Packit d3489f
		ret = io_uring_submit(ring);
Packit d3489f
		if (ret != batch) {
Packit d3489f
			fprintf(stderr, "%s: failed submit, %d\n", __FUNCTION__, ret);
Packit d3489f
			return 1;
Packit d3489f
		}
Packit d3489f
		nr -= batch;
Packit d3489f
		ret = reap_events(ring, 2 * batch, 0);
Packit d3489f
	}
Packit d3489f
	return 0;
Packit d3489f
}
Packit d3489f
Packit d3489f
static int add_polls(struct io_uring *ring, int fd, int nr)
Packit d3489f
{
Packit d3489f
	int pending, batch, i, count, ret;
Packit d3489f
	struct io_uring_sqe *sqe;
Packit d3489f
Packit d3489f
	pending = count = 0;
Packit d3489f
	while (nr) {
Packit d3489f
		batch = 1024;
Packit d3489f
		if (batch > nr)
Packit d3489f
			batch = nr;
Packit d3489f
Packit d3489f
		for (i = 0; i < batch; i++) {
Packit d3489f
			sqe = io_uring_get_sqe(ring);
Packit d3489f
			io_uring_prep_poll_add(sqe, fd, POLLIN);
Packit d3489f
			sqe_index[count++] = sqe;
Packit d3489f
			sqe->user_data = (unsigned long) sqe;
Packit d3489f
		}
Packit d3489f
Packit d3489f
		ret = io_uring_submit(ring);
Packit d3489f
		if (ret != batch) {
Packit d3489f
			fprintf(stderr, "%s: failed submit, %d\n", __FUNCTION__, ret);
Packit d3489f
			return 1;
Packit d3489f
		}
Packit d3489f
		nr -= batch;
Packit d3489f
		pending += batch;
Packit d3489f
		reap_events(ring, batch, 1);
Packit d3489f
	}
Packit d3489f
	return 0;
Packit d3489f
}
Packit d3489f
Packit d3489f
int main(int argc, char *argv[])
Packit d3489f
{
Packit d3489f
	struct io_uring ring;
Packit d3489f
	int pipe1[2];
Packit d3489f
	int ret;
Packit d3489f
Packit d3489f
	if (argc > 1)
Packit d3489f
		return 0;
Packit d3489f
Packit d3489f
	if (pipe(pipe1) != 0) {
Packit d3489f
		perror("pipe");
Packit d3489f
		return 1;
Packit d3489f
	}
Packit d3489f
Packit d3489f
	ret = io_uring_queue_init(1024, &ring, 0);
Packit d3489f
	if (ret) {
Packit d3489f
		fprintf(stderr, "ring setup failed: %d\n", ret);
Packit d3489f
		return 1;
Packit d3489f
	}
Packit d3489f
Packit d3489f
	add_polls(&ring, pipe1[0], 30000);
Packit d3489f
#if 0
Packit d3489f
	usleep(1000);
Packit d3489f
#endif
Packit d3489f
	del_polls(&ring, pipe1[0], 30000);
Packit d3489f
Packit d3489f
	io_uring_queue_exit(&ring);
Packit d3489f
	return 0;
Packit d3489f
}