1
0
Fork 0
forked from suyu/suyu

kernel: convert KResourceLimit

This commit is contained in:
Liam 2023-03-07 10:58:51 -05:00
parent c0b9e93b77
commit 641783df8f
2 changed files with 59 additions and 59 deletions

View file

@ -12,11 +12,11 @@ namespace Kernel {
constexpr s64 DefaultTimeout = 10000000000; // 10 seconds constexpr s64 DefaultTimeout = 10000000000; // 10 seconds
KResourceLimit::KResourceLimit(KernelCore& kernel) KResourceLimit::KResourceLimit(KernelCore& kernel)
: KAutoObjectWithSlabHeapAndContainer{kernel}, lock{kernel}, cond_var{kernel} {} : KAutoObjectWithSlabHeapAndContainer{kernel}, m_lock{m_kernel}, m_cond_var{m_kernel} {}
KResourceLimit::~KResourceLimit() = default; KResourceLimit::~KResourceLimit() = default;
void KResourceLimit::Initialize(const Core::Timing::CoreTiming* core_timing_) { void KResourceLimit::Initialize(const Core::Timing::CoreTiming* core_timing) {
core_timing = core_timing_; m_core_timing = core_timing;
} }
void KResourceLimit::Finalize() {} void KResourceLimit::Finalize() {}
@ -25,11 +25,11 @@ s64 KResourceLimit::GetLimitValue(LimitableResource which) const {
const auto index = static_cast<std::size_t>(which); const auto index = static_cast<std::size_t>(which);
s64 value{}; s64 value{};
{ {
KScopedLightLock lk{lock}; KScopedLightLock lk{m_lock};
value = limit_values[index]; value = m_limit_values[index];
ASSERT(value >= 0); ASSERT(value >= 0);
ASSERT(current_values[index] <= limit_values[index]); ASSERT(m_current_values[index] <= m_limit_values[index]);
ASSERT(current_hints[index] <= current_values[index]); ASSERT(m_current_hints[index] <= m_current_values[index]);
} }
return value; return value;
} }
@ -38,11 +38,11 @@ s64 KResourceLimit::GetCurrentValue(LimitableResource which) const {
const auto index = static_cast<std::size_t>(which); const auto index = static_cast<std::size_t>(which);
s64 value{}; s64 value{};
{ {
KScopedLightLock lk{lock}; KScopedLightLock lk{m_lock};
value = current_values[index]; value = m_current_values[index];
ASSERT(value >= 0); ASSERT(value >= 0);
ASSERT(current_values[index] <= limit_values[index]); ASSERT(m_current_values[index] <= m_limit_values[index]);
ASSERT(current_hints[index] <= current_values[index]); ASSERT(m_current_hints[index] <= m_current_values[index]);
} }
return value; return value;
} }
@ -51,11 +51,11 @@ s64 KResourceLimit::GetPeakValue(LimitableResource which) const {
const auto index = static_cast<std::size_t>(which); const auto index = static_cast<std::size_t>(which);
s64 value{}; s64 value{};
{ {
KScopedLightLock lk{lock}; KScopedLightLock lk{m_lock};
value = peak_values[index]; value = m_peak_values[index];
ASSERT(value >= 0); ASSERT(value >= 0);
ASSERT(current_values[index] <= limit_values[index]); ASSERT(m_current_values[index] <= m_limit_values[index]);
ASSERT(current_hints[index] <= current_values[index]); ASSERT(m_current_hints[index] <= m_current_values[index]);
} }
return value; return value;
} }
@ -64,11 +64,11 @@ s64 KResourceLimit::GetFreeValue(LimitableResource which) const {
const auto index = static_cast<std::size_t>(which); const auto index = static_cast<std::size_t>(which);
s64 value{}; s64 value{};
{ {
KScopedLightLock lk(lock); KScopedLightLock lk(m_lock);
ASSERT(current_values[index] >= 0); ASSERT(m_current_values[index] >= 0);
ASSERT(current_values[index] <= limit_values[index]); ASSERT(m_current_values[index] <= m_limit_values[index]);
ASSERT(current_hints[index] <= current_values[index]); ASSERT(m_current_hints[index] <= m_current_values[index]);
value = limit_values[index] - current_values[index]; value = m_limit_values[index] - m_current_values[index];
} }
return value; return value;
@ -76,51 +76,51 @@ s64 KResourceLimit::GetFreeValue(LimitableResource which) const {
Result KResourceLimit::SetLimitValue(LimitableResource which, s64 value) { Result KResourceLimit::SetLimitValue(LimitableResource which, s64 value) {
const auto index = static_cast<std::size_t>(which); const auto index = static_cast<std::size_t>(which);
KScopedLightLock lk(lock); KScopedLightLock lk(m_lock);
R_UNLESS(current_values[index] <= value, ResultInvalidState); R_UNLESS(m_current_values[index] <= value, ResultInvalidState);
limit_values[index] = value; m_limit_values[index] = value;
peak_values[index] = current_values[index]; m_peak_values[index] = m_current_values[index];
R_SUCCEED(); R_SUCCEED();
} }
bool KResourceLimit::Reserve(LimitableResource which, s64 value) { bool KResourceLimit::Reserve(LimitableResource which, s64 value) {
return Reserve(which, value, core_timing->GetGlobalTimeNs().count() + DefaultTimeout); return Reserve(which, value, m_core_timing->GetGlobalTimeNs().count() + DefaultTimeout);
} }
bool KResourceLimit::Reserve(LimitableResource which, s64 value, s64 timeout) { bool KResourceLimit::Reserve(LimitableResource which, s64 value, s64 timeout) {
ASSERT(value >= 0); ASSERT(value >= 0);
const auto index = static_cast<std::size_t>(which); const auto index = static_cast<std::size_t>(which);
KScopedLightLock lk(lock); KScopedLightLock lk(m_lock);
ASSERT(current_hints[index] <= current_values[index]); ASSERT(m_current_hints[index] <= m_current_values[index]);
if (current_hints[index] >= limit_values[index]) { if (m_current_hints[index] >= m_limit_values[index]) {
return false; return false;
} }
// Loop until we reserve or run out of time. // Loop until we reserve or run out of time.
while (true) { while (true) {
ASSERT(current_values[index] <= limit_values[index]); ASSERT(m_current_values[index] <= m_limit_values[index]);
ASSERT(current_hints[index] <= current_values[index]); ASSERT(m_current_hints[index] <= m_current_values[index]);
// If we would overflow, don't allow to succeed. // If we would overflow, don't allow to succeed.
if (Common::WrappingAdd(current_values[index], value) <= current_values[index]) { if (Common::WrappingAdd(m_current_values[index], value) <= m_current_values[index]) {
break; break;
} }
if (current_values[index] + value <= limit_values[index]) { if (m_current_values[index] + value <= m_limit_values[index]) {
current_values[index] += value; m_current_values[index] += value;
current_hints[index] += value; m_current_hints[index] += value;
peak_values[index] = std::max(peak_values[index], current_values[index]); m_peak_values[index] = std::max(m_peak_values[index], m_current_values[index]);
return true; return true;
} }
if (current_hints[index] + value <= limit_values[index] && if (m_current_hints[index] + value <= m_limit_values[index] &&
(timeout < 0 || core_timing->GetGlobalTimeNs().count() < timeout)) { (timeout < 0 || m_core_timing->GetGlobalTimeNs().count() < timeout)) {
waiter_count++; m_waiter_count++;
cond_var.Wait(&lock, timeout, false); m_cond_var.Wait(&m_lock, timeout, false);
waiter_count--; m_waiter_count--;
} else { } else {
break; break;
} }
@ -138,17 +138,17 @@ void KResourceLimit::Release(LimitableResource which, s64 value, s64 hint) {
ASSERT(hint >= 0); ASSERT(hint >= 0);
const auto index = static_cast<std::size_t>(which); const auto index = static_cast<std::size_t>(which);
KScopedLightLock lk(lock); KScopedLightLock lk(m_lock);
ASSERT(current_values[index] <= limit_values[index]); ASSERT(m_current_values[index] <= m_limit_values[index]);
ASSERT(current_hints[index] <= current_values[index]); ASSERT(m_current_hints[index] <= m_current_values[index]);
ASSERT(value <= current_values[index]); ASSERT(value <= m_current_values[index]);
ASSERT(hint <= current_hints[index]); ASSERT(hint <= m_current_hints[index]);
current_values[index] -= value; m_current_values[index] -= value;
current_hints[index] -= hint; m_current_hints[index] -= hint;
if (waiter_count != 0) { if (m_waiter_count != 0) {
cond_var.Broadcast(); m_cond_var.Broadcast();
} }
} }

View file

@ -28,10 +28,10 @@ class KResourceLimit final
KERNEL_AUTOOBJECT_TRAITS(KResourceLimit, KAutoObject); KERNEL_AUTOOBJECT_TRAITS(KResourceLimit, KAutoObject);
public: public:
explicit KResourceLimit(KernelCore& kernel_); explicit KResourceLimit(KernelCore& kernel);
~KResourceLimit() override; ~KResourceLimit() override;
void Initialize(const Core::Timing::CoreTiming* core_timing_); void Initialize(const Core::Timing::CoreTiming* core_timing);
void Finalize() override; void Finalize() override;
s64 GetLimitValue(LimitableResource which) const; s64 GetLimitValue(LimitableResource which) const;
@ -50,14 +50,14 @@ public:
private: private:
using ResourceArray = std::array<s64, static_cast<std::size_t>(LimitableResource::Count)>; using ResourceArray = std::array<s64, static_cast<std::size_t>(LimitableResource::Count)>;
ResourceArray limit_values{}; ResourceArray m_limit_values{};
ResourceArray current_values{}; ResourceArray m_current_values{};
ResourceArray current_hints{}; ResourceArray m_current_hints{};
ResourceArray peak_values{}; ResourceArray m_peak_values{};
mutable KLightLock lock; mutable KLightLock m_lock;
s32 waiter_count{}; s32 m_waiter_count{};
KLightConditionVariable cond_var; KLightConditionVariable m_cond_var;
const Core::Timing::CoreTiming* core_timing{}; const Core::Timing::CoreTiming* m_core_timing{};
}; };
KResourceLimit* CreateResourceLimitForProcess(Core::System& system, s64 physical_memory_size); KResourceLimit* CreateResourceLimitForProcess(Core::System& system, s64 physical_memory_size);