blob: 7690ebfc6c57efe2e82c138ed93d20194d482805 [file]
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
/// \file
/// Implementation for freelist.
///
//===----------------------------------------------------------------------===//
#include "freelist.h"
namespace LIBC_NAMESPACE_DECL {
void FreeList::push(Node *node) {
if (begin_) {
begin_->integrity_check();
// Since the list is circular, insert the node immediately before begin_.
node->prev_ = begin_->prev_;
node->next_ = begin_;
begin_->prev_->next_ = node;
begin_->prev_ = node;
} else {
begin_ = node->prev_ = node->next_ = node;
}
}
void FreeList::remove(Node *node) {
LIBC_ASSERT(begin_ && "cannot remove from empty list");
node->integrity_check();
Node *next = node->next_;
if (node == next) {
LIBC_ASSERT(node == begin_ &&
"a self-referential node must be the only element");
begin_ = nullptr;
} else {
Node *prev = node->prev_;
prev->next_ = next;
next->prev_ = prev;
if (begin_ == node)
begin_ = next;
}
}
void FreeList::integrity_check() const {
if (!begin_)
return;
Node *curr = begin_;
do {
curr->integrity_check();
curr = curr->next_;
} while (curr != begin_);
}
} // namespace LIBC_NAMESPACE_DECL