#pragma once #include "gp_config.hpp" #include "gp/functional/function.hpp" #include "gp/containers/indexed_array.hpp" #include "gp/utils/pointers.hpp" #include "gp/ipc/file_description.hpp" #include "gp/system/platforms/platform_autopicker.hpp" #include namespace gp { namespace system { /** * @brief Represent the different execution states a process can be in */ enum class process_status { inactive = 0, running = 1, waiting = 2, finished = 3, zombie = 4 }; /** * @brief A process ID type */ using pid_t = size_t; /** * @brief Represent and manages all the process info the scheduler doesn't need to be aware of * * Anything thread local is part of that */ struct base_process_info { virtual void initialize() {} //< An initializer virtual void checkpoint() {} //< Creates a checkpoint if the feature is available virtual void restore() {} //< Restores a checkpoint if the feature is available virtual void switch_in() {} //< Called as the process is resuming virtual void switch_out() {} //< Called as the process is paused virtual void cleanup() {} //< Called before the process get destroyed virtual ~base_process_info() {} //< Called as the process is destroyed }; /** * @brief Represents the data used for scheduling and managing a process resources. */ struct process_data{ pid_t pid; //< The current pid gp::function fn; //< Whatever there is to execute void* stack; //< The stack lower bound pointer size_t stack_sz; //< The stack size in bytes gp::system::process_status state; //< The current process' state std::atomic_bool is_running; //< Whenever the process is currently using execution time [[no_unique_address]] gp::system::specifics::platform_data specifics; //< The special bits used to handle context switching gp::unique_ptr info; //< Other data related to processes but not to scheduling process_data(gp::function _fn, void* _stack, size_t _stack_sz, gp::unique_ptr&& _info) : fn(_fn) , stack(_stack) , stack_sz(_stack_sz) , state(gp::system::process_status::inactive) , specifics(gp::buffer{(char*)stack, stack_sz}) , info(gp::move(_info)) {} process_data(process_data&& v) : fn(v.fn) , stack(v.stack) , stack_sz(v.stack_sz) , state(v.state) , specifics(v.specifics) , info(gp::move(v.info)) {} ~process_data() { if(info) { info->cleanup(); } } }; } }