Status CASDList::Delete()

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();
    }
  }
}