Files
Atmosphere/mesosphere/include/mesosphere/processes/KHandleTable.hpp
2019-06-03 17:41:01 -07:00

76 lines
2.0 KiB
C++

#pragma once
#include <mesosphere/core/util.hpp>
#include <mesosphere/core/Handle.hpp>
#include <mesosphere/kresources/KAutoObject.hpp>
#include <mesosphere/arch/KSpinLock.hpp>
#include <array>
namespace mesosphere
{
class KThread;
class KProcess;
class KHandleTable final {
public:
static constexpr size_t capacityLimit = 1024;
static constexpr Handle selfThreadAlias{0, -1, true};
static constexpr Handle selfProcessAlias{1, -1, true};
template<typename T>
SharedPtr<T> Get(Handle handle, bool allowAlias = true) const
{
if constexpr (std::is_same_v<T, KAutoObject>) {
(void)allowAlias;
return GetAutoObject(handle);
} else if constexpr (std::is_same_v<T, KThread>) {
return GetThread(handle, allowAlias);
} else if constexpr (std::is_same_v<T, KProcess>) {
return GetProcess(handle, allowAlias);
} else {
return DynamicObjectCast<T>(GetAutoObject(handle));
}
}
bool Generate(Handle &out, SharedPtr<KAutoObject> obj);
/// For deferred-init
bool Set(SharedPtr<KAutoObject> obj, Handle handle);
bool Close(Handle handle);
void Destroy();
constexpr size_t GetNumActive() const { return numActive; }
constexpr size_t GetSize() const { return size; }
constexpr size_t GetCapacity() const { return capacity; }
KHandleTable(size_t capacity);
~KHandleTable();
private:
bool IsValid(Handle handle) const;
SharedPtr<KAutoObject> GetAutoObject(Handle handle) const;
SharedPtr<KThread> GetThread(Handle handle, bool allowAlias = true) const;
SharedPtr<KProcess> GetProcess(Handle handle, bool allowAlias = true) const;
struct Entry {
SharedPtr<KAutoObject> object{};
s16 id = 0;
};
std::array<Entry, capacityLimit> entries{};
// Here the official kernel uses pointer, Yuzu and ourselves are repurposing a field in Entry instead.
s16 firstFreeIndex = 0;
s16 idCounter = 1;
u16 numActive = 0, size = 0, capacity = 0;
mutable KSpinLock spinlock;
};
}