io_uring timeout testing

blocking-uring-test
Vitaliy Filippov 2019-11-17 17:45:39 +03:00
parent eec1c35ea4
commit 2f429b17dd
3 changed files with 80 additions and 12 deletions

View File

@ -17,6 +17,7 @@ ring_loop_t::ring_loop_t(int qd)
ring_loop_t::~ring_loop_t()
{
free(ring_data);
io_uring_queue_exit(&ring);
}
struct io_uring_sqe* ring_loop_t::get_sqe()
@ -47,11 +48,7 @@ void ring_loop_t::unregister_consumer(int number)
void ring_loop_t::loop(bool sleep)
{
struct io_uring_cqe *cqe;
if (sleep)
{
io_uring_wait_cqe(&ring, &cqe);
}
while ((io_uring_peek_cqe(&ring, &cqe), cqe))
while (!io_uring_peek_cqe(&ring, &cqe))
{
struct ring_data_t *d = (struct ring_data_t*)cqe->user_data;
if (d->callback)
@ -64,4 +61,8 @@ void ring_loop_t::loop(bool sleep)
{
consumers[i].loop();
}
if (sleep)
{
io_uring_wait_cqe(&ring, &cqe);
}
}

View File

@ -38,7 +38,7 @@ static void test_write(struct io_uring *ring, int fd)
uint8_t *buf = (uint8_t*)memalign(512, 1024*1024*1024);
struct iovec iov = { buf, 1024*1024*1024 };
io_uring_prep_writev(sqe, fd, &iov, 1, 0);
io_uring_sqe_set_data(sqe, 0);
io_uring_sqe_set_data(sqe, buf);
io_uring_submit_and_wait(ring, 1);
struct io_uring_cqe *cqe;
io_uring_peek_cqe(ring, &cqe);
@ -47,7 +47,7 @@ static void test_write(struct io_uring *ring, int fd)
if (ret < 0)
printf("cqe failed: %d %s\n", ret, strerror(-ret));
else
printf("result: %d\n", ret);
printf("result: %d user_data: %d -> %d\n", ret, sqe->user_data, cqe->user_data);
io_uring_cqe_seen(ring, cqe);
free(buf);
}
@ -70,7 +70,7 @@ inline bool operator == (const obj_ver_id & a, const obj_ver_id & b)
return a.oid == b.oid && a.version == b.version;
}
int main(int argc, char *argv[])
int main00(int argc, char *argv[])
{
// queue with random removal: vector is best :D
// deque: 8.1s
@ -208,7 +208,7 @@ int main1(int argc, char *argv[])
return 0;
}
int main2(int argc, char *argv[])
int main(int argc, char *argv[])
{
std::map<int, std::string> strs;
strs.emplace(12, "str");
@ -217,7 +217,7 @@ int main2(int argc, char *argv[])
it--;
printf("s = %d %s\n", it->first, it->second.c_str());
struct io_uring ring;
int fd = open("testfile", O_RDWR | O_DIRECT, 0644);
int fd = open("/dev/loop0", O_RDWR | O_DIRECT, 0644);
if (fd < 0)
{
perror("open infile");

View File

@ -1,6 +1,67 @@
#include <sys/timerfd.h>
#include <sys/poll.h>
#include <iostream>
#include "blockstore.h"
class timerfd_interval
{
int wait_state;
int timerfd;
int status;
ring_loop_t *ringloop;
ring_consumer_t consumer;
public:
timerfd_interval(ring_loop_t *ringloop, int seconds)
{
wait_state = 0;
timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK);
if (timerfd < 0)
{
throw std::runtime_error(std::string("timerfd_create: ") + strerror(errno));
}
struct itimerspec exp = {
.it_interval = { seconds, 0 },
.it_value = { seconds, 0 },
};
if (timerfd_settime(timerfd, 0, &exp, NULL))
{
throw std::runtime_error(std::string("timerfd_settime: ") + strerror(errno));
}
consumer.loop = [this]() { loop(); };
ringloop->register_consumer(consumer);
this->ringloop = ringloop;
}
~timerfd_interval()
{
ringloop->unregister_consumer(consumer.number);
close(timerfd);
}
void loop()
{
if (wait_state == 1)
{
return;
}
struct io_uring_sqe *sqe = ringloop->get_sqe();
if (!sqe)
{
wait_state = 0;
return;
}
struct ring_data_t *data = ((ring_data_t*)sqe->user_data);
io_uring_prep_poll_add(sqe, timerfd, POLLIN);
data->callback = [&](ring_data_t *data)
{
wait_state = 0;
printf("tick\n");
};
wait_state = 1;
ringloop->submit();
}
};
int main(int narg, char *args[])
{
spp::sparse_hash_map<std::string, std::string> config;
@ -8,9 +69,15 @@ int main(int narg, char *args[])
config["journal_device"] = "./test_journal.bin";
config["data_device"] = "./test_data.bin";
ring_loop_t *ringloop = new ring_loop_t(512);
blockstore *bs = new blockstore(config, ringloop);
// print "tick" each second
timerfd_interval tick_tfd(ringloop, 1);
while (true)
{
ringloop->loop(true);
}
//blockstore *bs = new blockstore(config, ringloop);
delete bs;
//delete bs;
delete ringloop;
return 0;
}