diff --git a/blockstore.cpp b/blockstore.cpp index 32ed4a48..78a4a7bb 100644 --- a/blockstore.cpp +++ b/blockstore.cpp @@ -59,6 +59,11 @@ blockstore::~blockstore() free(journal.sector_info); } +bool blockstore::is_started() +{ + return initialized == 10; +} + // main event loop - produce requests void blockstore::loop() { diff --git a/blockstore.h b/blockstore.h index 30615bdf..ef130671 100644 --- a/blockstore.h +++ b/blockstore.h @@ -211,7 +211,7 @@ struct blockstore_operation uint32_t offset; // For stabilize requests: buf contains obj_ver_id's to stabilize uint32_t len; - uint8_t *buf; + uint8_t *buf; // FIXME: void* int retval; // FIXME: Move internal fields somewhere @@ -325,6 +325,8 @@ public: // Event loop void loop(); + bool is_started(); + // Returns true when it's safe to destroy the instance. If destroying the instance // requires to purge some queues, starts that process. Should be called in the event // loop until it returns true. diff --git a/blockstore_write.cpp b/blockstore_write.cpp index c1a57891..4ccaaff9 100644 --- a/blockstore_write.cpp +++ b/blockstore_write.cpp @@ -3,16 +3,21 @@ void blockstore::enqueue_write(blockstore_operation *op) { // Assign version number - auto dirty_it = dirty_db.upper_bound((obj_ver_id){ - .oid = op->oid, - .version = UINT64_MAX, - }); - dirty_it--; - if (dirty_it != dirty_db.end() && dirty_it->first.oid == op->oid) + bool found = false; + if (dirty_db.size() > 0) { - op->version = dirty_it->first.version + 1; + auto dirty_it = dirty_db.upper_bound((obj_ver_id){ + .oid = op->oid, + .version = UINT64_MAX, + }); + dirty_it--; + if (dirty_it != dirty_db.end() && dirty_it->first.oid == op->oid) + { + found = true; + op->version = dirty_it->first.version + 1; + } } - else + if (!found) { auto clean_it = clean_db.find(op->oid); if (clean_it != clean_db.end()) diff --git a/test.cpp b/test.cpp index 5e23221a..bcc5fe41 100644 --- a/test.cpp +++ b/test.cpp @@ -212,10 +212,11 @@ int main(int argc, char *argv[]) { std::map strs; strs.emplace(12, "str"); - auto it = strs.upper_bound(11); - printf("s = %d %s %d\n", it->first, it->second.c_str(), it == strs.begin()); + auto it = strs.upper_bound(13); + //printf("s = %d %s %d\n", it->first, it->second.c_str(), it == strs.begin()); it--; - printf("s = %d %s\n", it->first, it->second.c_str()); + printf("%d\n", it == strs.end()); + //printf("s = %d %s\n", it->first, it->second.c_str()); struct io_uring ring; int fd = open("/dev/loop0", O_RDWR | O_DIRECT, 0644); if (fd < 0) diff --git a/test_blockstore.cpp b/test_blockstore.cpp index 6ad09233..27bdd176 100644 --- a/test_blockstore.cpp +++ b/test_blockstore.cpp @@ -10,8 +10,9 @@ class timerfd_interval int status; ring_loop_t *ringloop; ring_consumer_t consumer; + std::function callback; public: - timerfd_interval(ring_loop_t *ringloop, int seconds) + timerfd_interval(ring_loop_t *ringloop, int seconds, std::function cb) { wait_state = 0; timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK); @@ -30,6 +31,7 @@ public: consumer.loop = [this]() { loop(); }; ringloop->register_consumer(consumer); this->ringloop = ringloop; + this->callback = cb; } ~timerfd_interval() @@ -61,7 +63,7 @@ public: uint64_t n; read(timerfd, &n, 8); wait_state = 0; - printf("tick 1s\n"); + callback(); }; wait_state = 1; ringloop->submit(); @@ -76,13 +78,33 @@ int main(int narg, char *args[]) config["data_device"] = "./test_data.bin"; ring_loop_t *ringloop = new ring_loop_t(512); blockstore *bs = new blockstore(config, ringloop); - // print "tick" every second - timerfd_interval tick_tfd(ringloop, 1); + timerfd_interval tick_tfd(ringloop, 1, []() + { + printf("tick 1s\n"); + }); + blockstore_operation op; + op.flags = OP_WRITE; + op.oid = { .inode = 1, .stripe = 0 }; + op.version = 0; + op.offset = 4096; + op.len = 4096; + op.buf = (uint8_t*)memalign(512, 4096); + memset(op.buf, 0xaa, 4096); + op.callback = [](blockstore_operation *op) + { + printf("completed %d\n", op->retval); + }; + bool bs_was_done = false; while (true) { + bool bs_done = bs->is_started(); + if (bs_done && !bs_was_done) + { + bs->enqueue_op(&op); + bs_was_done = true; + } ringloop->loop(true); } - delete bs; delete ringloop; return 0;