parent
a7dc759f74
commit
a8f250c68f
@ -1,15 +1,15 @@ |
||||
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 |
||||
clean: |
||||
rm -f *.o
|
||||
crc32c.o: crc32c.c |
||||
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 $@ $<
|
||||
test: test.cpp |
||||
g++ -g -O3 -o test -luring test.cpp
|
||||
test_blockstore: $(BLOCKSTORE_OBJS) test_blockstore.cpp |
||||
g++ -g -o test_blockstore -luring test_blockstore.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)
|
||||
|
@ -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(); |
||||
} |
@ -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(); |
||||
}; |
Loading…
Reference in new issue