diff --git a/lib/glacier/container/vector.h b/lib/glacier/container/vector.h new file mode 100644 index 0000000..9f2d343 --- /dev/null +++ b/lib/glacier/container/vector.h @@ -0,0 +1,110 @@ +#pragma once + +#include +#include + +namespace glcr { + +template +class Vector { + public: + Vector() : data_(nullptr), size_(0), capacity_(0) {} + + Vector(const Vector&) = delete; + // TODO: Implement Move + Vector(Vector&&) = delete; + + ~Vector() { delete[] data_; } + + // FIXME: Handle downsizing. + void Resize(uint64_t capacity); + + // Setters. + void PushBack(const T& item); + void PushBack(T&& item); + template + void EmplaceBack(Args... args); + + // Accessors. + T& operator[](uint64_t index); + const T& operator[](uint64_t index) const; + T& at(uint64_t index); + const T& at(uint64_t index) const; + + uint64_t size() const { return size_; } + uint64_t capacity() const { return capacity_; } + + private: + T* data_; + uint64_t size_; + uint64_t capacity_; + + void Expand(); +}; + +template +void Vector::Resize(uint64_t capacity) { + T* new_data = reinterpret_cast(new uint8_t[capacity * sizeof(T)]); + for (uint64_t i = 0; i < size_; i++) { + new_data[i] = glcr::Move(data_[i]); + } + delete[] data_; + data_ = new_data; + capacity_ = capacity; +} + +template +void Vector::PushBack(const T& item) { + if (size_ >= capacity_) { + Expand(); + } + + data_[size_++] = item; +} + +template +void Vector::PushBack(T&& item) { + if (size_ >= capacity_) { + Expand(); + } + + data_[size_++] = glcr::Move(item); +} + +template +template +void Vector::EmplaceBack(Args... args) { + if (size_ >= capacity_) { + Expand(); + } + + data_[size_++] = T(args...); +} + +template +T& Vector::operator[](uint64_t index) { + return data_[index]; +} + +template +const T& Vector::operator[](uint64_t index) const { + return data_[index]; +} + +template +T& Vector::at(uint64_t index) { + return data_[index]; +} + +template +const T& Vector::at(uint64_t index) const { + return data_[index]; +} + +template +void Vector::Expand() { + uint64_t new_capacity = capacity_ == 0 ? 1 : capacity_ * 2; + Resize(new_capacity); +} + +} // namespace glcr diff --git a/zion/memory/kernel_heap.cpp b/zion/memory/kernel_heap.cpp index 8d82df4..0fb84fc 100644 --- a/zion/memory/kernel_heap.cpp +++ b/zion/memory/kernel_heap.cpp @@ -68,3 +68,4 @@ void* operator new(uint64_t size) { return GetKernelHeap().Allocate(size); } void* operator new[](uint64_t size) { return GetKernelHeap().Allocate(size); } void operator delete(void*, uint64_t) {} +void operator delete[](void*) {} diff --git a/zion/object/process.cpp b/zion/object/process.cpp index 456f3a6..7829c63 100644 --- a/zion/object/process.cpp +++ b/zion/object/process.cpp @@ -39,25 +39,19 @@ glcr::RefPtr Process::CreateThread() { glcr::RefPtr Process::GetThread(uint64_t tid) { MutexHolder lock(mutex_); - auto iter = threads_.begin(); - while (iter != threads_.end()) { - if ((*iter)->tid() == tid) { - return *iter; - } - ++iter; + if (tid >= threads_.size()) { + panic("Bad thread access %u on process %u with %u threads.", tid, id_, + threads_.size()); } - panic("Bad thread access."); - return nullptr; + return threads_[tid]; } void Process::CheckState() { MutexHolder lock(mutex_); - auto iter = threads_.begin(); - while (iter != threads_.end()) { - if ((*iter)->GetState() != Thread::FINISHED) { + for (uint64_t i = 0; i < threads_.size(); i++) { + if (threads_[i]->GetState() != Thread::FINISHED) { return; } - ++iter; } state_ = FINISHED; } diff --git a/zion/object/process.h b/zion/object/process.h index b305511..06e3dc1 100644 --- a/zion/object/process.h +++ b/zion/object/process.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include @@ -64,8 +64,7 @@ class Process : public KernelObject { State state_; uint64_t next_thread_id_ = 0; - uint64_t next_cap_id_ = 0x100; - glcr::LinkedList> threads_; + glcr::Vector> threads_; CapabilityTable caps_; }; diff --git a/zion/scheduler/process_manager.cpp b/zion/scheduler/process_manager.cpp index 9c87324..dc92ba3 100644 --- a/zion/scheduler/process_manager.cpp +++ b/zion/scheduler/process_manager.cpp @@ -14,23 +14,15 @@ void ProcessManager::InsertProcess(const glcr::RefPtr& proc) { } Process& ProcessManager::FromId(uint64_t pid) { - auto iter = proc_list_.begin(); - while (iter != proc_list_.end()) { - if ((*iter)->id() == pid) { - return **iter; - } - ++iter; + if (pid >= proc_list_.size()) { + panic("Bad proc access %u, have %u processes", pid, proc_list_.size()); } - - panic("Searching for invalid process id"); - return *((Process*)0); + return *proc_list_[pid]; } void ProcessManager::DumpProcessStates() { dbgln("Process States: %u", proc_list_.size()); - auto iter = proc_list_.begin(); - while (iter != proc_list_.end()) { - dbgln("%u: %u", (*iter)->id(), (*iter)->GetState()); - ++iter; + for (uint64_t i = 0; i < proc_list_.size(); i++) { + dbgln("%u: %u", proc_list_[i]->id(), proc_list_[i]->GetState()); } } diff --git a/zion/scheduler/process_manager.h b/zion/scheduler/process_manager.h index c925919..509ecd3 100644 --- a/zion/scheduler/process_manager.h +++ b/zion/scheduler/process_manager.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include "object/process.h" @@ -18,7 +18,7 @@ class ProcessManager { private: // TODO: This should be a hashmap. - glcr::LinkedList> proc_list_; + glcr::Vector> proc_list_; }; extern ProcessManager* gProcMan;