diff --git a/ringloop.cpp b/ringloop.cpp index 40a43323c..7116b2d80 100644 --- a/ringloop.cpp +++ b/ringloop.cpp @@ -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); + } } diff --git a/test.cpp b/test.cpp index 92c971b09..5e23221a4 100644 --- a/test.cpp +++ b/test.cpp @@ -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 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"); diff --git a/test_blockstore.cpp b/test_blockstore.cpp index ce19563a9..4871a3b3b 100644 --- a/test_blockstore.cpp +++ b/test_blockstore.cpp @@ -1,6 +1,67 @@ +#include +#include #include #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 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; }