Skip to content

Commit

Permalink
Wake up non-STATE_LOCKED_WAITING writers with priority
Browse files Browse the repository at this point in the history
The last writer sets the state of the writers that are not
STATE_LOCKED_WAITING to STATE_COMPLETED, and then notify-one writers
in STATE_LOCKED_WAITING sequentially, so that some writers will not
fall from non-BlockingAwaitState to its counterpart at this stage due
to the long waiting time.
 
  • Loading branch information
casualwind committed Apr 28, 2024
1 parent 7872ac1 commit e3959f7
Showing 1 changed file with 27 additions and 7 deletions.
34 changes: 27 additions & 7 deletions db/write_thread.cc
Original file line number Diff line number Diff line change
Expand Up @@ -871,16 +871,36 @@ void WriteThread::ExitAsBatchGroupLeader(WriteGroup& write_group,
// else nobody else was waiting, although there might already be a new
// leader now

while (last_writer != leader) {
assert(last_writer);
last_writer->status = status;
// cv_head is used for the list head for all the cv writers in
// the writer_group
Writer cv_head;
auto curr = last_writer;

// Since the cost of waking up in STATE_LOCKED_WAITING is higher,
// wake up those writers with lower wake-up costs first.
while (curr != leader) {
assert(curr);

// we need to read link_older before calling SetState, because as soon
// as it is marked committed the other thread's Await may return and
// as it is marked committed the other writers's Await may return and
// deallocate the Writer.
auto next = last_writer->link_older;
SetState(last_writer, STATE_COMPLETED);
auto next = curr->link_older;
if (curr->state != STATE_LOCKED_WAITING) {
curr->status = status;
SetState(curr, STATE_COMPLETED);
} else {
curr->link_older = cv_head.link_older;
cv_head.link_older = curr;
}
curr = next;
}

last_writer = next;
curr = cv_head.link_older;
while (curr) {
curr->status = status;
auto next = curr->link_older;
SetState(curr, STATE_COMPLETED);
curr = next;
}
}
}
Expand Down

0 comments on commit e3959f7

Please sign in to comment.