/* SPDX-License-Identifier: MIT */
/*
 * Description: tests for getevents timeout
 *
 */
#include <stdio.h>
#include <sys/time.h>
#include <unistd.h>
#include <pthread.h>
#include "liburing.h"

#define TIMEOUT_MSEC	200
#define TIMEOUT_SEC	10

int thread_ret0, thread_ret1;
int cnt = 0;
pthread_mutex_t mutex;

static void msec_to_ts(struct __kernel_timespec *ts, unsigned int msec)
{
	ts->tv_sec = msec / 1000;
	ts->tv_nsec = (msec % 1000) * 1000000;
}

static unsigned long long mtime_since(const struct timeval *s,
				      const struct timeval *e)
{
	long long sec, usec;

	sec = e->tv_sec - s->tv_sec;
	usec = (e->tv_usec - s->tv_usec);
	if (sec > 0 && usec < 0) {
		sec--;
		usec += 1000000;
	}

	sec *= 1000;
	usec /= 1000;
	return sec + usec;
}

static unsigned long long mtime_since_now(struct timeval *tv)
{
	struct timeval end;

	gettimeofday(&end, NULL);
	return mtime_since(tv, &end);
}


static int test_return_before_timeout(struct io_uring *ring)
{
	struct io_uring_cqe *cqe;
	struct io_uring_sqe *sqe;
	int ret;
	struct __kernel_timespec ts;

	sqe = io_uring_get_sqe(ring);
	if (!sqe) {
		fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
		return 1;
	}

	io_uring_prep_nop(sqe);

	ret = io_uring_submit(ring);
	if (ret <= 0) {
		fprintf(stderr, "%s: sqe submit failed: %d\n", __FUNCTION__, ret);
		return 1;
	}

	msec_to_ts(&ts, TIMEOUT_MSEC);
	ret = io_uring_wait_cqe_timeout(ring, &cqe, &ts);
	if (ret < 0) {
		fprintf(stderr, "%s: timeout error: %d\n", __FUNCTION__, ret);
		return 1;
	}

	io_uring_cqe_seen(ring, cqe);
	return 0;
}

static int test_return_after_timeout(struct io_uring *ring)
{
	struct io_uring_cqe *cqe;
	int ret;
	struct __kernel_timespec ts;
	struct timeval tv;
	unsigned long long exp;

	msec_to_ts(&ts, TIMEOUT_MSEC);
	gettimeofday(&tv, NULL);
	ret = io_uring_wait_cqe_timeout(ring, &cqe, &ts);
	exp = mtime_since_now(&tv);
	if (ret != -ETIME) {
		fprintf(stderr, "%s: timeout error: %d\n", __FUNCTION__, ret);
		return 1;
	}

	if (exp < TIMEOUT_MSEC / 2 || exp > (TIMEOUT_MSEC  * 3) / 2) {
		fprintf(stderr, "%s: Timeout seems wonky (got %llu)\n", __FUNCTION__, exp);
		return 1;
	}

	return 0;
}

int __reap_thread_fn(void *data) {
	struct io_uring *ring = (struct io_uring *)data;
	struct io_uring_cqe *cqe;
	struct __kernel_timespec ts;

	msec_to_ts(&ts, TIMEOUT_SEC);
	pthread_mutex_lock(&mutex);
	cnt++;
	pthread_mutex_unlock(&mutex);
	return io_uring_wait_cqe_timeout(ring, &cqe, &ts);
}

void *reap_thread_fn0(void *data) {
	thread_ret0 = __reap_thread_fn(data);
	return NULL;
}

void *reap_thread_fn1(void *data) {
	thread_ret1 = __reap_thread_fn(data);
	return NULL;
}

/*
 * This is to test issuing a sqe in main thread and reaping it in two child-thread
 * at the same time. To see if timeout feature works or not.
 */
int test_multi_threads_timeout() {
	struct io_uring ring;
	int ret;
	bool both_wait = false;
	pthread_t reap_thread0, reap_thread1;
	struct io_uring_sqe *sqe;

	ret = io_uring_queue_init(8, &ring, 0);
	if (ret) {
		fprintf(stderr, "%s: ring setup failed: %d\n", __FUNCTION__, ret);
		return 1;
	}

	pthread_create(&reap_thread0, NULL, reap_thread_fn0, &ring);
	pthread_create(&reap_thread1, NULL, reap_thread_fn1, &ring);

	/*
	 * make two threads both enter io_uring_wait_cqe_timeout() before issuing the sqe
	 * as possible as we can. So that there are two threads in the ctx->wait queue.
	 * In this way, we can test if a cqe wakes up two threads at the same time.
	 */
	while(!both_wait) {
		pthread_mutex_lock(&mutex);
		if (cnt == 2)
			both_wait = true;
		pthread_mutex_unlock(&mutex);
		sleep(1);
	}

	sqe = io_uring_get_sqe(&ring);
	if (!sqe) {
		fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
		goto err;
	}

	io_uring_prep_nop(sqe);

	ret = io_uring_submit(&ring);
	if (ret <= 0) {
		fprintf(stderr, "%s: sqe submit failed: %d\n", __FUNCTION__, ret);
		goto err;
	}

	pthread_join(reap_thread0, NULL);
	pthread_join(reap_thread1, NULL);

	if ((thread_ret0 && thread_ret0 != -ETIME) || (thread_ret1 && thread_ret1 != -ETIME)) {
		fprintf(stderr, "%s: thread wait cqe timeout failed: %d %d\n",
				__FUNCTION__, thread_ret0, thread_ret1);
		goto err;
	}

	return 0;
err:
	return 1;
}

int main(int argc, char *argv[])
{
	struct io_uring ring_normal, ring_sq;
	int ret;

	if (argc > 1)
		return 0;

	ret = io_uring_queue_init(8, &ring_normal, 0);
	if (ret) {
		fprintf(stderr, "ring_normal setup failed: %d\n", ret);
		return 1;
	}
	if (!(ring_normal.features & IORING_FEAT_EXT_ARG)) {
		fprintf(stderr, "feature IORING_FEAT_EXT_ARG not supported.\n");
		return 0;
	}

	ret = test_return_before_timeout(&ring_normal);
	if (ret) {
		fprintf(stderr, "ring_normal: test_return_before_timeout failed\n");
		return ret;
	}

	ret = test_return_after_timeout(&ring_normal);
	if (ret) {
		fprintf(stderr, "ring_normal: test_return_after_timeout failed\n");
		return ret;
	}

	ret = io_uring_queue_init(8, &ring_sq, IORING_SETUP_SQPOLL);
	if (ret) {
		fprintf(stderr, "ring_sq setup failed: %d\n", ret);
		return 1;
	}

	ret = test_return_before_timeout(&ring_sq);
	if (ret) {
		fprintf(stderr, "ring_sq: test_return_before_timeout failed\n");
		return ret;
	}

	ret = test_return_after_timeout(&ring_sq);
	if (ret) {
		fprintf(stderr, "ring_sq: test_return_after_timeout failed\n");
		return ret;
	}

	ret = test_multi_threads_timeout();
	if (ret) {
		fprintf(stderr, "test_multi_threads_timeout failed\n");
		return ret;
	}

	return 0;
}
