From edcd4cbc26d09b405fb05621338e7b1fc69a64b7 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Sat, 3 Nov 2018 10:31:03 -0700 Subject: [PATCH] Result: Refactor to have compiletime defs --- mesosphere/include/mesosphere/core/Result.hpp | 198 +++++++++++------- .../include/mesosphere/threading/KThread.hpp | 2 +- 2 files changed, 127 insertions(+), 73 deletions(-) diff --git a/mesosphere/include/mesosphere/core/Result.hpp b/mesosphere/include/mesosphere/core/Result.hpp index f28366bab..a5ad0b60d 100644 --- a/mesosphere/include/mesosphere/core/Result.hpp +++ b/mesosphere/include/mesosphere/core/Result.hpp @@ -5,83 +5,137 @@ namespace mesosphere { -class Result final { +enum class ResultModule : uint { + None = 0, + Kernel = 1, + /* Other modules not included. */ +}; + +class ResultHelper { public: - enum class Module : uint { - None = 0, - Kernel = 1, - /* Other modules not included. */ + using BaseType = uint; + static constexpr BaseType SuccessValue = BaseType(); + static constexpr BaseType ModuleBits = 9; + static constexpr BaseType DescriptionBits = 13; + + template + struct MakeResult : public std::integral_constant(module)) | (description << ModuleBits))> { + static_assert(static_cast(module) < 1 << (ModuleBits + 1), "Invalid Module"); + static_assert(description < 1 << (DescriptionBits + 1), "Invalid Description"); }; - - enum class Description : uint { - None = 0, - - InvalidCapabilityDescriptor = 14, - - NotImplemented = 33, - - ThreadTerminated = 59, - - OutOfDebugEvents = 70, - - InvalidSize = 101, - InvalidAddress = 102, - AllocatorDepleted = 103, - OutOfMemory = 104, - OutOfHandles = 105, - InvalidMemoryState = 106, - InvalidMemoryPermissions = 108, - InvalidMemoryRange = 110, - InvalidPriority = 112, - InvalidCoreId = 113, - InvalidHandle = 114, - InvalidUserBuffer = 115, - InvalidCombination = 116, - TimedOut = 117, - Cancelled = 118, - OutOfRange = 119, - InvalidEnumValue = 120, - NotFound = 121, - AlreadyExists = 122, - ConnectionClosed = 123, - UnhandledUserInterrupt = 124, - InvalidState = 125, - ReservedValue = 126, - InvalidHwBreakpoint = 127, - FatalUserException = 128, - OwnedByAnotherProcess = 129, - ConnectionRefused = 131, - OutOfResource = 132, - - IpcMapFailed = 259, - IpcCmdbufTooSmall = 260, - - NotDebugged = 520, - }; - - constexpr Result() : module{(uint)Module::None}, description{(uint)Description::None}, padding{0} {} - constexpr Result(Description description, Module module = Module::Kernel) : - module{(uint)module}, description{(uint)description}, padding{0} {} - - constexpr bool IsSuccess() const - { - return module == (uint)Module::None && description == (uint)Description::None && padding == 0; + + static constexpr ResultModule GetModule(BaseType value) { + return static_cast(value & ~(~BaseType() << ModuleBits)); } - constexpr bool operator==(const Result &other) const - { - return module == other.module && description == other.description && padding == other.padding; + + static constexpr BaseType GetDescription(BaseType value) { + return ((value >> ModuleBits) & ~(~BaseType() << DescriptionBits)); } - constexpr bool operator!=(const Result &other) const { return !(*this == other); } +}; + - constexpr Module GetModule() const { return (Module)module; } - constexpr Description GetDescription() const { return (Description)module; } - - void SetModule(Module module) { this->module = (uint)module; } - void SetDescription(Description description) { this->description = (uint)description;} - private: - uint module : 9; - uint description : 13; - uint padding : 10; +/* Use CRTP for Results. */ +template +class ResultBase { + public: + using BaseType = typename ResultHelper::BaseType; + static constexpr BaseType SuccessValue = ResultHelper::SuccessValue; + + constexpr bool IsSuccess() const { return static_cast(this)->GetValue() == SuccessValue; } + constexpr bool IsFailure() const { return !IsSuccess(); } + constexpr operator bool() const { return IsSuccess(); } + constexpr bool operator !() const { return IsFailure(); } + + constexpr ResultModule GetModule() const { return static_cast(this)->GetValue(); } + constexpr BaseType GetDescription() const { return static_cast(this)->GetValue(); } }; +/* Actual result type. */ +class Result final : public ResultBase { + public: + using BaseType = typename ResultBase::BaseType; + static constexpr BaseType SuccessValue = ResultBase::SuccessValue; + + constexpr Result() : value(SuccessValue) {} + + constexpr BaseType GetValue() const { return this->value; } + constexpr bool operator==(const Result &other) const { return value == other.value; } + constexpr bool operator!=(const Result &other) const { return value != other.value; } + + static constexpr Result MakeResult(BaseType v) { return Result(v); } + + private: + BaseType value; + constexpr explicit Result(BaseType v) : value(v) {} +}; + +static_assert(sizeof(Result) == sizeof(Result::BaseType), "Bad Result definition!"); + +/* Successful result class. */ +class ResultSuccess final : public ResultBase { + public: + using BaseType = typename ResultBase::BaseType; + static constexpr BaseType SuccessValue = ResultBase::SuccessValue; + + constexpr operator Result() { return Result::MakeResult(SuccessValue); } + constexpr BaseType GetValue() const { return SuccessValue; } +}; + +/* Error result class. */ +template +class ResultError : public ResultBase> { + public: + using BaseType = typename ResultBase>::BaseType; + static constexpr BaseType SuccessValue = ResultBase>::SuccessValue; + + static constexpr BaseType Value = ResultHelper::MakeResult::value; + static_assert(Value != SuccessValue, "Invalid ResultError"); + + constexpr operator Result() { return Result::MakeResult(Value); } + constexpr BaseType GetValue() const { return Value; } +}; + +#define DEFINE_RESULT(module, name, description) class Result##module##name final : public ResultError {} + +DEFINE_RESULT(Kernel, InvalidCapabilityDescriptor, 14); + +DEFINE_RESULT(Kernel, NotImplemented, 33); +DEFINE_RESULT(Kernel, ThreadTerminated, 59); + +DEFINE_RESULT(Kernel, OutOfDebugEvents, 70); + +DEFINE_RESULT(Kernel, InvalidSize, 101); +DEFINE_RESULT(Kernel, InvalidAddress, 102); +DEFINE_RESULT(Kernel, ResourceExhausted, 103); +DEFINE_RESULT(Kernel, OutOfMemory, 104); +DEFINE_RESULT(Kernel, OutOfHandles, 105); +DEFINE_RESULT(Kernel, InvalidMemoryState, 106); +DEFINE_RESULT(Kernel, InvalidMemoryPermissions, 108); +DEFINE_RESULT(Kernel, InvalidMemoryRange, 110); +DEFINE_RESULT(Kernel, InvalidPriority, 112); +DEFINE_RESULT(Kernel, InvalidCoreId, 113); +DEFINE_RESULT(Kernel, InvalidHandle, 114); +DEFINE_RESULT(Kernel, InvalidUserBuffer, 115); +DEFINE_RESULT(Kernel, InvalidCombination, 116); +DEFINE_RESULT(Kernel, TimedOut, 117); +DEFINE_RESULT(Kernel, Cancelled, 118); +DEFINE_RESULT(Kernel, OutOfRange, 119); +DEFINE_RESULT(Kernel, InvalidEnumValue, 120); +DEFINE_RESULT(Kernel, NotFound, 121); +DEFINE_RESULT(Kernel, AlreadyExists, 122); +DEFINE_RESULT(Kernel, ConnectionClosed, 123); +DEFINE_RESULT(Kernel, UnhandledUserInterrupt, 124); +DEFINE_RESULT(Kernel, NotPermitted, 125); +DEFINE_RESULT(Kernel, ReservedValue, 126); +DEFINE_RESULT(Kernel, InvalidHwBreakpoint, 127); +DEFINE_RESULT(Kernel, FatalUserException, 128); +DEFINE_RESULT(Kernel, OwnedByAnotherProcess, 129); +DEFINE_RESULT(Kernel, ConnectionRefused, 131); +DEFINE_RESULT(Kernel, OutOfResource, 132); + +DEFINE_RESULT(Kernel, IpcMapFailed, 259); +DEFINE_RESULT(Kernel, IpcCmdbufTooSmall, 260); + +DEFINE_RESULT(Kernel, NotDebugged, 520); + } diff --git a/mesosphere/include/mesosphere/threading/KThread.hpp b/mesosphere/include/mesosphere/threading/KThread.hpp index 1cfbfe030..8ccc8f305 100644 --- a/mesosphere/include/mesosphere/threading/KThread.hpp +++ b/mesosphere/include/mesosphere/threading/KThread.hpp @@ -245,7 +245,7 @@ private: size_t numKernelMutexWaiters = 0; Handle syncResultHandle{}; - Result syncResult{}; + Result syncResult = ResultSuccess(); u64 lastScheduledTime = 0; };