Commit cd92284c authored by Dominik Charousset's avatar Dominik Charousset

Minimize locking in double_ended_queue::prepend

parent 9dcebc5d
......@@ -133,23 +133,35 @@ class double_ended_queue {
m_tail = tmp;
}
// acquires both locks
// acquires both locks if empty()
void prepend(pointer value) {
CAF_REQUIRE(value != nullptr);
node* tmp = new node(value);
// acquire both locks since we might touch m_last too
lock_guard guard1(m_head_lock);
lock_guard guard2(m_tail_lock);
auto first = m_head.load();
node* first = nullptr;
auto insert = [&] {
auto next = first->next.load();
// m_first always points to a dummy with no value,
// hence we put the new element second
tmp->next = next;
first->next = tmp;
// in case the queue is empty, we need to swing last forward
if (m_tail == first) {
};
// acquire both locks since we might touch m_last too
lock_guard guard1(m_head_lock);
first = m_head.load();
if (first == m_tail) {
// acquire second lock as well and move tail after insertion
lock_guard guard2(m_tail_lock);
// condition still strue?
if (first == m_tail) {
insert();
m_tail = tmp;
return;
}
// else: someone called append() in the meantime,
// release lock and insert as usual
}
// insertion without second lock is safe
insert();
}
// acquires only one lock, returns nullptr on failure
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment