KConditionVariable/KAddressArbiter: no need for global compare thread
This commit is contained in:
@@ -20,8 +20,6 @@
|
||||
|
||||
namespace ams::kern {
|
||||
|
||||
extern KThread g_cv_arbiter_compare_thread;
|
||||
|
||||
class KConditionVariable {
|
||||
public:
|
||||
using ThreadTree = typename KThread::ConditionVariableThreadTreeType;
|
||||
|
||||
@@ -124,7 +124,21 @@ namespace ams::kern {
|
||||
static_assert(sizeof(SyncObjectBuffer::sync_objects) == sizeof(SyncObjectBuffer::handles));
|
||||
|
||||
struct ConditionVariableComparator {
|
||||
static constexpr ALWAYS_INLINE int Compare(const KThread &lhs, const KThread &rhs) {
|
||||
struct LightCompareType {
|
||||
uintptr_t cv_key;
|
||||
s32 priority;
|
||||
|
||||
constexpr ALWAYS_INLINE uintptr_t GetConditionVariableKey() const {
|
||||
return this->cv_key;
|
||||
}
|
||||
|
||||
constexpr ALWAYS_INLINE s32 GetPriority() const {
|
||||
return this->priority;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T> requires (std::same_as<T, KThread> || std::same_as<T, LightCompareType>)
|
||||
static constexpr ALWAYS_INLINE int Compare(const T &lhs, const KThread &rhs) {
|
||||
const uintptr_t l_key = lhs.GetConditionVariableKey();
|
||||
const uintptr_t r_key = rhs.GetConditionVariableKey();
|
||||
|
||||
@@ -139,6 +153,8 @@ namespace ams::kern {
|
||||
}
|
||||
}
|
||||
};
|
||||
static_assert(ams::util::HasLightCompareType<ConditionVariableComparator>);
|
||||
static_assert(std::same_as<ams::util::LightCompareType<ConditionVariableComparator, void>, ConditionVariableComparator::LightCompareType>);
|
||||
private:
|
||||
static inline std::atomic<u64> s_next_thread_id = 0;
|
||||
private:
|
||||
|
||||
@@ -50,9 +50,8 @@ namespace ams::kern {
|
||||
s32 num_waiters = 0;
|
||||
{
|
||||
KScopedSchedulerLock sl;
|
||||
g_cv_arbiter_compare_thread.SetupForAddressArbiterCompare(addr, -1);
|
||||
|
||||
auto it = this->tree.nfind(g_cv_arbiter_compare_thread);
|
||||
auto it = this->tree.nfind_light({ addr, -1 });
|
||||
while ((it != this->tree.end()) && (count <= 0 || num_waiters < count) && (it->GetAddressArbiterKey() == addr)) {
|
||||
KThread *target_thread = std::addressof(*it);
|
||||
target_thread->SetSyncedObject(nullptr, ResultSuccess());
|
||||
@@ -79,10 +78,7 @@ namespace ams::kern {
|
||||
R_UNLESS(UpdateIfEqual(std::addressof(user_value), addr, value, value + 1), svc::ResultInvalidCurrentMemory());
|
||||
R_UNLESS(user_value == value, svc::ResultInvalidState());
|
||||
|
||||
g_cv_arbiter_compare_thread.SetupForAddressArbiterCompare(addr, -1);
|
||||
|
||||
auto it = this->tree.nfind(g_cv_arbiter_compare_thread);
|
||||
|
||||
auto it = this->tree.nfind_light({ addr, -1 });
|
||||
while ((it != this->tree.end()) && (count <= 0 || num_waiters < count) && (it->GetAddressArbiterKey() == addr)) {
|
||||
KThread *target_thread = std::addressof(*it);
|
||||
target_thread->SetSyncedObject(nullptr, ResultSuccess());
|
||||
@@ -103,10 +99,8 @@ namespace ams::kern {
|
||||
s32 num_waiters = 0;
|
||||
{
|
||||
KScopedSchedulerLock sl;
|
||||
g_cv_arbiter_compare_thread.SetupForAddressArbiterCompare(addr, -1);
|
||||
|
||||
auto it = this->tree.nfind(g_cv_arbiter_compare_thread);
|
||||
|
||||
auto it = this->tree.nfind_light({ addr, -1 });
|
||||
/* Determine the updated value. */
|
||||
s32 new_value;
|
||||
if (GetTargetFirmware() >= TargetFirmware_7_0_0) {
|
||||
|
||||
@@ -17,8 +17,6 @@
|
||||
|
||||
namespace ams::kern {
|
||||
|
||||
constinit KThread g_cv_arbiter_compare_thread;
|
||||
|
||||
namespace {
|
||||
|
||||
ALWAYS_INLINE bool ReadFromUser(u32 *out, KProcessAddress address) {
|
||||
@@ -179,9 +177,8 @@ namespace ams::kern {
|
||||
int num_waiters = 0;
|
||||
{
|
||||
KScopedSchedulerLock sl;
|
||||
g_cv_arbiter_compare_thread.SetupForConditionVariableCompare(cv_key, -1);
|
||||
|
||||
auto it = this->tree.nfind(g_cv_arbiter_compare_thread);
|
||||
auto it = this->tree.nfind_light({ cv_key, -1 });
|
||||
while ((it != this->tree.end()) && (count <= 0 || num_waiters < count) && (it->GetConditionVariableKey() == cv_key)) {
|
||||
KThread *target_thread = std::addressof(*it);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user