#pragma once #include #include #include #include "capability/capability.h" #include "capability/capability_table.h" #include "object/address_space.h" #include "object/channel.h" #include "object/mutex.h" #include "object/port.h" // Forward decl due to cyclic dependency. class Thread; template <> struct KernelObjectTag { static const uint64_t type = KernelObject::PROCESS; }; class Process : public KernelObject { public: uint64_t TypeTag() override { return KernelObject::PROCESS; } static uint64_t DefaultPermissions() { return kZionPerm_Write | kZionPerm_Read | kZionPerm_SpawnThread | kZionPerm_SpawnProcess | kZionPerm_Duplicate | kZionPerm_Transmit; } enum State { UNSPECIFIED, SETUP, RUNNING, FINISHED, }; static glcr::RefPtr RootProcess(); static glcr::RefPtr Create(); uint64_t id() const { return id_; } glcr::RefPtr vmas() { return vmas_; } glcr::RefPtr CreateThread(); glcr::RefPtr GetThread(uint64_t tid); glcr::RefPtr ReleaseCapability(uint64_t cid); glcr::RefPtr GetCapability(uint64_t cid); template uint64_t AddNewCapability(const glcr::RefPtr& obj, uint64_t permissions) { return caps_.AddNewCapability(obj, permissions); } template uint64_t AddNewCapability(const glcr::RefPtr& obj) { return caps_.AddNewCapability(obj); } uint64_t AddExistingCapability(const glcr::RefPtr& cap); // Checks the state of all child threads and transitions to // finished if all have finished. void CheckState(); State GetState() { return state_; } void Exit(); private: friend class glcr::MakeRefCountedFriend; Process(); Process(uint64_t id) : id_(id), vmas_(AddressSpace::ForRoot()) {} glcr::RefPtr mutex_ = Mutex::Create(); uint64_t id_; glcr::RefPtr vmas_; State state_; uint64_t next_thread_id_ = 0; glcr::Vector> threads_; CapabilityTable caps_; };