diff --git a/furvm/include/furvm/context.hpp b/furvm/include/furvm/context.hpp index 6bed0a4..82ef5c1 100644 --- a/furvm/include/furvm/context.hpp +++ b/furvm/include/furvm/context.hpp @@ -13,8 +13,10 @@ namespace furvm { class context { public: using value_type = std::unique_ptr; /**< An alias to unique pointer of module. */ + + friend class executor; public: - context() = default; + context(); ~context() = default; /** @@ -92,7 +94,8 @@ public: */ constexpr size_t size() const { return m_modules.size(); } private: - std::vector> m_modules; + std::vector> m_modules; + std::vector> m_executors; }; } // namespace furvm diff --git a/furvm/include/furvm/executor.hpp b/furvm/include/furvm/executor.hpp new file mode 100644 index 0000000..467c412 --- /dev/null +++ b/furvm/include/furvm/executor.hpp @@ -0,0 +1,88 @@ +#ifndef FURVM_EXECUTOR_HPP +#define FURVM_EXECUTOR_HPP + +#include "furvm/fwd.hpp" + +#include + +namespace furvm { + +enum class executor_flags : std::uint32_t { + Suspended = (1 << 0), /**< Execution suspended. */ +}; + +static inline executor_flags operator|(executor_flags lhs, executor_flags rhs) { + return executor_flags(static_cast(lhs) | static_cast(rhs)); +} + +static inline executor_flags operator&(executor_flags lhs, executor_flags rhs) { + return executor_flags(static_cast(lhs) & static_cast(rhs)); +} + +static inline executor_flags operator~(executor_flags flags) { + return executor_flags(~static_cast(flags)); +} + +class executor { +private: + /** + * @brief A private token for the private constructor. + * + * Also `egzekutor` in Polish translates to `executor` I think. + */ + struct egzekutor { + explicit egzekutor() = default; + }; +public: + /** + * @brief Private constructor. + * + * @param id + * @param context + */ + executor(egzekutor, executor_handle id, const std::shared_ptr& context); + + ~executor(); + + /** + * @brief Move constructor. + */ + executor(executor&&) = default; + + /** + * @brief Move constructor. + */ + executor& operator=(executor&&) = default; + + executor(const executor&) = delete; + executor& operator=(const executor&) = delete; +public: + /** + * @brief Returns a new executor. + * + * @param context Furvm context. + */ + static std::shared_ptr create(const std::shared_ptr& context); +public: + /** + * @brief Returns an id of this executor. + * + * @return The id. + */ + executor_handle id() const { return m_id; } + + /** + * @brief Returns flags of this executor. + * + * @return The flags. + */ + executor_flags flags() const { return m_flags; } +private: + executor_handle m_id; + executor_flags m_flags{}; // NOLINT(bugprone-invalid-enum-default-initialization) + std::shared_ptr m_context; +}; + +} // namespace furvm + +#endif // FURVM_EXECUTOR_HPP \ No newline at end of file diff --git a/furvm/include/furvm/fwd.hpp b/furvm/include/furvm/fwd.hpp index 545eeef..1b6b0f5 100644 --- a/furvm/include/furvm/fwd.hpp +++ b/furvm/include/furvm/fwd.hpp @@ -61,6 +61,27 @@ class mod; */ using module_handle = std::uint32_t; +// executor.hpp + +/** + * @enum executor_flags + * @brief Flags of an executor. + */ +enum class executor_flags : std::uint32_t; + +/** + * @class executor + * @brief Furvm executor. + * + * Furvm executors are like threads. + */ +class executor; + +/** + * @brief Furvm executor's index. + */ +using executor_handle = std::uint32_t; + // context.hpp /** diff --git a/furvm/src/context.cpp b/furvm/src/context.cpp index 29023e9..f1b3877 100644 --- a/furvm/src/context.cpp +++ b/furvm/src/context.cpp @@ -1,3 +1,7 @@ #include "furvm/context.hpp" -namespace furvm {} \ No newline at end of file +namespace furvm { + +context::context() {} + +} // namespace furvm \ No newline at end of file diff --git a/furvm/src/executor.cpp b/furvm/src/executor.cpp new file mode 100644 index 0000000..4fc7e58 --- /dev/null +++ b/furvm/src/executor.cpp @@ -0,0 +1,20 @@ +#include "furvm/executor.hpp" + +#include "furvm/context.hpp" + +namespace furvm { + +executor::executor(egzekutor, executor_handle id, const std::shared_ptr& context) + : m_id(id), m_context(context) {} + +executor::~executor() { + m_context->m_executors[m_id] = nullptr; +} + +std::shared_ptr executor::create(const std::shared_ptr& context) { + auto ex = std::make_shared(egzekutor{}, context->m_executors.size(), context); + context->m_executors.push_back(ex); + return std::move(ex); +} + +} // namespace furvm \ No newline at end of file diff --git a/furvm/src/main.cpp b/furvm/src/main.cpp index 0ff8592..3105ce7 100644 --- a/furvm/src/main.cpp +++ b/furvm/src/main.cpp @@ -1,10 +1,12 @@ #ifndef LIBFURVM #include "furvm/context.hpp" +#include "furvm/executor.hpp" #include "furvm/instruction.hpp" #include #include +#include static constexpr std::array s_bytecode = { furvm::byte(furvm::instruction_t::PushB2I), @@ -13,9 +15,11 @@ static constexpr std::array s_bytecode = { }; int main(void) { - furvm::context context; + auto context = std::make_shared(); - const auto& mainModule = context.emplace(s_bytecode.begin(), s_bytecode.end()); + const auto& mainModule = context->emplace(s_bytecode.begin(), s_bytecode.end()); + + auto executor = furvm::executor::create(context); return 0; }