Use std::vector for the blockstore submission queue

Vitaliy Filippov 2021-03-07 00:48:34 +03:00
parent 0d8b5e2ef9
commit 36c935ace6
3 changed files with 32 additions and 39 deletions

View File

@ -101,15 +101,14 @@ void blockstore_impl_t::loop()
{
// try to submit ops
unsigned initial_ring_space = ringloop->space_left();
auto cur = submit_queue.begin();
// has_writes == 0 - no writes before the current queue item
// has_writes == 1 - some writes in progress
// has_writes == 2 - tried to submit some writes, but failed
int has_writes = 0;
while (cur != submit_queue.end())
int has_writes = 0, op_idx = 0, new_idx = 0;
for (; op_idx < submit_queue.size(); op_idx++)
{
auto op_ptr = cur;
auto op = *(cur++);
auto op = submit_queue[op_idx];
submit_queue[new_idx++] = op;
// FIXME: This needs some simplification
// Writes should not block reads if the ring is not full and reads don't depend on them
// In all other cases we should stop submission
@ -131,12 +130,13 @@ void blockstore_impl_t::loop()
}
unsigned ring_space = ringloop->space_left();
unsigned prev_sqe_pos = ringloop->save();
bool dequeue_op = false, cancel_op = false;
bool has_in_progress_sync = false;
// 0 = can't submit
// 1 = in progress
// 2 = can be removed from queue
int wr_st = 0;
if (op->opcode == BS_OP_READ)
{
dequeue_op = dequeue_read(op);
cancel_op = !dequeue_op;
wr_st = dequeue_read(op);
}
else if (op->opcode == BS_OP_WRITE || op->opcode == BS_OP_WRITE_STABLE)
{
@ -145,12 +145,7 @@ void blockstore_impl_t::loop()
// Some writes already could not be submitted
continue;
}
int wr_st = dequeue_write(op);
// 0 = can't submit
// 1 = in progress
// 2 = completed, remove from queue
dequeue_op = wr_st == 2;
cancel_op = wr_st == 0;
wr_st = dequeue_write(op);
has_writes = wr_st > 0 ? 1 : 2;
}
else if (op->opcode == BS_OP_DELETE)
@ -160,9 +155,7 @@ void blockstore_impl_t::loop()
// Some writes already could not be submitted
continue;
}
int wr_st = dequeue_del(op);
dequeue_op = wr_st == 2;
cancel_op = wr_st == 0;
wr_st = dequeue_del(op);
has_writes = wr_st > 0 ? 1 : 2;
}
else if (op->opcode == BS_OP_SYNC)
@ -176,39 +169,31 @@ void blockstore_impl_t::loop()
// Can't submit SYNC before previous writes
continue;
}
int wr_st = continue_sync(op, has_in_progress_sync);
dequeue_op = wr_st == 2;
cancel_op = wr_st == 0;
if (dequeue_op != 2)
wr_st = continue_sync(op, false);
if (wr_st != 2)
{
// Or we could just set has_writes=1...
has_in_progress_sync = true;
has_writes = wr_st > 0 ? 1 : 2;
}
}
else if (op->opcode == BS_OP_STABLE)
{
int wr_st = dequeue_stable(op);
dequeue_op = wr_st == 2;
cancel_op = wr_st == 0;
wr_st = dequeue_stable(op);
}
else if (op->opcode == BS_OP_ROLLBACK)
{
int wr_st = dequeue_rollback(op);
dequeue_op = wr_st == 2;
cancel_op = wr_st == 0;
wr_st = dequeue_rollback(op);
}
else if (op->opcode == BS_OP_LIST)
{
// LIST doesn't need to be blocked by previous modifications
process_list(op);
dequeue_op = true;
cancel_op = false;
wr_st = 2;
}
if (dequeue_op)
if (wr_st == 2)
{
submit_queue.erase(op_ptr);
new_idx--;
}
if (cancel_op)
if (wr_st == 0)
{
ringloop->restore(prev_sqe_pos);
if (PRIV(op)->wait_for == WAIT_SQE)
@ -219,6 +204,14 @@ void blockstore_impl_t::loop()
}
}
}
if (op_idx != new_idx)
{
while (op_idx < submit_queue.size())
{
submit_queue[new_idx++] = submit_queue[op_idx++];
}
submit_queue.resize(new_idx);
}
if (!readonly)
{
flusher->loop();

View File

@ -208,7 +208,7 @@ class blockstore_impl_t
blockstore_clean_db_t clean_db;
uint8_t *clean_bitmap = NULL;
blockstore_dirty_db_t dirty_db;
std::list<blockstore_op_t*> submit_queue; // FIXME: funny thing is that vector is better here
std::vector<blockstore_op_t*> submit_queue;
std::vector<obj_ver_id> unsynced_big_writes, unsynced_small_writes;
allocator *data_alloc = NULL;
uint8_t *zero_object;

View File

@ -112,7 +112,7 @@ int blockstore_impl_t::dequeue_read(blockstore_op_t *read_op)
read_op->version = 0;
read_op->retval = read_op->len;
FINISH_OP(read_op);
return 1;
return 2;
}
uint64_t fulfilled = 0;
PRIV(read_op)->pending_ops = 0;
@ -232,10 +232,10 @@ int blockstore_impl_t::dequeue_read(blockstore_op_t *read_op)
}
read_op->retval = read_op->len;
FINISH_OP(read_op);
return 1;
return 2;
}
read_op->retval = 0;
return 1;
return 2;
}
void blockstore_impl_t::handle_read_event(ring_data_t *data, blockstore_op_t *op)