forked from vitalif/vitastor
io_uring timeout testing
parent
eec1c35ea4
commit
2f429b17dd
11
ringloop.cpp
11
ringloop.cpp
|
@ -17,6 +17,7 @@ ring_loop_t::ring_loop_t(int qd)
|
||||||
ring_loop_t::~ring_loop_t()
|
ring_loop_t::~ring_loop_t()
|
||||||
{
|
{
|
||||||
free(ring_data);
|
free(ring_data);
|
||||||
|
io_uring_queue_exit(&ring);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct io_uring_sqe* ring_loop_t::get_sqe()
|
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)
|
void ring_loop_t::loop(bool sleep)
|
||||||
{
|
{
|
||||||
struct io_uring_cqe *cqe;
|
struct io_uring_cqe *cqe;
|
||||||
if (sleep)
|
while (!io_uring_peek_cqe(&ring, &cqe))
|
||||||
{
|
|
||||||
io_uring_wait_cqe(&ring, &cqe);
|
|
||||||
}
|
|
||||||
while ((io_uring_peek_cqe(&ring, &cqe), cqe))
|
|
||||||
{
|
{
|
||||||
struct ring_data_t *d = (struct ring_data_t*)cqe->user_data;
|
struct ring_data_t *d = (struct ring_data_t*)cqe->user_data;
|
||||||
if (d->callback)
|
if (d->callback)
|
||||||
|
@ -64,4 +61,8 @@ void ring_loop_t::loop(bool sleep)
|
||||||
{
|
{
|
||||||
consumers[i].loop();
|
consumers[i].loop();
|
||||||
}
|
}
|
||||||
|
if (sleep)
|
||||||
|
{
|
||||||
|
io_uring_wait_cqe(&ring, &cqe);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
10
test.cpp
10
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);
|
uint8_t *buf = (uint8_t*)memalign(512, 1024*1024*1024);
|
||||||
struct iovec iov = { buf, 1024*1024*1024 };
|
struct iovec iov = { buf, 1024*1024*1024 };
|
||||||
io_uring_prep_writev(sqe, fd, &iov, 1, 0);
|
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);
|
io_uring_submit_and_wait(ring, 1);
|
||||||
struct io_uring_cqe *cqe;
|
struct io_uring_cqe *cqe;
|
||||||
io_uring_peek_cqe(ring, &cqe);
|
io_uring_peek_cqe(ring, &cqe);
|
||||||
|
@ -47,7 +47,7 @@ static void test_write(struct io_uring *ring, int fd)
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
printf("cqe failed: %d %s\n", ret, strerror(-ret));
|
printf("cqe failed: %d %s\n", ret, strerror(-ret));
|
||||||
else
|
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);
|
io_uring_cqe_seen(ring, cqe);
|
||||||
free(buf);
|
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;
|
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
|
// queue with random removal: vector is best :D
|
||||||
// deque: 8.1s
|
// deque: 8.1s
|
||||||
|
@ -208,7 +208,7 @@ int main1(int argc, char *argv[])
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main2(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
std::map<int, std::string> strs;
|
std::map<int, std::string> strs;
|
||||||
strs.emplace(12, "str");
|
strs.emplace(12, "str");
|
||||||
|
@ -217,7 +217,7 @@ int main2(int argc, char *argv[])
|
||||||
it--;
|
it--;
|
||||||
printf("s = %d %s\n", it->first, it->second.c_str());
|
printf("s = %d %s\n", it->first, it->second.c_str());
|
||||||
struct io_uring ring;
|
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)
|
if (fd < 0)
|
||||||
{
|
{
|
||||||
perror("open infile");
|
perror("open infile");
|
||||||
|
|
|
@ -1,6 +1,67 @@
|
||||||
|
#include <sys/timerfd.h>
|
||||||
|
#include <sys/poll.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "blockstore.h"
|
#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[])
|
int main(int narg, char *args[])
|
||||||
{
|
{
|
||||||
spp::sparse_hash_map<std::string, std::string> config;
|
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["journal_device"] = "./test_journal.bin";
|
||||||
config["data_device"] = "./test_data.bin";
|
config["data_device"] = "./test_data.bin";
|
||||||
ring_loop_t *ringloop = new ring_loop_t(512);
|
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;
|
delete ringloop;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue