in src/double-linked-list/doubly_linked_list.cc [205:272]
Status CASDList::Delete(DListNode* node, bool) {
#ifdef PMEM
RAW_CHECK(!((uint64_t)node & kDirtyFlag), "dirty node pointer");
#endif
if (node == &head_ || node == &tail_) {
RAW_CHECK(((uint64_t)node->next & kNodeDeleted) == 0,
"invalid next pointer");
RAW_CHECK(((uint64_t)node->prev & kNodeDeleted) == 0,
"invalid next pointer");
return Status::OK();
}
while (true) {
#ifdef PMEM
DListNode* node_next = ReadPersist(&node->next);
#else
auto* node_next = node->next;
#endif
if ((uint64_t)node_next & kNodeDeleted) {
return Status::OK();
}
// Try to set the deleted bit in node->next
#ifdef PMEM
auto* desired =
(DListNode*)((uint64_t)node_next | kNodeDeleted | kDirtyFlag);
#else
auto* desired =
(DListNode*)((uint64_t)node_next | kNodeDeleted);
#endif
DListNode* rnode = CompareExchange64Ptr(
&node->next, desired,
node_next);
if (rnode == node_next) {
DListNode* node_prev = nullptr;
while (true) {
#ifdef PMEM
node_prev = ReadPersist(&node->prev);
#else
node_prev = node->prev;
#endif
if ((uint64_t)node_prev & kNodeDeleted) {
break;
}
#ifdef PMEM
auto* desired =
(DListNode*)((uint64_t)node_prev | kNodeDeleted | kDirtyFlag);
#else
auto* desired =
(DListNode*)((uint64_t)node_prev | kNodeDeleted);
#endif
if (node_prev == CompareExchange64Ptr(
&node->prev, desired,
node_prev)) {
break;
}
}
RAW_CHECK(node_prev, "invalid node_prev pointer");
RAW_CHECK(((uint64_t)head_.next & kNodeDeleted) == 0,
"invalid next pointer");
CorrectPrev((DListNode*)((uint64_t)node_prev & ~kNodeDeleted), node_next);
return Status::OK();
}
}
}