Wakeup ring loop

blocking-uring-test
Vitaliy Filippov 2019-11-18 14:08:11 +03:00
parent b6174075de
commit 8c690c76ec
5 changed files with 34 additions and 18 deletions

View File

@ -48,7 +48,7 @@ blockstore::~blockstore()
{ {
delete flusher; delete flusher;
free(zero_object); free(zero_object);
ringloop->unregister_consumer(ring_consumer.number); ringloop->unregister_consumer(ring_consumer);
if (data_fd >= 0) if (data_fd >= 0)
close(data_fd); close(data_fd);
if (meta_fd >= 0 && meta_fd != data_fd) if (meta_fd >= 0 && meta_fd != data_fd)
@ -246,5 +246,6 @@ int blockstore::enqueue_op(blockstore_operation *op)
{ {
enqueue_write(op); enqueue_write(op);
} }
ringloop->wakeup(ring_consumer);
return 0; return 0;
} }

View File

@ -254,6 +254,7 @@ int blockstore_init_journal::loop()
bs->journal.crc32_last = crc32_last; bs->journal.crc32_last = crc32_last;
journal_buffer = NULL; journal_buffer = NULL;
step = 100; step = 100;
return 0;
} }
return 1; return 1;
} }

View File

@ -27,17 +27,22 @@ int ring_loop_t::register_consumer(ring_consumer_t & consumer)
return consumer.number; return consumer.number;
} }
void ring_loop_t::unregister_consumer(int number) void ring_loop_t::wakeup(ring_consumer_t & consumer)
{ {
if (number < consumers.size()) loop_again = true;
}
void ring_loop_t::unregister_consumer(ring_consumer_t & consumer)
{
if (consumer.number >= 0 && consumer.number < consumers.size())
{ {
consumers[number].loop = NULL; consumers[consumer.number].loop = NULL;
consumer.number = -1;
} }
} }
void ring_loop_t::loop(bool sleep) void ring_loop_t::loop()
{ {
// FIXME: we should loop until all "coroutines" are suspended. currently we loop only once before sleeping
struct io_uring_cqe *cqe; struct io_uring_cqe *cqe;
while (!io_uring_peek_cqe(&ring, &cqe)) while (!io_uring_peek_cqe(&ring, &cqe))
{ {
@ -49,12 +54,13 @@ void ring_loop_t::loop(bool sleep)
} }
io_uring_cqe_seen(&ring, cqe); io_uring_cqe_seen(&ring, cqe);
} }
for (int i = 0; i < consumers.size(); i++) do
{ {
consumers[i].loop(); loop_again = false;
} for (int i = 0; i < consumers.size(); i++)
if (sleep) {
{ consumers[i].loop();
io_uring_wait_cqe(&ring, &cqe); }
} } while (loop_again);
io_uring_wait_cqe(&ring, &cqe);
} }

View File

@ -120,6 +120,7 @@ class ring_loop_t
{ {
std::vector<ring_consumer_t> consumers; std::vector<ring_consumer_t> consumers;
struct ring_data_t *ring_data; struct ring_data_t *ring_data;
bool loop_again;
public: public:
struct io_uring ring; struct io_uring ring;
ring_loop_t(int qd); ring_loop_t(int qd);
@ -134,8 +135,9 @@ public:
return sqe; return sqe;
} }
int register_consumer(ring_consumer_t & consumer); int register_consumer(ring_consumer_t & consumer);
void unregister_consumer(int number); void wakeup(ring_consumer_t & consumer);
void loop(bool sleep); void unregister_consumer(ring_consumer_t & consumer);
void loop();
inline int submit() inline int submit()
{ {
return io_uring_submit(&ring); return io_uring_submit(&ring);

View File

@ -36,7 +36,7 @@ public:
~timerfd_interval() ~timerfd_interval()
{ {
ringloop->unregister_consumer(consumer.number); ringloop->unregister_consumer(consumer);
close(timerfd); close(timerfd);
} }
@ -94,16 +94,22 @@ int main(int narg, char *args[])
{ {
printf("completed %d\n", op->retval); printf("completed %d\n", op->retval);
}; };
ring_consumer_t main_cons;
bool bs_was_done = false; bool bs_was_done = false;
while (true) main_cons.loop = [&]()
{ {
bool bs_done = bs->is_started(); bool bs_done = bs->is_started();
if (bs_done && !bs_was_done) if (bs_done && !bs_was_done)
{ {
printf("init completed\n");
bs->enqueue_op(&op); bs->enqueue_op(&op);
bs_was_done = true; bs_was_done = true;
} }
ringloop->loop(true); };
ringloop->register_consumer(main_cons);
while (true)
{
ringloop->loop();
} }
delete bs; delete bs;
delete ringloop; delete ringloop;