mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2024-11-12 15:06:41 +00:00
kern: use optimized red black tree finds for remaining holdouts
This commit is contained in:
parent
436613401a
commit
89926f44c6
5 changed files with 36 additions and 37 deletions
|
@ -248,10 +248,16 @@ namespace ams::kern {
|
||||||
public:
|
public:
|
||||||
constexpr ALWAYS_INLINE KAutoObjectWithList(util::ConstantInitializeTag) : KAutoObjectWithListBase(util::ConstantInitialize), m_list_node(util::ConstantInitialize) { /* ... */ }
|
constexpr ALWAYS_INLINE KAutoObjectWithList(util::ConstantInitializeTag) : KAutoObjectWithListBase(util::ConstantInitialize), m_list_node(util::ConstantInitialize) { /* ... */ }
|
||||||
ALWAYS_INLINE explicit KAutoObjectWithList() { /* ... */ }
|
ALWAYS_INLINE explicit KAutoObjectWithList() { /* ... */ }
|
||||||
|
public:
|
||||||
|
using RedBlackKeyType = u64;
|
||||||
|
|
||||||
static ALWAYS_INLINE int Compare(const KAutoObjectWithList &lhs, const KAutoObjectWithList &rhs) {
|
static constexpr ALWAYS_INLINE RedBlackKeyType GetRedBlackKey(const RedBlackKeyType &v) { return v; }
|
||||||
const u64 lid = lhs.GetId();
|
static constexpr ALWAYS_INLINE RedBlackKeyType GetRedBlackKey(const KAutoObjectWithList &v) { return v.GetId(); }
|
||||||
const u64 rid = rhs.GetId();
|
|
||||||
|
template<typename T> requires (std::same_as<T, KAutoObjectWithList> || std::same_as<T, RedBlackKeyType>)
|
||||||
|
static ALWAYS_INLINE int Compare(const T &lhs, const KAutoObjectWithList &rhs) {
|
||||||
|
const u64 lid = GetRedBlackKey(lhs);
|
||||||
|
const u64 rid = GetRedBlackKey(rhs);
|
||||||
|
|
||||||
if (lid < rid) {
|
if (lid < rid) {
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -33,17 +33,21 @@ namespace ams::kern {
|
||||||
explicit ListAccessor(KAutoObjectWithListContainer *container) : KScopedLightLock(container->m_lock), m_list(container->m_object_list) { /* ... */ }
|
explicit ListAccessor(KAutoObjectWithListContainer *container) : KScopedLightLock(container->m_lock), m_list(container->m_object_list) { /* ... */ }
|
||||||
explicit ListAccessor(KAutoObjectWithListContainer &container) : KScopedLightLock(container.m_lock), m_list(container.m_object_list) { /* ... */ }
|
explicit ListAccessor(KAutoObjectWithListContainer &container) : KScopedLightLock(container.m_lock), m_list(container.m_object_list) { /* ... */ }
|
||||||
|
|
||||||
typename ListType::iterator begin() const {
|
ALWAYS_INLINE typename ListType::iterator begin() const {
|
||||||
return m_list.begin();
|
return m_list.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
typename ListType::iterator end() const {
|
ALWAYS_INLINE typename ListType::iterator end() const {
|
||||||
return m_list.end();
|
return m_list.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
typename ListType::iterator find(typename ListType::const_reference ref) const {
|
ALWAYS_INLINE typename ListType::iterator find(typename ListType::const_reference ref) const {
|
||||||
return m_list.find(ref);
|
return m_list.find(ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ALWAYS_INLINE typename ListType::iterator find_key(typename ListType::const_key_reference ref) const {
|
||||||
|
return m_list.find_key(ref);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
friend class ListAccessor;
|
friend class ListAccessor;
|
||||||
|
|
|
@ -42,10 +42,16 @@ namespace ams::kern {
|
||||||
explicit KThreadLocalPage() : KThreadLocalPage(Null<KProcessAddress>) { /* ... */ }
|
explicit KThreadLocalPage() : KThreadLocalPage(Null<KProcessAddress>) { /* ... */ }
|
||||||
|
|
||||||
constexpr ALWAYS_INLINE KProcessAddress GetAddress() const { return m_virt_addr; }
|
constexpr ALWAYS_INLINE KProcessAddress GetAddress() const { return m_virt_addr; }
|
||||||
|
public:
|
||||||
|
using RedBlackKeyType = KProcessAddress;
|
||||||
|
|
||||||
static constexpr ALWAYS_INLINE int Compare(const KThreadLocalPage &lhs, const KThreadLocalPage &rhs) {
|
static constexpr ALWAYS_INLINE RedBlackKeyType GetRedBlackKey(const RedBlackKeyType &v) { return v; }
|
||||||
const KProcessAddress lval = lhs.GetAddress();
|
static constexpr ALWAYS_INLINE RedBlackKeyType GetRedBlackKey(const KThreadLocalPage &v) { return v.GetAddress(); }
|
||||||
const KProcessAddress rval = rhs.GetAddress();
|
|
||||||
|
template<typename T> requires (std::same_as<T, KThreadLocalPage> || std::same_as<T, RedBlackKeyType>)
|
||||||
|
static constexpr ALWAYS_INLINE int Compare(const T &lhs, const KThreadLocalPage &rhs) {
|
||||||
|
const KProcessAddress lval = GetRedBlackKey(lhs);
|
||||||
|
const KProcessAddress rval = GetRedBlackKey(rhs);
|
||||||
|
|
||||||
if (lval < rval) {
|
if (lval < rval) {
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -705,10 +705,10 @@ namespace ams::kern {
|
||||||
KScopedSchedulerLock sl;
|
KScopedSchedulerLock sl;
|
||||||
|
|
||||||
/* Try to find the page in the partially used list. */
|
/* Try to find the page in the partially used list. */
|
||||||
auto it = m_partially_used_tlp_tree.find(KThreadLocalPage(util::AlignDown(GetInteger(addr), PageSize)));
|
auto it = m_partially_used_tlp_tree.find_key(util::AlignDown(GetInteger(addr), PageSize));
|
||||||
if (it == m_partially_used_tlp_tree.end()) {
|
if (it == m_partially_used_tlp_tree.end()) {
|
||||||
/* If we don't find it, it has to be in the fully used list. */
|
/* If we don't find it, it has to be in the fully used list. */
|
||||||
it = m_fully_used_tlp_tree.find(KThreadLocalPage(util::AlignDown(GetInteger(addr), PageSize)));
|
it = m_fully_used_tlp_tree.find_key(util::AlignDown(GetInteger(addr), PageSize));
|
||||||
R_UNLESS(it != m_fully_used_tlp_tree.end(), svc::ResultInvalidAddress());
|
R_UNLESS(it != m_fully_used_tlp_tree.end(), svc::ResultInvalidAddress());
|
||||||
|
|
||||||
/* Release the region. */
|
/* Release the region. */
|
||||||
|
@ -749,9 +749,9 @@ namespace ams::kern {
|
||||||
KThreadLocalPage *tlp = nullptr;
|
KThreadLocalPage *tlp = nullptr;
|
||||||
{
|
{
|
||||||
KScopedSchedulerLock sl;
|
KScopedSchedulerLock sl;
|
||||||
if (auto it = m_partially_used_tlp_tree.find(KThreadLocalPage(util::AlignDown(GetInteger(addr), PageSize))); it != m_partially_used_tlp_tree.end()) {
|
if (auto it = m_partially_used_tlp_tree.find_key(util::AlignDown(GetInteger(addr), PageSize)); it != m_partially_used_tlp_tree.end()) {
|
||||||
tlp = std::addressof(*it);
|
tlp = std::addressof(*it);
|
||||||
} else if (auto it = m_fully_used_tlp_tree.find(KThreadLocalPage(util::AlignDown(GetInteger(addr), PageSize))); it != m_fully_used_tlp_tree.end()) {
|
} else if (auto it = m_fully_used_tlp_tree.find_key(util::AlignDown(GetInteger(addr), PageSize)); it != m_fully_used_tlp_tree.end()) {
|
||||||
tlp = std::addressof(*it);
|
tlp = std::addressof(*it);
|
||||||
} else {
|
} else {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
|
@ -1324,33 +1324,16 @@ namespace ams::kern {
|
||||||
KThread::ListAccessor accessor;
|
KThread::ListAccessor accessor;
|
||||||
const auto end = accessor.end();
|
const auto end = accessor.end();
|
||||||
|
|
||||||
/* Define helper object to find the thread. */
|
|
||||||
class IdObjectHelper : public KAutoObjectWithListContainer::ListType::value_type {
|
|
||||||
private:
|
|
||||||
u64 m_id;
|
|
||||||
public:
|
|
||||||
explicit IdObjectHelper(u64 id) : m_id(id) { /* ... */ }
|
|
||||||
virtual u64 GetId() const override { return m_id; }
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Find the object with the right id. */
|
/* Find the object with the right id. */
|
||||||
const auto it = accessor.find(IdObjectHelper(thread_id));
|
if (const auto it = accessor.find_key(thread_id); it != end) {
|
||||||
|
/* Try to open the thread. */
|
||||||
/* Check to make sure we found the thread. */
|
if (KThread *thread = static_cast<KThread *>(std::addressof(*it)); AMS_LIKELY(thread->Open())) {
|
||||||
if (it == end) {
|
MESOSPHERE_ASSERT(thread->GetId() == thread_id);
|
||||||
return nullptr;
|
return thread;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the thread. */
|
/* We failed to find or couldn't open the thread. */
|
||||||
KThread *thread = static_cast<KThread *>(std::addressof(*it));
|
|
||||||
|
|
||||||
/* Open the thread. */
|
|
||||||
if (AMS_LIKELY(thread->Open())) {
|
|
||||||
MESOSPHERE_ASSERT(thread->GetId() == thread_id);
|
|
||||||
return thread;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We failed to find the thread. */
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue