fio engine starts now

blocking-uring-test
Vitaliy Filippov 2019-11-26 02:18:37 +03:00
parent a7dc759f74
commit a8f250c68f
7 changed files with 106 additions and 81 deletions

View File

@ -1,15 +1,15 @@
BLOCKSTORE_OBJS := allocator.o blockstore.o blockstore_init.o blockstore_open.o blockstore_journal.o blockstore_read.o \ BLOCKSTORE_OBJS := allocator.o blockstore.o blockstore_init.o blockstore_open.o blockstore_journal.o blockstore_read.o \
blockstore_write.o blockstore_sync.o blockstore_stable.o blockstore_flush.o crc32c.o ringloop.o blockstore_write.o blockstore_sync.o blockstore_stable.o blockstore_flush.o crc32c.o ringloop.o timerfd_interval.o
all: $(BLOCKSTORE_OBJS) test test_blockstore libfio_blockstore.so all: $(BLOCKSTORE_OBJS) test test_blockstore libfio_blockstore.so
clean: clean:
rm -f *.o rm -f *.o
crc32c.o: crc32c.c crc32c.o: crc32c.c
g++ -fPIC -c -o $@ $< g++ -fPIC -c -o $@ $<
%.o: %.cpp allocator.h blockstore_flush.h blockstore.h blockstore_init.h blockstore_journal.h crc32c.h ringloop.h xor.h %.o: %.cpp allocator.h blockstore_flush.h blockstore.h blockstore_init.h blockstore_journal.h crc32c.h ringloop.h xor.h timerfd_interval.h
g++ -g -Wall -Wno-sign-compare -Wno-parentheses -fPIC -c -o $@ $< g++ -g -Wall -Wno-sign-compare -Wno-parentheses -fPIC -c -o $@ $<
test: test.cpp test: test.cpp
g++ -g -O3 -o test -luring test.cpp g++ -g -O3 -o test -luring test.cpp
test_blockstore: $(BLOCKSTORE_OBJS) test_blockstore.cpp test_blockstore: $(BLOCKSTORE_OBJS) test_blockstore.cpp
g++ -g -o test_blockstore -luring test_blockstore.cpp $(BLOCKSTORE_OBJS) g++ -g -o test_blockstore -luring test_blockstore.cpp $(BLOCKSTORE_OBJS)
libfio_blockstore.so: fio_engine.cpp $(BLOCKSTORE_OBJS) libfio_blockstore.so: fio_engine.cpp $(BLOCKSTORE_OBJS)
g++ -Wno-pointer-arith -fPIC -shared -luring -o libfio_blockstore.so fio_engine.cpp $(BLOCKSTORE_OBJS) g++ -g -Wno-pointer-arith -fPIC -shared -luring -o libfio_blockstore.so fio_engine.cpp $(BLOCKSTORE_OBJS)

View File

@ -43,7 +43,7 @@ static int bs_setup(struct thread_data *td)
int r; int r;
//int64_t size; //int64_t size;
bsd = (bs_data*)calloc(1, sizeof(*bsd)); bsd = new bs_data;
if (!bsd) if (!bsd)
{ {
td_verror(td, errno, "calloc"); td_verror(td, errno, "calloc");
@ -71,7 +71,7 @@ static void bs_cleanup(struct thread_data *td)
if (bsd) if (bsd)
{ {
free(bsd); delete bsd;
} }
} }
@ -88,9 +88,12 @@ static int bs_init(struct thread_data *td)
config["data_device"] = "./test_data.bin"; config["data_device"] = "./test_data.bin";
bsd->ringloop = new ring_loop_t(512); bsd->ringloop = new ring_loop_t(512);
bsd->bs = new blockstore(config, bsd->ringloop); bsd->bs = new blockstore(config, bsd->ringloop);
while (!bsd->bs->is_started()) while (1)
{ {
bsd->ringloop->loop(); bsd->ringloop->loop();
if (bsd->bs->is_started())
break;
bsd->ringloop->wait();
} }
log_info("fio: blockstore initialized\n"); log_info("fio: blockstore initialized\n");
@ -122,8 +125,9 @@ static enum fio_q_status bs_queue(struct thread_data *td, struct io_u *io_u)
}; };
op->offset = io_u->offset % bsd->bs->block_size; op->offset = io_u->offset % bsd->bs->block_size;
op->len = io_u->xfer_buflen; op->len = io_u->xfer_buflen;
op->callback = [&](blockstore_operation *op) op->callback = [io_u](blockstore_operation *op)
{ {
bs_data *bsd = (bs_data*)io_u->engine_data;
bsd->completed.push_back(io_u); bsd->completed.push_back(io_u);
delete op; delete op;
}; };
@ -137,16 +141,18 @@ static enum fio_q_status bs_queue(struct thread_data *td, struct io_u *io_u)
}; };
op->offset = io_u->offset % bsd->bs->block_size; op->offset = io_u->offset % bsd->bs->block_size;
op->len = io_u->xfer_buflen; op->len = io_u->xfer_buflen;
op->callback = [&](blockstore_operation *op) op->callback = [io_u](blockstore_operation *op)
{ {
bs_data *bsd = (bs_data*)io_u->engine_data;
bsd->completed.push_back(io_u); bsd->completed.push_back(io_u);
delete op; delete op;
}; };
break; break;
case DDIR_SYNC: case DDIR_SYNC:
op->flags = OP_SYNC; op->flags = OP_SYNC;
op->callback = [&](blockstore_operation *op) op->callback = [io_u](blockstore_operation *op)
{ {
bs_data *bsd = (bs_data*)io_u->engine_data;
if (bsd->bs->unstable_writes.size() > 0) if (bsd->bs->unstable_writes.size() > 0)
{ {
op->flags = OP_STABLE; op->flags = OP_STABLE;
@ -162,8 +168,9 @@ static enum fio_q_status bs_queue(struct thread_data *td, struct io_u *io_u)
}; };
} }
bsd->bs->enqueue_op(op); bsd->bs->enqueue_op(op);
op->callback = [&](blockstore_operation *op) op->callback = [io_u](blockstore_operation *op)
{ {
bs_data *bsd = (bs_data*)io_u->engine_data;
bsd->completed.push_back(io_u); bsd->completed.push_back(io_u);
obj_ver_id *vers = (obj_ver_id*)op->buf; obj_ver_id *vers = (obj_ver_id*)op->buf;
delete[] vers; delete[] vers;
@ -192,9 +199,12 @@ static int bs_getevents(struct thread_data *td, unsigned int min, unsigned int m
{ {
bs_data *bsd = (bs_data*)td->io_ops_data; bs_data *bsd = (bs_data*)td->io_ops_data;
// FIXME timeout // FIXME timeout
while (bsd->completed.size() < min) while (true)
{ {
bsd->ringloop->loop(); bsd->ringloop->loop();
if (bsd->completed.size() >= min)
break;
bsd->ringloop->wait();
} }
return bsd->completed.size(); return bsd->completed.size();
} }

View File

@ -62,5 +62,4 @@ void ring_loop_t::loop()
consumers[i].loop(); consumers[i].loop();
} }
} while (loop_again); } while (loop_again);
io_uring_wait_cqe(&ring, &cqe);
} }

View File

@ -142,4 +142,9 @@ public:
{ {
return io_uring_submit(&ring); return io_uring_submit(&ring);
} }
inline int wait()
{
struct io_uring_cqe *cqe;
return io_uring_wait_cqe(&ring, &cqe);
}
}; };

View File

@ -1,75 +1,7 @@
#include <sys/timerfd.h>
#include <sys/poll.h>
#include <iostream> #include <iostream>
#include "timerfd_interval.h"
#include "blockstore.h" #include "blockstore.h"
class timerfd_interval
{
int wait_state;
int timerfd;
int status;
ring_loop_t *ringloop;
ring_consumer_t consumer;
std::function<void(void)> callback;
public:
timerfd_interval(ring_loop_t *ringloop, int seconds, std::function<void(void)> cb)
{
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;
this->callback = cb;
}
~timerfd_interval()
{
ringloop->unregister_consumer(consumer);
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);
my_uring_prep_poll_add(sqe, timerfd, POLLIN);
data->callback = [&](ring_data_t *data)
{
if (data->res < 0)
{
throw std::runtime_error(std::string("waiting for timer failed: ") + strerror(-data->res));
}
uint64_t n;
read(timerfd, &n, 8);
wait_state = 0;
callback();
};
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;
@ -141,6 +73,7 @@ int main(int narg, char *args[])
while (1) while (1)
{ {
ringloop->loop(); ringloop->loop();
ringloop->wait();
} }
delete bs; delete bs;
delete ringloop; delete ringloop;

61
timerfd_interval.cpp Normal file
View File

@ -0,0 +1,61 @@
#include <sys/timerfd.h>
#include <sys/poll.h>
#include <unistd.h>
#include "timerfd_interval.h"
timerfd_interval::timerfd_interval(ring_loop_t *ringloop, int seconds, std::function<void(void)> cb)
{
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;
this->callback = cb;
}
timerfd_interval::~timerfd_interval()
{
ringloop->unregister_consumer(consumer);
close(timerfd);
}
void timerfd_interval::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);
my_uring_prep_poll_add(sqe, timerfd, POLLIN);
data->callback = [&](ring_data_t *data)
{
if (data->res < 0)
{
throw std::runtime_error(std::string("waiting for timer failed: ") + strerror(-data->res));
}
uint64_t n;
read(timerfd, &n, 8);
wait_state = 0;
callback();
};
wait_state = 1;
ringloop->submit();
}

17
timerfd_interval.h Normal file
View File

@ -0,0 +1,17 @@
#pragma once
#include "ringloop.h"
class timerfd_interval
{
int wait_state;
int timerfd;
int status;
ring_loop_t *ringloop;
ring_consumer_t consumer;
std::function<void(void)> callback;
public:
timerfd_interval(ring_loop_t *ringloop, int seconds, std::function<void(void)> cb);
~timerfd_interval();
void loop();
};