Compare commits
8 Commits
172bf51db7
...
3ab9b4d818
Author | SHA1 | Date |
---|---|---|
|
3ab9b4d818 | |
|
a99096b0ff | |
|
25737d9377 | |
|
e1af79b975 | |
|
8bcb574677 | |
|
56eae3d4e5 | |
|
f3443cf4de | |
|
859fbf66da |
|
@ -1,3 +1,4 @@
|
||||||
|
add_subdirectory(glacier)
|
||||||
add_subdirectory(libc)
|
add_subdirectory(libc)
|
||||||
add_subdirectory(libcxx)
|
add_subdirectory(libcxx)
|
||||||
add_subdirectory(mammoth)
|
add_subdirectory(mammoth)
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
add_library(glacier STATIC
|
||||||
|
string/string.cpp)
|
||||||
|
|
||||||
|
target_include_directories(glacier
|
||||||
|
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
|
PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/..")
|
|
@ -0,0 +1,102 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <glacier/memory/ref_ptr.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
namespace glcr {
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class IntrusiveListNode {
|
||||||
|
public:
|
||||||
|
RefPtr<T> next_;
|
||||||
|
RefPtr<T> prev_;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class IntrusiveList {
|
||||||
|
public:
|
||||||
|
IntrusiveList() : front_(nullptr), back_(nullptr) {}
|
||||||
|
|
||||||
|
void PushFront(const RefPtr<T>& obj);
|
||||||
|
void PushBack(const RefPtr<T>& obj);
|
||||||
|
|
||||||
|
RefPtr<T> PopFront();
|
||||||
|
RefPtr<T> PopBack();
|
||||||
|
|
||||||
|
RefPtr<T> PeekFront() { return front_; }
|
||||||
|
RefPtr<T> PeekBack() { return back_; }
|
||||||
|
|
||||||
|
uint64_t size() { return size_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
RefPtr<T> front_;
|
||||||
|
RefPtr<T> back_;
|
||||||
|
|
||||||
|
uint64_t size_ = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void IntrusiveList<T>::PushFront(const RefPtr<T>& obj) {
|
||||||
|
// FIXME: Check to make sure obj next and prev aren't set.
|
||||||
|
size_++;
|
||||||
|
obj->next_ = front_;
|
||||||
|
obj->prev_ = nullptr;
|
||||||
|
if (front_ == nullptr) {
|
||||||
|
front_ = obj;
|
||||||
|
back_ = obj;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
front_->prev_ = obj;
|
||||||
|
front_ = obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void IntrusiveList<T>::PushBack(const RefPtr<T>& obj) {
|
||||||
|
if (front_ == nullptr) {
|
||||||
|
PushFront(obj);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
size_++;
|
||||||
|
back_->next_ = obj;
|
||||||
|
obj->prev_ = back_;
|
||||||
|
obj->next_ = nullptr;
|
||||||
|
back_ = obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
RefPtr<T> IntrusiveList<T>::PopFront() {
|
||||||
|
if (front_ == nullptr) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
size_--;
|
||||||
|
if (front_ == back_) {
|
||||||
|
RefPtr<T> ptr = front_;
|
||||||
|
front_ = nullptr;
|
||||||
|
back_ = nullptr;
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
RefPtr<T> ptr = front_;
|
||||||
|
front_ = front_->next_;
|
||||||
|
front_->prev_ = nullptr;
|
||||||
|
ptr->next_ = nullptr;
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
RefPtr<T> IntrusiveList<T>::PopBack() {
|
||||||
|
if (back_ == nullptr) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
if (front_ == back_) {
|
||||||
|
return PopFront();
|
||||||
|
}
|
||||||
|
size_--;
|
||||||
|
RefPtr<T> ptr = back_;
|
||||||
|
back_ = back_->prev_;
|
||||||
|
back_->next_ = nullptr;
|
||||||
|
ptr->prev_ = nullptr;
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace glcr
|
|
@ -0,0 +1,29 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
namespace glcr {
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class RefCounted {
|
||||||
|
public:
|
||||||
|
RefCounted() {}
|
||||||
|
virtual ~RefCounted() {}
|
||||||
|
// FIXME: Rethink error handling in these cases now that we can't panic the
|
||||||
|
// kernel.
|
||||||
|
void Adopt() { ref_count_ = 1; }
|
||||||
|
|
||||||
|
void Acquire() { ref_count_++; }
|
||||||
|
bool Release() { return (--ref_count_) == 0; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
// FIXME: This should be an atomic type.
|
||||||
|
uint64_t ref_count_ = -1;
|
||||||
|
// Disallow copy and move.
|
||||||
|
RefCounted(RefCounted&) = delete;
|
||||||
|
RefCounted(RefCounted&&) = delete;
|
||||||
|
RefCounted& operator=(RefCounted&) = delete;
|
||||||
|
RefCounted& operator=(RefCounted&&) = delete;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace glcr
|
|
@ -1,6 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "debug/debug.h"
|
namespace glcr {
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class RefPtr;
|
class RefPtr;
|
||||||
|
@ -28,7 +28,6 @@ class RefPtr {
|
||||||
ptr_->Acquire();
|
ptr_->Acquire();
|
||||||
}
|
}
|
||||||
if (old && old->Release()) {
|
if (old && old->Release()) {
|
||||||
dbgln("Deleting obj %m", old);
|
|
||||||
delete old;
|
delete old;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,3 +89,5 @@ template <typename T, typename U>
|
||||||
RefPtr<T> StaticCastRefPtr(const RefPtr<U>& ref) {
|
RefPtr<T> StaticCastRefPtr(const RefPtr<U>& ref) {
|
||||||
return RefPtr(static_cast<T*>(ref.get()), RefPtr<T>::DontAdopt);
|
return RefPtr(static_cast<T*>(ref.get()), RefPtr<T>::DontAdopt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace glcr
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "debug/debug.h"
|
namespace glcr {
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class SharedPtr {
|
class SharedPtr {
|
||||||
|
@ -30,33 +30,14 @@ class SharedPtr {
|
||||||
|
|
||||||
~SharedPtr() { Cleanup(); }
|
~SharedPtr() { Cleanup(); }
|
||||||
|
|
||||||
T& operator*() {
|
T& operator*() { return *ptr_; }
|
||||||
CheckValid();
|
const T& operator*() const { return *ptr_; }
|
||||||
return *ptr_;
|
T* operator->() { return ptr_; }
|
||||||
}
|
const T* operator->() const { return ptr_; }
|
||||||
const T& operator*() const {
|
|
||||||
CheckValid();
|
|
||||||
return *ptr_;
|
|
||||||
}
|
|
||||||
T* operator->() {
|
|
||||||
CheckValid();
|
|
||||||
return ptr_;
|
|
||||||
}
|
|
||||||
const T* operator->() const {
|
|
||||||
CheckValid();
|
|
||||||
return ptr_;
|
|
||||||
}
|
|
||||||
|
|
||||||
T* ptr() {
|
T* ptr() { return ptr_; }
|
||||||
CheckValid();
|
|
||||||
return ptr_;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator==(const SharedPtr<T>& other) {
|
bool operator==(const SharedPtr<T>& other) { return ptr_ == other.ptr_; }
|
||||||
CheckValid();
|
|
||||||
other.CheckValid();
|
|
||||||
return ptr_ == other.ptr_;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool empty() { return !init_; }
|
bool empty() { return !init_; }
|
||||||
|
|
||||||
|
@ -74,15 +55,11 @@ class SharedPtr {
|
||||||
delete ref_cnt_;
|
delete ref_cnt_;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheckValid() const {
|
|
||||||
if (!init_) {
|
|
||||||
panic("Accessing invalid shared ptr");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, class... A>
|
template <typename T, class... A>
|
||||||
SharedPtr<T> MakeShared(A... args) {
|
SharedPtr<T> MakeShared(A... args) {
|
||||||
return {new T(args...)};
|
return {new T(args...)};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace glcr
|
|
@ -0,0 +1,37 @@
|
||||||
|
#include "string/string.h"
|
||||||
|
|
||||||
|
namespace glcr {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
uint64_t cstrlen(const char* cstr) {
|
||||||
|
uint64_t len = 0;
|
||||||
|
while (*cstr != '\0') {
|
||||||
|
cstr++;
|
||||||
|
len++;
|
||||||
|
}
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
String::String(const char* str) {
|
||||||
|
length_ = cstrlen(str);
|
||||||
|
cstr_ = new char[length_ + 1];
|
||||||
|
for (uint64_t i = 0; i <= length_; i++) {
|
||||||
|
cstr_[i] = str[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool String::operator==(const String& other) {
|
||||||
|
if (other.length_ != length_) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (uint64_t i = 0; i < length_; i++) {
|
||||||
|
if (cstr_[i] != other.cstr_[i]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace glcr
|
|
@ -0,0 +1,18 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
namespace glcr {
|
||||||
|
|
||||||
|
class String {
|
||||||
|
public:
|
||||||
|
String(const char* cstr);
|
||||||
|
|
||||||
|
bool operator==(const String& str);
|
||||||
|
|
||||||
|
private:
|
||||||
|
char* cstr_;
|
||||||
|
uint64_t length_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace glcr
|
|
@ -45,6 +45,9 @@ target_include_directories(zion
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}
|
${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
target_link_libraries(zion
|
||||||
|
glacier)
|
||||||
|
|
||||||
# -c -- Don't run the linker (only necessary for the assembler)
|
# -c -- Don't run the linker (only necessary for the assembler)
|
||||||
# -ffreestanding
|
# -ffreestanding
|
||||||
# -fno-rtti -- No runtime type information (might mess with polymorphism?)
|
# -fno-rtti -- No runtime type information (might mess with polymorphism?)
|
||||||
|
|
|
@ -1,26 +1,28 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <glacier/memory/ref_counted.h>
|
||||||
|
#include <glacier/memory/ref_ptr.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "lib/ref_ptr.h"
|
#include "include/ztypes.h"
|
||||||
#include "object/kernel_object.h"
|
#include "object/kernel_object.h"
|
||||||
|
|
||||||
class Process;
|
class Process;
|
||||||
class Thread;
|
class Thread;
|
||||||
|
|
||||||
class Capability : public RefCounted<Capability> {
|
class Capability : public glcr::RefCounted<Capability> {
|
||||||
public:
|
public:
|
||||||
Capability(const RefPtr<KernelObject>& obj, uint64_t permissions)
|
Capability(const glcr::RefPtr<KernelObject>& obj, uint64_t permissions)
|
||||||
: obj_(obj), permissions_(permissions) {}
|
: obj_(obj), permissions_(permissions) {}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
Capability(const RefPtr<T>& obj, uint64_t permissions)
|
Capability(const glcr::RefPtr<T>& obj, uint64_t permissions)
|
||||||
: Capability(StaticCastRefPtr<KernelObject>(obj), permissions) {}
|
: Capability(StaticCastRefPtr<KernelObject>(obj), permissions) {}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
RefPtr<T> obj();
|
glcr::RefPtr<T> obj();
|
||||||
|
|
||||||
RefPtr<KernelObject> raw_obj() { return obj_; }
|
glcr::RefPtr<KernelObject> raw_obj() { return obj_; }
|
||||||
|
|
||||||
uint64_t permissions() { return permissions_; }
|
uint64_t permissions() { return permissions_; }
|
||||||
bool HasPermissions(uint64_t requested) {
|
bool HasPermissions(uint64_t requested) {
|
||||||
|
@ -28,12 +30,12 @@ class Capability : public RefCounted<Capability> {
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RefPtr<KernelObject> obj_;
|
glcr::RefPtr<KernelObject> obj_;
|
||||||
uint64_t permissions_;
|
uint64_t permissions_;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
RefPtr<T> Capability::obj() {
|
glcr::RefPtr<T> Capability::obj() {
|
||||||
if (obj_->TypeTag() != KernelObjectTag<T>::type) {
|
if (obj_->TypeTag() != KernelObjectTag<T>::type) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -41,7 +43,7 @@ RefPtr<T> Capability::obj() {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
z_err_t ValidateCapability(const RefPtr<Capability>& cap,
|
z_err_t ValidateCapability(const glcr::RefPtr<Capability>& cap,
|
||||||
uint64_t permissions) {
|
uint64_t permissions) {
|
||||||
if (!cap) {
|
if (!cap) {
|
||||||
return Z_ERR_CAP_NOT_FOUND;
|
return Z_ERR_CAP_NOT_FOUND;
|
||||||
|
|
|
@ -2,14 +2,15 @@
|
||||||
|
|
||||||
CapabilityTable::CapabilityTable() {}
|
CapabilityTable::CapabilityTable() {}
|
||||||
|
|
||||||
uint64_t CapabilityTable::AddExistingCapability(const RefPtr<Capability>& cap) {
|
uint64_t CapabilityTable::AddExistingCapability(
|
||||||
|
const glcr::RefPtr<Capability>& cap) {
|
||||||
MutexHolder h(lock_);
|
MutexHolder h(lock_);
|
||||||
uint64_t id = next_cap_id_++;
|
uint64_t id = next_cap_id_++;
|
||||||
capabilities_.PushBack({.id = id, .cap = cap});
|
capabilities_.PushBack({.id = id, .cap = cap});
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<Capability> CapabilityTable::GetCapability(uint64_t id) {
|
glcr::RefPtr<Capability> CapabilityTable::GetCapability(uint64_t id) {
|
||||||
MutexHolder h(lock_);
|
MutexHolder h(lock_);
|
||||||
auto iter = capabilities_.begin();
|
auto iter = capabilities_.begin();
|
||||||
while (iter != capabilities_.end()) {
|
while (iter != capabilities_.end()) {
|
||||||
|
@ -23,7 +24,7 @@ RefPtr<Capability> CapabilityTable::GetCapability(uint64_t id) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<Capability> CapabilityTable::ReleaseCapability(uint64_t id) {
|
glcr::RefPtr<Capability> CapabilityTable::ReleaseCapability(uint64_t id) {
|
||||||
MutexHolder h(lock_);
|
MutexHolder h(lock_);
|
||||||
auto iter = capabilities_.begin();
|
auto iter = capabilities_.begin();
|
||||||
while (iter != capabilities_.end()) {
|
while (iter != capabilities_.end()) {
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <glacier/memory/ref_ptr.h>
|
||||||
|
|
||||||
#include "capability/capability.h"
|
#include "capability/capability.h"
|
||||||
#include "lib/linked_list.h"
|
#include "lib/linked_list.h"
|
||||||
#include "lib/mutex.h"
|
#include "lib/mutex.h"
|
||||||
#include "lib/ref_ptr.h"
|
|
||||||
|
|
||||||
class CapabilityTable {
|
class CapabilityTable {
|
||||||
public:
|
public:
|
||||||
|
@ -13,11 +14,12 @@ class CapabilityTable {
|
||||||
CapabilityTable& operator=(CapabilityTable&) = delete;
|
CapabilityTable& operator=(CapabilityTable&) = delete;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
uint64_t AddNewCapability(const RefPtr<T>& object, uint64_t permissions);
|
uint64_t AddNewCapability(const glcr::RefPtr<T>& object,
|
||||||
uint64_t AddExistingCapability(const RefPtr<Capability>& cap);
|
uint64_t permissions);
|
||||||
|
uint64_t AddExistingCapability(const glcr::RefPtr<Capability>& cap);
|
||||||
|
|
||||||
RefPtr<Capability> GetCapability(uint64_t id);
|
glcr::RefPtr<Capability> GetCapability(uint64_t id);
|
||||||
RefPtr<Capability> ReleaseCapability(uint64_t id);
|
glcr::RefPtr<Capability> ReleaseCapability(uint64_t id);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Mutex lock_{"cap table"};
|
Mutex lock_{"cap table"};
|
||||||
|
@ -26,13 +28,13 @@ class CapabilityTable {
|
||||||
// FIXME: use a map data structure.
|
// FIXME: use a map data structure.
|
||||||
struct CapEntry {
|
struct CapEntry {
|
||||||
uint64_t id;
|
uint64_t id;
|
||||||
RefPtr<Capability> cap;
|
glcr::RefPtr<Capability> cap;
|
||||||
};
|
};
|
||||||
LinkedList<CapEntry> capabilities_;
|
LinkedList<CapEntry> capabilities_;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
uint64_t CapabilityTable::AddNewCapability(const RefPtr<T>& object,
|
uint64_t CapabilityTable::AddNewCapability(const glcr::RefPtr<T>& object,
|
||||||
uint64_t permissions) {
|
uint64_t permissions) {
|
||||||
MutexHolder h(lock_);
|
MutexHolder h(lock_);
|
||||||
uint64_t id = next_cap_id_++;
|
uint64_t id = next_cap_id_++;
|
||||||
|
|
|
@ -138,7 +138,7 @@ extern "C" void interrupt_timer(InterruptFrame*) {
|
||||||
gScheduler->Preempt();
|
gScheduler->Preempt();
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<Port> pci1_port;
|
glcr::RefPtr<Port> pci1_port;
|
||||||
extern "C" void isr_pci1();
|
extern "C" void isr_pci1();
|
||||||
extern "C" void interrupt_pci1(InterruptFrame*) {
|
extern "C" void interrupt_pci1(InterruptFrame*) {
|
||||||
dbgln("Interrupt PCI line 1");
|
dbgln("Interrupt PCI line 1");
|
||||||
|
@ -185,4 +185,4 @@ void InitIdt() {
|
||||||
EnableApic();
|
EnableApic();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RegisterPciPort(const RefPtr<Port>& port) { pci1_port = port; }
|
void RegisterPciPort(const glcr::RefPtr<Port>& port) { pci1_port = port; }
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "lib/ref_ptr.h"
|
#include <glacier/memory/ref_ptr.h>
|
||||||
|
|
||||||
#include "object/port.h"
|
#include "object/port.h"
|
||||||
|
|
||||||
void InitIdt();
|
void InitIdt();
|
||||||
|
|
||||||
void RegisterPciPort(const RefPtr<Port>& port);
|
void RegisterPciPort(const glcr::RefPtr<Port>& port);
|
||||||
|
|
|
@ -10,7 +10,7 @@ z_err_t UnboundedMessageQueue::PushBack(uint64_t num_bytes, const void* bytes,
|
||||||
return Z_ERR_UNIMPLEMENTED;
|
return Z_ERR_UNIMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto message = MakeShared<Message>();
|
auto message = glcr::MakeShared<Message>();
|
||||||
message->num_bytes = num_bytes;
|
message->num_bytes = num_bytes;
|
||||||
message->bytes = new uint8_t[num_bytes];
|
message->bytes = new uint8_t[num_bytes];
|
||||||
for (uint64_t i = 0; i < num_bytes; i++) {
|
for (uint64_t i = 0; i < num_bytes; i++) {
|
||||||
|
@ -56,8 +56,9 @@ z_err_t UnboundedMessageQueue::PopFront(uint64_t* num_bytes, void* bytes,
|
||||||
return Z_OK;
|
return Z_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UnboundedMessageQueue::WriteKernel(uint64_t init, RefPtr<Capability> cap) {
|
void UnboundedMessageQueue::WriteKernel(uint64_t init,
|
||||||
auto msg = MakeShared<Message>();
|
glcr::RefPtr<Capability> cap) {
|
||||||
|
auto msg = glcr::MakeShared<Message>();
|
||||||
msg->bytes = new uint8_t[8];
|
msg->bytes = new uint8_t[8];
|
||||||
msg->num_bytes = sizeof(init);
|
msg->num_bytes = sizeof(init);
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <glacier/memory/ref_ptr.h>
|
||||||
|
#include <glacier/memory/shared_ptr.h>
|
||||||
|
|
||||||
#include "capability/capability.h"
|
#include "capability/capability.h"
|
||||||
#include "include/ztypes.h"
|
#include "include/ztypes.h"
|
||||||
#include "lib/linked_list.h"
|
#include "lib/linked_list.h"
|
||||||
#include "lib/shared_ptr.h"
|
|
||||||
|
|
||||||
class MessageQueue {
|
class MessageQueue {
|
||||||
public:
|
public:
|
||||||
|
@ -27,7 +29,7 @@ class UnboundedMessageQueue : public MessageQueue {
|
||||||
z_err_t PopFront(uint64_t* num_bytes, void* bytes, uint64_t* num_caps,
|
z_err_t PopFront(uint64_t* num_bytes, void* bytes, uint64_t* num_caps,
|
||||||
z_cap_t* caps) override;
|
z_cap_t* caps) override;
|
||||||
|
|
||||||
void WriteKernel(uint64_t init, RefPtr<Capability> cap);
|
void WriteKernel(uint64_t init, glcr::RefPtr<Capability> cap);
|
||||||
|
|
||||||
uint64_t size() { return pending_messages_.size(); }
|
uint64_t size() { return pending_messages_.size(); }
|
||||||
bool empty() { return size() == 0; }
|
bool empty() { return size() == 0; }
|
||||||
|
@ -37,8 +39,8 @@ class UnboundedMessageQueue : public MessageQueue {
|
||||||
uint64_t num_bytes;
|
uint64_t num_bytes;
|
||||||
uint8_t* bytes;
|
uint8_t* bytes;
|
||||||
|
|
||||||
LinkedList<RefPtr<Capability>> caps;
|
LinkedList<glcr::RefPtr<Capability>> caps;
|
||||||
};
|
};
|
||||||
|
|
||||||
LinkedList<SharedPtr<Message>> pending_messages_;
|
LinkedList<glcr::SharedPtr<Message>> pending_messages_;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,41 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include "debug/debug.h"
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
class RefCounted {
|
|
||||||
public:
|
|
||||||
RefCounted() {}
|
|
||||||
~RefCounted() { dbgln("RefCounted object destroyed"); }
|
|
||||||
void Adopt() {
|
|
||||||
if (ref_count_ != -1) {
|
|
||||||
panic("Adopting owned ptr");
|
|
||||||
} else {
|
|
||||||
ref_count_ = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Acquire() {
|
|
||||||
if (ref_count_ == -1) {
|
|
||||||
panic("Acquiring unowned ptr");
|
|
||||||
}
|
|
||||||
ref_count_++;
|
|
||||||
}
|
|
||||||
bool Release() {
|
|
||||||
if (ref_count_ == -1 || ref_count_ == 0) {
|
|
||||||
panic("Releasing unowned ptr");
|
|
||||||
}
|
|
||||||
return (--ref_count_) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
// FIXME: This should be an atomic type.
|
|
||||||
uint64_t ref_count_ = -1;
|
|
||||||
// Disallow copy and move.
|
|
||||||
RefCounted(RefCounted&) = delete;
|
|
||||||
RefCounted(RefCounted&&) = delete;
|
|
||||||
RefCounted& operator=(RefCounted&) = delete;
|
|
||||||
RefCounted& operator=(RefCounted&&) = delete;
|
|
||||||
};
|
|
|
@ -1,9 +1,11 @@
|
||||||
#include "loader/init_loader.h"
|
#include "loader/init_loader.h"
|
||||||
|
|
||||||
|
#include <glacier/memory/ref_ptr.h>
|
||||||
|
#include <glacier/string/string.h>
|
||||||
|
|
||||||
#include "boot/boot_info.h"
|
#include "boot/boot_info.h"
|
||||||
#include "debug/debug.h"
|
#include "debug/debug.h"
|
||||||
#include "include/zcall.h"
|
#include "include/zcall.h"
|
||||||
#include "lib/ref_ptr.h"
|
|
||||||
#include "memory/paging_util.h"
|
#include "memory/paging_util.h"
|
||||||
#include "object/process.h"
|
#include "object/process.h"
|
||||||
#include "object/thread.h"
|
#include "object/thread.h"
|
||||||
|
@ -71,7 +73,7 @@ uint64_t LoadElfProgram(Process& dest_proc, uint64_t base, uint64_t offset) {
|
||||||
program.type, program.flags, program.offset, program.vaddr,
|
program.type, program.flags, program.offset, program.vaddr,
|
||||||
program.paddr, program.filesz, program.memsz, program.align);
|
program.paddr, program.filesz, program.memsz, program.align);
|
||||||
#endif
|
#endif
|
||||||
auto mem_obj = MakeRefCounted<MemoryObject>(program.memsz);
|
auto mem_obj = glcr::MakeRefCounted<MemoryObject>(program.memsz);
|
||||||
mem_obj->CopyBytesToObject(base + program.offset, program.filesz);
|
mem_obj->CopyBytesToObject(base + program.offset, program.filesz);
|
||||||
dest_proc.vmas()->MapInMemoryObject(program.vaddr, mem_obj);
|
dest_proc.vmas()->MapInMemoryObject(program.vaddr, mem_obj);
|
||||||
}
|
}
|
||||||
|
@ -103,11 +105,13 @@ void DumpModules() {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
const limine_file& GetInitProgram(const char* path) {
|
const limine_file& GetInitProgram(glcr::String path) {
|
||||||
const limine_module_response& resp = boot::GetModules();
|
const limine_module_response& resp = boot::GetModules();
|
||||||
for (uint64_t i = 0; i < resp.module_count; i++) {
|
for (uint64_t i = 0; i < resp.module_count; i++) {
|
||||||
const limine_file& file = *resp.modules[i];
|
const limine_file& file = *resp.modules[i];
|
||||||
if (streq(file.path, path)) return file;
|
if (path == file.path) {
|
||||||
|
return file;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
panic("Program not found: %s", path);
|
panic("Program not found: %s", path);
|
||||||
}
|
}
|
||||||
|
@ -118,18 +122,19 @@ void LoadInitProgram() {
|
||||||
DumpModules();
|
DumpModules();
|
||||||
const limine_file& init_prog = GetInitProgram("/sys/yellowstone");
|
const limine_file& init_prog = GetInitProgram("/sys/yellowstone");
|
||||||
|
|
||||||
RefPtr<Process> proc = Process::Create();
|
glcr::RefPtr<Process> proc = Process::Create();
|
||||||
gProcMan->InsertProcess(proc);
|
gProcMan->InsertProcess(proc);
|
||||||
|
|
||||||
uint64_t entry = LoadElfProgram(
|
uint64_t entry = LoadElfProgram(
|
||||||
*proc, reinterpret_cast<uint64_t>(init_prog.address), init_prog.size);
|
*proc, reinterpret_cast<uint64_t>(init_prog.address), init_prog.size);
|
||||||
|
|
||||||
const limine_file& prog2 = GetInitProgram("/sys/denali");
|
const limine_file& prog2 = GetInitProgram("/sys/denali");
|
||||||
RefPtr<MemoryObject> prog2_vmmo = MakeRefCounted<MemoryObject>(prog2.size);
|
glcr::RefPtr<MemoryObject> prog2_vmmo =
|
||||||
|
glcr::MakeRefCounted<MemoryObject>(prog2.size);
|
||||||
prog2_vmmo->CopyBytesToObject(reinterpret_cast<uint64_t>(prog2.address),
|
prog2_vmmo->CopyBytesToObject(reinterpret_cast<uint64_t>(prog2.address),
|
||||||
prog2.size);
|
prog2.size);
|
||||||
|
|
||||||
auto port = MakeRefCounted<Port>();
|
auto port = glcr::MakeRefCounted<Port>();
|
||||||
uint64_t port_cap = proc->AddNewCapability(port, ZC_READ | ZC_WRITE);
|
uint64_t port_cap = proc->AddNewCapability(port, ZC_READ | ZC_WRITE);
|
||||||
|
|
||||||
port->WriteKernel(Z_INIT_SELF_PROC,
|
port->WriteKernel(Z_INIT_SELF_PROC,
|
||||||
|
|
|
@ -8,10 +8,10 @@
|
||||||
|
|
||||||
extern KernelStackManager* gKernelStackManager;
|
extern KernelStackManager* gKernelStackManager;
|
||||||
|
|
||||||
RefPtr<AddressSpace> AddressSpace::ForRoot() {
|
glcr::RefPtr<AddressSpace> AddressSpace::ForRoot() {
|
||||||
uint64_t cr3 = 0;
|
uint64_t cr3 = 0;
|
||||||
asm volatile("mov %%cr3, %0;" : "=r"(cr3));
|
asm volatile("mov %%cr3, %0;" : "=r"(cr3));
|
||||||
return MakeRefCounted<AddressSpace>(cr3);
|
return glcr::MakeRefCounted<AddressSpace>(cr3);
|
||||||
}
|
}
|
||||||
|
|
||||||
AddressSpace::AddressSpace() {
|
AddressSpace::AddressSpace() {
|
||||||
|
@ -36,12 +36,13 @@ uint64_t AddressSpace::GetNextMemMapAddr(uint64_t size) {
|
||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddressSpace::MapInMemoryObject(uint64_t vaddr,
|
void AddressSpace::MapInMemoryObject(
|
||||||
const RefPtr<MemoryObject>& mem_obj) {
|
uint64_t vaddr, const glcr::RefPtr<MemoryObject>& mem_obj) {
|
||||||
memory_mappings_.PushBack({.vaddr = vaddr, .mem_obj = mem_obj});
|
memory_mappings_.PushBack({.vaddr = vaddr, .mem_obj = mem_obj});
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t AddressSpace::MapInMemoryObject(const RefPtr<MemoryObject>& mem_obj) {
|
uint64_t AddressSpace::MapInMemoryObject(
|
||||||
|
const glcr::RefPtr<MemoryObject>& mem_obj) {
|
||||||
uint64_t vaddr = GetNextMemMapAddr(mem_obj->size());
|
uint64_t vaddr = GetNextMemMapAddr(mem_obj->size());
|
||||||
memory_mappings_.PushBack({.vaddr = vaddr, .mem_obj = mem_obj});
|
memory_mappings_.PushBack({.vaddr = vaddr, .mem_obj = mem_obj});
|
||||||
return vaddr;
|
return vaddr;
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <glacier/memory/ref_ptr.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "lib/ref_ptr.h"
|
|
||||||
#include "memory/user_stack_manager.h"
|
#include "memory/user_stack_manager.h"
|
||||||
#include "object/memory_object.h"
|
#include "object/memory_object.h"
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ class AddressSpace : public KernelObject {
|
||||||
KERNEL_STACK,
|
KERNEL_STACK,
|
||||||
};
|
};
|
||||||
|
|
||||||
static RefPtr<AddressSpace> ForRoot();
|
static glcr::RefPtr<AddressSpace> ForRoot();
|
||||||
|
|
||||||
AddressSpace();
|
AddressSpace();
|
||||||
AddressSpace(const AddressSpace&) = delete;
|
AddressSpace(const AddressSpace&) = delete;
|
||||||
|
@ -63,9 +63,10 @@ class AddressSpace : public KernelObject {
|
||||||
|
|
||||||
// Maps in a memory object at a specific address.
|
// Maps in a memory object at a specific address.
|
||||||
// Note this is unsafe for now as it may clobber other mappings.
|
// Note this is unsafe for now as it may clobber other mappings.
|
||||||
void MapInMemoryObject(uint64_t vaddr, const RefPtr<MemoryObject>& mem_obj);
|
void MapInMemoryObject(uint64_t vaddr,
|
||||||
|
const glcr::RefPtr<MemoryObject>& mem_obj);
|
||||||
|
|
||||||
uint64_t MapInMemoryObject(const RefPtr<MemoryObject>& mem_obj);
|
uint64_t MapInMemoryObject(const glcr::RefPtr<MemoryObject>& mem_obj);
|
||||||
|
|
||||||
// Kernel Mappings.
|
// Kernel Mappings.
|
||||||
uint64_t* AllocateKernelStack();
|
uint64_t* AllocateKernelStack();
|
||||||
|
@ -74,7 +75,7 @@ class AddressSpace : public KernelObject {
|
||||||
bool HandlePageFault(uint64_t vaddr);
|
bool HandlePageFault(uint64_t vaddr);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class MakeRefCountedFriend<AddressSpace>;
|
friend class glcr::MakeRefCountedFriend<AddressSpace>;
|
||||||
AddressSpace(uint64_t cr3) : cr3_(cr3) {}
|
AddressSpace(uint64_t cr3) : cr3_(cr3) {}
|
||||||
uint64_t cr3_ = 0;
|
uint64_t cr3_ = 0;
|
||||||
|
|
||||||
|
@ -83,7 +84,7 @@ class AddressSpace : public KernelObject {
|
||||||
|
|
||||||
struct MemoryMapping {
|
struct MemoryMapping {
|
||||||
uint64_t vaddr;
|
uint64_t vaddr;
|
||||||
RefPtr<MemoryObject> mem_obj;
|
glcr::RefPtr<MemoryObject> mem_obj;
|
||||||
};
|
};
|
||||||
LinkedList<MemoryMapping> memory_mappings_;
|
LinkedList<MemoryMapping> memory_mappings_;
|
||||||
|
|
||||||
|
|
|
@ -3,9 +3,10 @@
|
||||||
#include "include/ztypes.h"
|
#include "include/ztypes.h"
|
||||||
#include "scheduler/scheduler.h"
|
#include "scheduler/scheduler.h"
|
||||||
|
|
||||||
Pair<RefPtr<Channel>, RefPtr<Channel>> Channel::CreateChannelPair() {
|
Pair<glcr::RefPtr<Channel>, glcr::RefPtr<Channel>>
|
||||||
auto c1 = MakeRefCounted<Channel>();
|
Channel::CreateChannelPair() {
|
||||||
auto c2 = MakeRefCounted<Channel>();
|
auto c1 = glcr::MakeRefCounted<Channel>();
|
||||||
|
auto c2 = glcr::MakeRefCounted<Channel>();
|
||||||
c1->SetPeer(c2);
|
c1->SetPeer(c2);
|
||||||
c2->SetPeer(c1);
|
c2->SetPeer(c1);
|
||||||
return {c1, c2};
|
return {c1, c2};
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <glacier/container/intrusive_list.h>
|
||||||
|
#include <glacier/memory/ref_ptr.h>
|
||||||
|
|
||||||
#include "capability/capability.h"
|
#include "capability/capability.h"
|
||||||
#include "include/ztypes.h"
|
#include "include/ztypes.h"
|
||||||
#include "lib/linked_list.h"
|
|
||||||
#include "lib/message_queue.h"
|
#include "lib/message_queue.h"
|
||||||
#include "lib/mutex.h"
|
#include "lib/mutex.h"
|
||||||
#include "lib/pair.h"
|
#include "lib/pair.h"
|
||||||
#include "lib/ref_ptr.h"
|
|
||||||
#include "lib/shared_ptr.h"
|
|
||||||
#include "object/kernel_object.h"
|
#include "object/kernel_object.h"
|
||||||
#include "usr/zcall_internal.h"
|
#include "usr/zcall_internal.h"
|
||||||
|
|
||||||
|
@ -21,9 +21,9 @@ struct KernelObjectTag<Channel> {
|
||||||
class Channel : public KernelObject {
|
class Channel : public KernelObject {
|
||||||
public:
|
public:
|
||||||
uint64_t TypeTag() override { return KernelObject::CHANNEL; }
|
uint64_t TypeTag() override { return KernelObject::CHANNEL; }
|
||||||
static Pair<RefPtr<Channel>, RefPtr<Channel>> CreateChannelPair();
|
static Pair<glcr::RefPtr<Channel>, glcr::RefPtr<Channel>> CreateChannelPair();
|
||||||
|
|
||||||
RefPtr<Channel> peer() { return peer_; }
|
glcr::RefPtr<Channel> peer() { return peer_; }
|
||||||
|
|
||||||
z_err_t Write(uint64_t num_bytes, const void* bytes, uint64_t num_caps,
|
z_err_t Write(uint64_t num_bytes, const void* bytes, uint64_t num_caps,
|
||||||
const z_cap_t* caps);
|
const z_cap_t* caps);
|
||||||
|
@ -33,16 +33,16 @@ class Channel : public KernelObject {
|
||||||
private:
|
private:
|
||||||
// FIXME: We will likely never close the channel based on this
|
// FIXME: We will likely never close the channel based on this
|
||||||
// circular dependency.
|
// circular dependency.
|
||||||
RefPtr<Channel> peer_{nullptr};
|
glcr::RefPtr<Channel> peer_{nullptr};
|
||||||
|
|
||||||
Mutex mutex_{"channel"};
|
Mutex mutex_{"channel"};
|
||||||
UnboundedMessageQueue message_queue_;
|
UnboundedMessageQueue message_queue_;
|
||||||
|
|
||||||
LinkedList<RefPtr<Thread>> blocked_threads_;
|
glcr::IntrusiveList<Thread> blocked_threads_;
|
||||||
|
|
||||||
friend class MakeRefCountedFriend<Channel>;
|
friend class glcr::MakeRefCountedFriend<Channel>;
|
||||||
Channel() {}
|
Channel() {}
|
||||||
void SetPeer(const RefPtr<Channel>& peer) { peer_ = peer; }
|
void SetPeer(const glcr::RefPtr<Channel>& peer) { peer_ = peer; }
|
||||||
|
|
||||||
z_err_t WriteInternal(uint64_t num_bytes, const void* bytes,
|
z_err_t WriteInternal(uint64_t num_bytes, const void* bytes,
|
||||||
uint64_t num_caps, const z_cap_t* caps);
|
uint64_t num_caps, const z_cap_t* caps);
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "lib/ref_counted.h"
|
#include <glacier/memory/ref_counted.h>
|
||||||
|
|
||||||
class KernelObject : public RefCounted<KernelObject> {
|
class KernelObject : public glcr::RefCounted<KernelObject> {
|
||||||
public:
|
public:
|
||||||
enum ObjectType {
|
enum ObjectType {
|
||||||
INVALID = 0x0,
|
INVALID = 0x0,
|
||||||
|
|
|
@ -33,7 +33,7 @@ z_err_t Port::Read(uint64_t* num_bytes, void* bytes, uint64_t* num_caps,
|
||||||
return message_queue_.PopFront(num_bytes, bytes, num_caps, caps);
|
return message_queue_.PopFront(num_bytes, bytes, num_caps, caps);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Port::WriteKernel(uint64_t init, RefPtr<Capability> cap) {
|
void Port::WriteKernel(uint64_t init, glcr::RefPtr<Capability> cap) {
|
||||||
MutexHolder h(mutex_);
|
MutexHolder h(mutex_);
|
||||||
message_queue_.WriteKernel(init, cap);
|
message_queue_.WriteKernel(init, cap);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <glacier/container/intrusive_list.h>
|
||||||
|
#include <glacier/memory/ref_ptr.h>
|
||||||
|
|
||||||
#include "capability/capability.h"
|
#include "capability/capability.h"
|
||||||
#include "lib/linked_list.h"
|
|
||||||
#include "lib/message_queue.h"
|
#include "lib/message_queue.h"
|
||||||
#include "lib/mutex.h"
|
#include "lib/mutex.h"
|
||||||
#include "lib/shared_ptr.h"
|
|
||||||
#include "object/kernel_object.h"
|
#include "object/kernel_object.h"
|
||||||
#include "object/thread.h"
|
#include "object/thread.h"
|
||||||
#include "usr/zcall_internal.h"
|
#include "usr/zcall_internal.h"
|
||||||
|
@ -27,13 +28,13 @@ class Port : public KernelObject {
|
||||||
z_err_t Read(uint64_t* num_bytes, void* bytes, uint64_t* num_caps,
|
z_err_t Read(uint64_t* num_bytes, void* bytes, uint64_t* num_caps,
|
||||||
z_cap_t* caps);
|
z_cap_t* caps);
|
||||||
|
|
||||||
void WriteKernel(uint64_t init, RefPtr<Capability> cap);
|
void WriteKernel(uint64_t init, glcr::RefPtr<Capability> cap);
|
||||||
|
|
||||||
bool HasMessages();
|
bool HasMessages();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
UnboundedMessageQueue message_queue_;
|
UnboundedMessageQueue message_queue_;
|
||||||
LinkedList<RefPtr<Thread>> blocked_threads_;
|
glcr::IntrusiveList<Thread> blocked_threads_;
|
||||||
|
|
||||||
Mutex mutex_{"Port"};
|
Mutex mutex_{"Port"};
|
||||||
};
|
};
|
||||||
|
|
|
@ -13,26 +13,31 @@ static uint64_t gNextId = 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<Process> Process::RootProcess() {
|
glcr::RefPtr<Process> Process::RootProcess() {
|
||||||
RefPtr<Process> proc = MakeRefCounted<Process>(0);
|
glcr::RefPtr<Process> proc = glcr::MakeRefCounted<Process>(0);
|
||||||
proc->threads_.PushBack(Thread::RootThread(*proc));
|
proc->threads_.PushBack(Thread::RootThread(*proc));
|
||||||
proc->next_thread_id_ = 1;
|
proc->next_thread_id_ = 1;
|
||||||
|
|
||||||
return proc;
|
return proc;
|
||||||
}
|
}
|
||||||
RefPtr<Process> Process::Create() { return MakeRefCounted<Process>(); }
|
glcr::RefPtr<Process> Process::Create() {
|
||||||
|
return glcr::MakeRefCounted<Process>();
|
||||||
|
}
|
||||||
|
|
||||||
Process::Process()
|
Process::Process()
|
||||||
: id_(gNextId++), vmas_(MakeRefCounted<AddressSpace>()), state_(RUNNING) {}
|
: id_(gNextId++),
|
||||||
|
vmas_(glcr::MakeRefCounted<AddressSpace>()),
|
||||||
|
state_(RUNNING) {}
|
||||||
|
|
||||||
RefPtr<Thread> Process::CreateThread() {
|
glcr::RefPtr<Thread> Process::CreateThread() {
|
||||||
MutexHolder lock(mutex_);
|
MutexHolder lock(mutex_);
|
||||||
RefPtr<Thread> thread = MakeRefCounted<Thread>(*this, next_thread_id_++);
|
glcr::RefPtr<Thread> thread =
|
||||||
|
glcr::MakeRefCounted<Thread>(*this, next_thread_id_++);
|
||||||
threads_.PushBack(thread);
|
threads_.PushBack(thread);
|
||||||
return thread;
|
return thread;
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<Thread> Process::GetThread(uint64_t tid) {
|
glcr::RefPtr<Thread> Process::GetThread(uint64_t tid) {
|
||||||
MutexHolder lock(mutex_);
|
MutexHolder lock(mutex_);
|
||||||
auto iter = threads_.begin();
|
auto iter = threads_.begin();
|
||||||
while (iter != threads_.end()) {
|
while (iter != threads_.end()) {
|
||||||
|
@ -57,14 +62,14 @@ void Process::CheckState() {
|
||||||
state_ = FINISHED;
|
state_ = FINISHED;
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<Capability> Process::ReleaseCapability(uint64_t cid) {
|
glcr::RefPtr<Capability> Process::ReleaseCapability(uint64_t cid) {
|
||||||
return caps_.ReleaseCapability(cid);
|
return caps_.ReleaseCapability(cid);
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<Capability> Process::GetCapability(uint64_t cid) {
|
glcr::RefPtr<Capability> Process::GetCapability(uint64_t cid) {
|
||||||
return caps_.GetCapability(cid);
|
return caps_.GetCapability(cid);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t Process::AddExistingCapability(const RefPtr<Capability>& cap) {
|
uint64_t Process::AddExistingCapability(const glcr::RefPtr<Capability>& cap) {
|
||||||
return caps_.AddExistingCapability(cap);
|
return caps_.AddExistingCapability(cap);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <glacier/memory/ref_ptr.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "capability/capability.h"
|
#include "capability/capability.h"
|
||||||
#include "capability/capability_table.h"
|
#include "capability/capability_table.h"
|
||||||
#include "lib/linked_list.h"
|
#include "lib/linked_list.h"
|
||||||
#include "lib/mutex.h"
|
#include "lib/mutex.h"
|
||||||
#include "lib/ref_ptr.h"
|
|
||||||
#include "object/address_space.h"
|
#include "object/address_space.h"
|
||||||
#include "object/channel.h"
|
#include "object/channel.h"
|
||||||
#include "object/port.h"
|
#include "object/port.h"
|
||||||
|
@ -28,23 +28,23 @@ class Process : public KernelObject {
|
||||||
RUNNING,
|
RUNNING,
|
||||||
FINISHED,
|
FINISHED,
|
||||||
};
|
};
|
||||||
static RefPtr<Process> RootProcess();
|
static glcr::RefPtr<Process> RootProcess();
|
||||||
static RefPtr<Process> Create();
|
static glcr::RefPtr<Process> Create();
|
||||||
|
|
||||||
uint64_t id() const { return id_; }
|
uint64_t id() const { return id_; }
|
||||||
RefPtr<AddressSpace> vmas() { return vmas_; }
|
glcr::RefPtr<AddressSpace> vmas() { return vmas_; }
|
||||||
|
|
||||||
RefPtr<Thread> CreateThread();
|
glcr::RefPtr<Thread> CreateThread();
|
||||||
RefPtr<Thread> GetThread(uint64_t tid);
|
glcr::RefPtr<Thread> GetThread(uint64_t tid);
|
||||||
|
|
||||||
RefPtr<Capability> ReleaseCapability(uint64_t cid);
|
glcr::RefPtr<Capability> ReleaseCapability(uint64_t cid);
|
||||||
RefPtr<Capability> GetCapability(uint64_t cid);
|
glcr::RefPtr<Capability> GetCapability(uint64_t cid);
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
uint64_t AddNewCapability(const RefPtr<T>& obj, uint64_t permissions) {
|
uint64_t AddNewCapability(const glcr::RefPtr<T>& obj, uint64_t permissions) {
|
||||||
return caps_.AddNewCapability(obj, permissions);
|
return caps_.AddNewCapability(obj, permissions);
|
||||||
}
|
}
|
||||||
uint64_t AddExistingCapability(const RefPtr<Capability>& cap);
|
uint64_t AddExistingCapability(const glcr::RefPtr<Capability>& cap);
|
||||||
|
|
||||||
// Checks the state of all child threads and transitions to
|
// Checks the state of all child threads and transitions to
|
||||||
// finished if all have finished.
|
// finished if all have finished.
|
||||||
|
@ -53,19 +53,19 @@ class Process : public KernelObject {
|
||||||
State GetState() { return state_; }
|
State GetState() { return state_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class MakeRefCountedFriend<Process>;
|
friend class glcr::MakeRefCountedFriend<Process>;
|
||||||
Process();
|
Process();
|
||||||
Process(uint64_t id) : id_(id), vmas_(AddressSpace::ForRoot()) {}
|
Process(uint64_t id) : id_(id), vmas_(AddressSpace::ForRoot()) {}
|
||||||
|
|
||||||
Mutex mutex_{"Process"};
|
Mutex mutex_{"Process"};
|
||||||
|
|
||||||
uint64_t id_;
|
uint64_t id_;
|
||||||
RefPtr<AddressSpace> vmas_;
|
glcr::RefPtr<AddressSpace> vmas_;
|
||||||
State state_;
|
State state_;
|
||||||
|
|
||||||
uint64_t next_thread_id_ = 0;
|
uint64_t next_thread_id_ = 0;
|
||||||
uint64_t next_cap_id_ = 0x100;
|
uint64_t next_cap_id_ = 0x100;
|
||||||
|
|
||||||
LinkedList<RefPtr<Thread>> threads_;
|
LinkedList<glcr::RefPtr<Thread>> threads_;
|
||||||
CapabilityTable caps_;
|
CapabilityTable caps_;
|
||||||
};
|
};
|
||||||
|
|
|
@ -21,12 +21,12 @@ extern "C" void thread_init() {
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
RefPtr<Thread> Thread::RootThread(Process& root_proc) {
|
glcr::RefPtr<Thread> Thread::RootThread(Process& root_proc) {
|
||||||
return MakeRefCounted<Thread>(root_proc);
|
return glcr::MakeRefCounted<Thread>(root_proc);
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<Thread> Thread::Create(Process& proc, uint64_t tid) {
|
glcr::RefPtr<Thread> Thread::Create(Process& proc, uint64_t tid) {
|
||||||
return MakeRefCounted<Thread>(proc, tid);
|
return glcr::MakeRefCounted<Thread>(proc, tid);
|
||||||
}
|
}
|
||||||
|
|
||||||
Thread::Thread(Process& proc, uint64_t tid) : process_(proc), id_(tid) {
|
Thread::Thread(Process& proc, uint64_t tid) : process_(proc), id_(tid) {
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <glacier/container/intrusive_list.h>
|
||||||
|
#include <glacier/memory/ref_ptr.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "lib/ref_ptr.h"
|
|
||||||
#include "object/kernel_object.h"
|
#include "object/kernel_object.h"
|
||||||
|
|
||||||
// Forward decl due to cyclic dependency.
|
// Forward decl due to cyclic dependency.
|
||||||
|
@ -14,7 +15,7 @@ struct KernelObjectTag<Thread> {
|
||||||
static const uint64_t type = KernelObject::THREAD;
|
static const uint64_t type = KernelObject::THREAD;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Thread : public KernelObject {
|
class Thread : public KernelObject, public glcr::IntrusiveListNode<Thread> {
|
||||||
public:
|
public:
|
||||||
uint64_t TypeTag() override { return KernelObject::THREAD; }
|
uint64_t TypeTag() override { return KernelObject::THREAD; }
|
||||||
enum State {
|
enum State {
|
||||||
|
@ -25,8 +26,8 @@ class Thread : public KernelObject {
|
||||||
BLOCKED,
|
BLOCKED,
|
||||||
FINISHED,
|
FINISHED,
|
||||||
};
|
};
|
||||||
static RefPtr<Thread> RootThread(Process& root_proc);
|
static glcr::RefPtr<Thread> RootThread(Process& root_proc);
|
||||||
static RefPtr<Thread> Create(Process& proc, uint64_t tid);
|
static glcr::RefPtr<Thread> Create(Process& proc, uint64_t tid);
|
||||||
|
|
||||||
uint64_t tid() const { return id_; };
|
uint64_t tid() const { return id_; };
|
||||||
uint64_t pid() const;
|
uint64_t pid() const;
|
||||||
|
@ -48,7 +49,7 @@ class Thread : public KernelObject {
|
||||||
void Exit();
|
void Exit();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class MakeRefCountedFriend<Thread>;
|
friend class glcr::MakeRefCountedFriend<Thread>;
|
||||||
Thread(Process& proc, uint64_t tid);
|
Thread(Process& proc, uint64_t tid);
|
||||||
// Special constructor for the root thread only.
|
// Special constructor for the root thread only.
|
||||||
Thread(Process& proc) : process_(proc), id_(0) {}
|
Thread(Process& proc) : process_(proc), id_(0) {}
|
||||||
|
|
|
@ -7,7 +7,7 @@ void ProcessManager::Init() {
|
||||||
gProcMan->InsertProcess(Process::RootProcess());
|
gProcMan->InsertProcess(Process::RootProcess());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProcessManager::InsertProcess(const RefPtr<Process>& proc) {
|
void ProcessManager::InsertProcess(const glcr::RefPtr<Process>& proc) {
|
||||||
proc_list_.PushBack(proc);
|
proc_list_.PushBack(proc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <glacier/memory/ref_ptr.h>
|
||||||
|
|
||||||
#include "lib/linked_list.h"
|
#include "lib/linked_list.h"
|
||||||
#include "lib/ref_ptr.h"
|
|
||||||
#include "object/process.h"
|
#include "object/process.h"
|
||||||
|
|
||||||
class ProcessManager {
|
class ProcessManager {
|
||||||
|
@ -10,14 +11,14 @@ class ProcessManager {
|
||||||
// and stores it in the global variable.
|
// and stores it in the global variable.
|
||||||
static void Init();
|
static void Init();
|
||||||
|
|
||||||
void InsertProcess(const RefPtr<Process>& proc);
|
void InsertProcess(const glcr::RefPtr<Process>& proc);
|
||||||
Process& FromId(uint64_t id);
|
Process& FromId(uint64_t id);
|
||||||
|
|
||||||
void DumpProcessStates();
|
void DumpProcessStates();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// TODO: This should be a hashmap.
|
// TODO: This should be a hashmap.
|
||||||
LinkedList<RefPtr<Process>> proc_list_;
|
LinkedList<glcr::RefPtr<Process>> proc_list_;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern ProcessManager* gProcMan;
|
extern ProcessManager* gProcMan;
|
||||||
|
|
|
@ -59,9 +59,10 @@ void Scheduler::Preempt() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<Thread> prev = current_thread_;
|
glcr::RefPtr<Thread> prev = current_thread_;
|
||||||
prev->SetState(Thread::RUNNABLE);
|
prev->SetState(Thread::RUNNABLE);
|
||||||
current_thread_ = runnable_threads_.CycleFront(prev);
|
runnable_threads_.PushBack(prev);
|
||||||
|
current_thread_ = runnable_threads_.PopFront();
|
||||||
|
|
||||||
SwapToCurrent(*prev);
|
SwapToCurrent(*prev);
|
||||||
}
|
}
|
||||||
|
@ -73,13 +74,12 @@ void Scheduler::Yield() {
|
||||||
}
|
}
|
||||||
asm volatile("cli");
|
asm volatile("cli");
|
||||||
|
|
||||||
RefPtr<Thread> prev = current_thread_;
|
glcr::RefPtr<Thread> prev = current_thread_;
|
||||||
if (prev == sleep_thread_) {
|
if (prev == sleep_thread_) {
|
||||||
if (runnable_threads_.size() == 0) {
|
if (runnable_threads_.size() == 0) {
|
||||||
panic("Sleep thread yielded without next.");
|
panic("Sleep thread yielded without next.");
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
// FIXME: Memory operation.
|
|
||||||
current_thread_ = runnable_threads_.PopFront();
|
current_thread_ = runnable_threads_.PopFront();
|
||||||
prev->SetState(Thread::RUNNABLE);
|
prev->SetState(Thread::RUNNABLE);
|
||||||
}
|
}
|
||||||
|
@ -89,7 +89,6 @@ void Scheduler::Yield() {
|
||||||
dbgln("Sleeping");
|
dbgln("Sleeping");
|
||||||
gProcMan->DumpProcessStates();
|
gProcMan->DumpProcessStates();
|
||||||
} else {
|
} else {
|
||||||
// FIXME: Memory operation.
|
|
||||||
current_thread_ = runnable_threads_.PopFront();
|
current_thread_ = runnable_threads_.PopFront();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <glacier/container/intrusive_list.h>
|
||||||
|
#include <glacier/memory/ref_ptr.h>
|
||||||
|
|
||||||
#include "object/process.h"
|
#include "object/process.h"
|
||||||
#include "object/thread.h"
|
#include "object/thread.h"
|
||||||
|
|
||||||
|
@ -13,9 +16,9 @@ class Scheduler {
|
||||||
void Enable() { enabled_ = true; }
|
void Enable() { enabled_ = true; }
|
||||||
|
|
||||||
Process& CurrentProcess() { return current_thread_->process(); }
|
Process& CurrentProcess() { return current_thread_->process(); }
|
||||||
RefPtr<Thread> CurrentThread() { return current_thread_; }
|
glcr::RefPtr<Thread> CurrentThread() { return current_thread_; }
|
||||||
|
|
||||||
void Enqueue(const RefPtr<Thread>& thread) {
|
void Enqueue(const glcr::RefPtr<Thread>& thread) {
|
||||||
runnable_threads_.PushBack(thread);
|
runnable_threads_.PushBack(thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,10 +28,10 @@ class Scheduler {
|
||||||
private:
|
private:
|
||||||
bool enabled_ = false;
|
bool enabled_ = false;
|
||||||
|
|
||||||
RefPtr<Thread> current_thread_;
|
glcr::RefPtr<Thread> current_thread_;
|
||||||
LinkedList<RefPtr<Thread>> runnable_threads_;
|
glcr::IntrusiveList<Thread> runnable_threads_;
|
||||||
|
|
||||||
RefPtr<Thread> sleep_thread_;
|
glcr::RefPtr<Thread> sleep_thread_;
|
||||||
|
|
||||||
Scheduler();
|
Scheduler();
|
||||||
void SwapToCurrent(Thread& prev);
|
void SwapToCurrent(Thread& prev);
|
||||||
|
|
|
@ -7,14 +7,14 @@
|
||||||
z_err_t MemoryObjectCreate(ZMemoryObjectCreateReq* req) {
|
z_err_t MemoryObjectCreate(ZMemoryObjectCreateReq* req) {
|
||||||
auto& curr_proc = gScheduler->CurrentProcess();
|
auto& curr_proc = gScheduler->CurrentProcess();
|
||||||
*req->vmmo_cap = curr_proc.AddNewCapability(
|
*req->vmmo_cap = curr_proc.AddNewCapability(
|
||||||
MakeRefCounted<MemoryObject>(req->size), ZC_WRITE);
|
glcr::MakeRefCounted<MemoryObject>(req->size), ZC_WRITE);
|
||||||
return Z_OK;
|
return Z_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
z_err_t MemoryObjectCreatePhysical(ZMemoryObjectCreatePhysicalReq* req) {
|
z_err_t MemoryObjectCreatePhysical(ZMemoryObjectCreatePhysicalReq* req) {
|
||||||
auto& curr_proc = gScheduler->CurrentProcess();
|
auto& curr_proc = gScheduler->CurrentProcess();
|
||||||
uint64_t paddr = req->paddr;
|
uint64_t paddr = req->paddr;
|
||||||
auto vmmo_ref = MakeRefCounted<FixedMemoryObject>(paddr, req->size);
|
auto vmmo_ref = glcr::MakeRefCounted<FixedMemoryObject>(paddr, req->size);
|
||||||
*req->vmmo_cap = curr_proc.AddNewCapability(
|
*req->vmmo_cap = curr_proc.AddNewCapability(
|
||||||
StaticCastRefPtr<MemoryObject>(vmmo_ref), ZC_WRITE);
|
StaticCastRefPtr<MemoryObject>(vmmo_ref), ZC_WRITE);
|
||||||
return Z_OK;
|
return Z_OK;
|
||||||
|
@ -23,7 +23,7 @@ z_err_t MemoryObjectCreatePhysical(ZMemoryObjectCreatePhysicalReq* req) {
|
||||||
z_err_t MemoryObjectCreateContiguous(ZMemoryObjectCreateContiguousReq* req) {
|
z_err_t MemoryObjectCreateContiguous(ZMemoryObjectCreateContiguousReq* req) {
|
||||||
auto& curr_proc = gScheduler->CurrentProcess();
|
auto& curr_proc = gScheduler->CurrentProcess();
|
||||||
uint64_t paddr = phys_mem::AllocateContinuous(((req->size - 1) / 0x1000) + 1);
|
uint64_t paddr = phys_mem::AllocateContinuous(((req->size - 1) / 0x1000) + 1);
|
||||||
auto vmmo_ref = MakeRefCounted<FixedMemoryObject>(paddr, req->size);
|
auto vmmo_ref = glcr::MakeRefCounted<FixedMemoryObject>(paddr, req->size);
|
||||||
*req->vmmo_cap = curr_proc.AddNewCapability(
|
*req->vmmo_cap = curr_proc.AddNewCapability(
|
||||||
StaticCastRefPtr<MemoryObject>(vmmo_ref), ZC_WRITE);
|
StaticCastRefPtr<MemoryObject>(vmmo_ref), ZC_WRITE);
|
||||||
*req->paddr = paddr;
|
*req->paddr = paddr;
|
||||||
|
@ -34,7 +34,7 @@ z_err_t TempPcieConfigObjectCreate(ZTempPcieConfigObjectCreateReq* req) {
|
||||||
auto& curr_proc = gScheduler->CurrentProcess();
|
auto& curr_proc = gScheduler->CurrentProcess();
|
||||||
uint64_t pci_base, pci_size;
|
uint64_t pci_base, pci_size;
|
||||||
RET_ERR(GetPciExtendedConfiguration(&pci_base, &pci_size));
|
RET_ERR(GetPciExtendedConfiguration(&pci_base, &pci_size));
|
||||||
auto vmmo_ref = MakeRefCounted<FixedMemoryObject>(pci_base, pci_size);
|
auto vmmo_ref = glcr::MakeRefCounted<FixedMemoryObject>(pci_base, pci_size);
|
||||||
*req->vmmo_cap = curr_proc.AddNewCapability(
|
*req->vmmo_cap = curr_proc.AddNewCapability(
|
||||||
StaticCastRefPtr<MemoryObject>(vmmo_ref), ZC_WRITE);
|
StaticCastRefPtr<MemoryObject>(vmmo_ref), ZC_WRITE);
|
||||||
*req->vmmo_size = pci_size;
|
*req->vmmo_size = pci_size;
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
z_err_t PortCreate(ZPortCreateReq* req) {
|
z_err_t PortCreate(ZPortCreateReq* req) {
|
||||||
auto& proc = gScheduler->CurrentProcess();
|
auto& proc = gScheduler->CurrentProcess();
|
||||||
auto port = MakeRefCounted<Port>();
|
auto port = glcr::MakeRefCounted<Port>();
|
||||||
*req->port_cap = proc.AddNewCapability(port, ZC_WRITE | ZC_READ);
|
*req->port_cap = proc.AddNewCapability(port, ZC_WRITE | ZC_READ);
|
||||||
return Z_OK;
|
return Z_OK;
|
||||||
}
|
}
|
||||||
|
@ -55,7 +55,7 @@ z_err_t IrqRegister(ZIrqRegisterReq* req) {
|
||||||
// FIXME: Don't hardcode this nonsense.
|
// FIXME: Don't hardcode this nonsense.
|
||||||
return Z_ERR_UNIMPLEMENTED;
|
return Z_ERR_UNIMPLEMENTED;
|
||||||
}
|
}
|
||||||
RefPtr<Port> port = MakeRefCounted<Port>();
|
glcr::RefPtr<Port> port = glcr::MakeRefCounted<Port>();
|
||||||
*req->port_cap = proc.AddNewCapability(port, ZC_READ | ZC_WRITE);
|
*req->port_cap = proc.AddNewCapability(port, ZC_READ | ZC_WRITE);
|
||||||
RegisterPciPort(port);
|
RegisterPciPort(port);
|
||||||
return Z_OK;
|
return Z_OK;
|
||||||
|
|
|
@ -18,7 +18,7 @@ z_err_t ProcessSpawn(ZProcessSpawnReq* req) {
|
||||||
auto cap = curr_proc.GetCapability(req->proc_cap);
|
auto cap = curr_proc.GetCapability(req->proc_cap);
|
||||||
RET_ERR(ValidateCapability<Process>(cap, ZC_PROC_SPAWN_PROC));
|
RET_ERR(ValidateCapability<Process>(cap, ZC_PROC_SPAWN_PROC));
|
||||||
|
|
||||||
RefPtr<Process> proc = Process::Create();
|
glcr::RefPtr<Process> proc = Process::Create();
|
||||||
gProcMan->InsertProcess(proc);
|
gProcMan->InsertProcess(proc);
|
||||||
|
|
||||||
*req->new_proc_cap = curr_proc.AddNewCapability(
|
*req->new_proc_cap = curr_proc.AddNewCapability(
|
||||||
|
|
Loading…
Reference in New Issue