* Copyright (c) 2025 Huawei Technologies Co., Ltd.
* This program is free software, you can redistribute it and/or modify it under the terms and conditions of
* CANN Open Software License Agreement Version 2.0 (the "License").
* Please refer to the License for details. You may not use this file except in compliance with the License.
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
* See LICENSE in the root of the software repository for the full text of the License.
*/
#include "kernel/memory/span/page_span.h"
#include <cmath>
#include "kernel/memory/allocator/scalable_allocator.h"
namespace gert {
void PageSpan::SetBuddy(PageSpan &buddy_span) {
PageSpan *next_buddy = buddy_link_.GetNext();
if (next_buddy != nullptr) {
next_buddy->buddy_link_.SetPrev(&buddy_span);
}
buddy_link_.SetNext(&buddy_span);
buddy_span.buddy_link_.SetNext(next_buddy);
buddy_span.buddy_link_.SetPrev(this);
}
void PageSpan::MergeBuddy(PageSpan &buddy_span) {
if ((buddy_link_.GetNext() == &buddy_span) && (buddy_span.buddy_link_.GetPrev() == this)) {
PageSpan *next_of_buddy = buddy_span.buddy_link_.GetNext();
if (next_of_buddy != nullptr) {
next_of_buddy->buddy_link_.SetPrev(this);
}
buddy_link_.SetNext(next_of_buddy);
page_len_ += buddy_span.GetPageLen();
if (buddy_link_.IsEmpty()) {
try_split_page_len_ = 0;
}
}
}
size_t PageSpan::GetSize() const {
return PageLen_GetMemSize(page_len_, scalable_allocator_.GetScalableConfig().page_idem_num) ;
}
void PageSpan::SetSplitable(bool splitable) {
splitable_ = splitable;
}
bool PageSpan::IsSplitable(const PageLen page_len) {
if (splitable_ || HasSplited()) {
return true;
}
try_split_page_len_ += page_len;
PageLen split_thresold = static_cast<PageLen>(floor(static_cast<float64_t>(page_len_) * kDelaySplitRatio));
return try_split_page_len_ > split_thresold;
}
}