#include "object/process.h" #include "debug/debug.h" #include "include/zcall.h" #include "memory/paging_util.h" #include "memory/physical_memory.h" #include "object/thread.h" #include "scheduler/scheduler.h" namespace { static uint64_t gNextId = 1; } RefPtr Process::RootProcess() { RefPtr proc = MakeRefCounted(0); proc->threads_.PushBack(Thread::RootThread(*proc)); proc->next_thread_id_ = 1; return proc; } RefPtr Process::Create() { auto proc = MakeRefCounted(); proc->caps_.PushBack( MakeRefCounted(proc, Capability::PROCESS, Z_INIT_PROC_SELF, ZC_PROC_SPAWN_PROC | ZC_PROC_SPAWN_THREAD)); proc->caps_.PushBack(MakeRefCounted( proc->vmas(), Capability::ADDRESS_SPACE, Z_INIT_VMAS_SELF, ZC_WRITE)); return proc; } Process::Process() : id_(gNextId++), vmas_(MakeRefCounted()), state_(RUNNING) {} RefPtr Process::CreateThread() { MutexHolder lock(mutex_); RefPtr thread = MakeRefCounted(*this, next_thread_id_++); threads_.PushBack(thread); return thread; } RefPtr Process::GetThread(uint64_t tid) { MutexHolder lock(mutex_); auto iter = threads_.begin(); while (iter != threads_.end()) { if (iter->tid() == tid) { return *iter; } ++iter; } panic("Bad thread access."); return nullptr; } void Process::CheckState() { MutexHolder lock(mutex_); auto iter = threads_.begin(); while (iter != threads_.end()) { if (iter->GetState() != Thread::FINISHED) { return; } ++iter; } state_ = FINISHED; } RefPtr Process::ReleaseCapability(uint64_t cid) { MutexHolder lock(mutex_); auto iter = caps_.begin(); while (iter != caps_.end()) { if (*iter && iter->id() == cid) { auto cap = *iter; *iter = {nullptr}; return cap; } ++iter; } dbgln("Bad cap release: %u", cid); dbgln("Num caps: %u", caps_.size()); return {}; } RefPtr Process::GetCapability(uint64_t cid) { MutexHolder lock(mutex_); auto iter = caps_.begin(); while (iter != caps_.end()) { if (*iter && iter->id() == cid) { return *iter; } ++iter; } dbgln("Bad cap access %u", cid); dbgln("Num caps: %u", caps_.size()); return {}; } uint64_t Process::AddCapability(const RefPtr& cap) { MutexHolder lock(mutex_); cap->set_id(next_cap_id_++); caps_.PushBack(cap); return cap->id(); } uint64_t Process::AddCapability(const RefPtr& thread) { MutexHolder lock(mutex_); uint64_t cap_id = next_cap_id_++; caps_.PushBack( MakeRefCounted(thread, Capability::THREAD, cap_id, ZC_WRITE)); return cap_id; } uint64_t Process::AddCapability(const RefPtr& p) { MutexHolder lock(mutex_); uint64_t cap_id = next_cap_id_++; caps_.PushBack(MakeRefCounted(p, Capability::PROCESS, cap_id, ZC_WRITE | ZC_PROC_SPAWN_THREAD)); return cap_id; } uint64_t Process::AddCapability(const RefPtr& vmas) { MutexHolder lock(mutex_); uint64_t cap_id = next_cap_id_++; caps_.PushBack(MakeRefCounted(vmas, Capability::ADDRESS_SPACE, cap_id, ZC_WRITE)); return cap_id; } uint64_t Process::AddCapability(const RefPtr& vmmo) { MutexHolder lock(mutex_); uint64_t cap_id = next_cap_id_++; caps_.PushBack(MakeRefCounted(vmmo, Capability::MEMORY_OBJECT, cap_id, ZC_WRITE)); return cap_id; } uint64_t Process::AddCapability(const RefPtr& chan) { MutexHolder lock(mutex_); uint64_t cap_id = next_cap_id_++; caps_.PushBack(MakeRefCounted(chan, Capability::CHANNEL, cap_id, ZC_WRITE | ZC_READ)); return cap_id; } uint64_t Process::AddCapability(const RefPtr& port) { MutexHolder lock(mutex_); uint64_t cap_id = next_cap_id_++; caps_.PushBack(MakeRefCounted(port, Capability::PORT, cap_id, ZC_WRITE | ZC_READ)); return cap_id; } void Process::AddCapability(uint64_t cap_id, const RefPtr& vmmo) { MutexHolder lock(mutex_); caps_.PushBack(MakeRefCounted(vmmo, Capability::MEMORY_OBJECT, cap_id, ZC_WRITE)); }