Skip to content

Commit

Permalink
C++: add shared_ptr
Browse files Browse the repository at this point in the history
  • Loading branch information
moodyhunter committed Feb 18, 2025
1 parent 3963167 commit 48cd7e6
Show file tree
Hide file tree
Showing 46 changed files with 502 additions and 373 deletions.
2 changes: 1 addition & 1 deletion cmake/add_mos_library.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ function(add_mos_library)
target_compile_definitions(stdlib_minimal PRIVATE ${ARG_PRIVATE_DEFINES})
add_mos_library_do_setup(stdlib_minimal "" "${ARG_PRIVATE_INCLUDE_DIRECTORIES}" "${ARG_PUBLIC_INCLUDE_DIRECTORIES}")

target_link_libraries(stdlib_minimal PUBLIC supc++ gcc mos::include)
target_link_libraries(stdlib_minimal PUBLIC gcc mos::include)
target_compile_options(stdlib_minimal PUBLIC "-ffreestanding")
target_compile_definitions(stdlib_minimal PUBLIC "__MLIBC_ABI_ONLY")
target_compile_definitions(stdlib_minimal PUBLIC "__MOS_MINIMAL_LIBC__")
Expand Down
1 change: 1 addition & 0 deletions kernel/arch/x86_64/interrupt/x86_interrupt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ static void x86_handle_exception(platform_regs_t *regs)
.is_exec = (regs->error_code & 0x10) != 0,
.ip = regs->ip,
.regs = regs,
.backing_page = nullptr,
};

mm_handle_fault(x86_cpu_get_cr2(), &info);
Expand Down
15 changes: 8 additions & 7 deletions kernel/arch/x86_64/tasks/context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ void platform_context_setup_child_thread(Thread *thread, thread_entry_t entry, v
regs->sp = thread->u_stack.head; // update the stack pointer
}

void platform_context_clone(const Thread *from, Thread *to)
void platform_context_clone(Thread *from, Thread *to)
{
platform_regs_t *to_regs = platform_thread_regs(to);
*to_regs = *platform_thread_regs(from);
Expand All @@ -119,22 +119,23 @@ void platform_context_clone(const Thread *from, Thread *to)

void platform_switch_to_thread(Thread *current, Thread *new_thread, switch_flags_t switch_flags)
{
const switch_func_t switch_func = statement_expr(switch_func_t, {
const switch_func_t switch_func = [=]() -> switch_func_t
{
switch (switch_flags)
{
case SWITCH_TO_NEW_USER_THREAD: retval = x86_start_user_thread; break;
case SWITCH_TO_NEW_KERNEL_THREAD: retval = x86_start_kernel_thread; break;
default: retval = x86_normal_switch_impl; break;
case SWITCH_TO_NEW_USER_THREAD: return x86_start_user_thread; break;
case SWITCH_TO_NEW_KERNEL_THREAD: return x86_start_kernel_thread; break;
default: return x86_normal_switch_impl; break;
}
});
}();

if (current)
x86_xsave_thread(current);

x86_xrstor_thread(new_thread);
x86_set_fsbase(new_thread);

__atomic_store_n(&current_cpu->thread, new_thread, __ATOMIC_SEQ_CST);
current_cpu->thread = new_thread;
__atomic_store_n(&per_cpu(x86_cpu_descriptor)->tss.rsp0, new_thread->k_stack.top, __ATOMIC_SEQ_CST);

ptr_t trash = 0;
Expand Down
8 changes: 4 additions & 4 deletions kernel/arch/x86_64/x86_platform_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ void platform_switch_mm(const MMContext *mm)
x86_cpu_set_cr3(pgd_pfn(mm->pgd) * MOS_PAGE_SIZE);
}

platform_regs_t *platform_thread_regs(const Thread *thread)
platform_regs_t *platform_thread_regs(Thread *thread)
{
return (platform_regs_t *) (thread->k_stack.top - sizeof(platform_regs_t));
}
Expand All @@ -103,7 +103,7 @@ void platform_dump_thread_kernel_stack(const Thread *thread)

if (thread->state != THREAD_STATE_BLOCKED)
{
pr_emph("thread %pt is not blocked, cannot dump stack", (void *) thread);
pr_emph("thread %pt is not blocked, cannot dump stack", thread);
return;
}

Expand All @@ -123,14 +123,14 @@ u64 platform_arch_syscall(u64 syscall, u64 __maybe_unused arg1, u64 __maybe_unus
{
case X86_SYSCALL_IOPL_ENABLE:
{
pr_dinfo2(syscall, "enabling IOPL for thread %pt", (void *) current_thread);
pr_dinfo2(syscall, "enabling IOPL for thread %pt", current_thread);
current_process->platform_options.iopl = true;
platform_thread_regs(current_thread)->eflags |= 0x3000;
return 0;
}
case X86_SYSCALL_IOPL_DISABLE:
{
pr_dinfo2(syscall, "disabling IOPL for thread %pt", (void *) current_thread);
pr_dinfo2(syscall, "disabling IOPL for thread %pt", current_thread);
current_process->platform_options.iopl = false;
platform_thread_regs(current_thread)->eflags &= ~0x3000;
return 0;
Expand Down
2 changes: 1 addition & 1 deletion kernel/device/timer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ static bool timer_do_wakeup(ktimer_t *timer, void *arg)
{
MOS_UNUSED(arg);

if (timer->thread != NULL)
if (timer->thread)
scheduler_wake_thread(timer->thread);

return true;
Expand Down
11 changes: 4 additions & 7 deletions kernel/filesystem/mount.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,9 @@
#include <mos/hashmap.hpp>
#include <mos/shared_ptr.hpp>
#include <mos_stdlib.hpp>
#include <type_traits>

#define VFS_MOUNTPOINT_MAP_SIZE 256
static mos::HashMap<const dentry_t *, mos::shared_ptr<mount_t>> vfs_mountpoint_map; // dentry_t -> mount_t
static mos::HashMap<const dentry_t *, ptr<mount_t>> vfs_mountpoint_map; // dentry_t -> mount_t
list_head vfs_mountpoint_list;

/**
Expand Down Expand Up @@ -48,7 +47,7 @@ dentry_t *dentry_root_get_mountpoint(dentry_t *dentry)
return NULL; // not found, possibly just have been unmounted
}

mos::shared_ptr<mount_t> dentry_get_mount(const dentry_t *dentry)
ptr<mount_t> dentry_get_mount(const dentry_t *dentry)
{
if (!dentry->is_mountpoint)
{
Expand All @@ -63,11 +62,9 @@ mos::shared_ptr<mount_t> dentry_get_mount(const dentry_t *dentry)
return NULL;
}

auto mount = *pmount.value();

// otherwise the mountpoint must match the dentry
MOS_ASSERT(mount->mountpoint == dentry);
return mount;
MOS_ASSERT((*pmount)->mountpoint == dentry);
return *pmount;
}

bool dentry_mount(dentry_t *mountpoint, dentry_t *root, filesystem_t *fs)
Expand Down
6 changes: 2 additions & 4 deletions kernel/filesystem/page_cache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,9 @@ long pagecache_flush_or_drop(inode_cache_t *icache, off_t pgoff, size_t npages,
{
auto ppage = icache->pages.get(pgoff + i);
if (!ppage.has_value())
{
continue;
}

do_flush_and_drop_cached_page(pgoff + i, **ppage, &data);
do_flush_and_drop_cached_page(pgoff + i, *ppage, &data);

if (data.ret != 0)
{
Expand All @@ -89,7 +87,7 @@ PtrResult<phyframe_t> pagecache_get_page_for_read(inode_cache_t *cache, off_t pg
{
const auto page = cache->pages.get(pgoff);
if (page)
return **page;
return *page;
}

if (!cache->ops)
Expand Down
27 changes: 1 addition & 26 deletions kernel/include/libs/mos/allocator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,37 +4,12 @@

#include "mos/mm/slab.hpp"

#include <mos/string_view.hpp>
#include <mos/type_utils.hpp>
#include <type_traits>

MOSAPI void *do_kmalloc(size_t size);
MOSAPI void *do_kcalloc(size_t nmemb, size_t size);
MOSAPI void *do_krealloc(void *ptr, size_t size);
MOSAPI void do_kfree(const void *ptr);

namespace mos
{
template<typename T>
concept HasTypeName = std::is_same_v<std::remove_const_t<decltype(T::type_name)>, mos::string_view>;

template<typename T, typename... Args>
requires HasTypeName<T> T *create(Args &&...args)
{
InitOnce<Slab<T>> slab;
static InitOnce<Slab<T>> slab;
return slab->create(args...);
}

struct default_allocator
{
void *allocate(size_t size)
{
return do_kmalloc(size);
}

void free(void *ptr, size_t = 0)
{
do_kfree(ptr);
}
};
} // namespace mos
27 changes: 27 additions & 0 deletions kernel/include/libs/mos/default_allocator.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// SPDX-License-Identifier: GPL-3.0-or-later

#pragma once

#include <mos/mos_global.h>
#include <mos/string_view.hpp>

MOSAPI void *do_kmalloc(size_t size);
MOSAPI void *do_kcalloc(size_t nmemb, size_t size);
MOSAPI void *do_krealloc(void *ptr, size_t size);
MOSAPI void do_kfree(const void *ptr);

namespace mos
{
struct default_allocator
{
static void *allocate(size_t size)
{
return do_kmalloc(size);
}

static void free(void *ptr, size_t = 0)
{
do_kfree(ptr);
}
};
} // namespace mos
88 changes: 39 additions & 49 deletions kernel/include/libs/mos/hashmap.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,11 +136,31 @@ namespace mos
size_t bucket;
};

constexpr HashMap(TAllocator allocator = TAllocator());
HashMap(std::initializer_list<entry_type> init, TAllocator allocator = TAllocator());
HashMap(const HashMap &) = delete;
constexpr HashMap() : _table(nullptr), _capacity(0), _size(0) {};
HashMap(std::initializer_list<entry_type> init) : _table(nullptr), _capacity(0), _size(0)
{
/* TODO: we know the size so we don't have to keep rehashing?? */
for (auto &[key, value] : init)
insert(key, value);
}

~HashMap();
~HashMap()
{
for (size_t i = 0; i < _capacity; i++)
{
chain *item = _table[i];
while (item != nullptr)
{
chain *next = item->next;
delete item;
item = next;
}
}

TAllocator::free(_table, sizeof(chain *) * _capacity);
}

HashMap(const HashMap &) = delete;

void insert(const Key &key, const Value &value);
void insert(const Key &key, Value &&value);
Expand Down Expand Up @@ -206,7 +226,7 @@ namespace mos
return end();
}

std::optional<Value *> get(const Key &key);
std::optional<Value> get(const Key &key);
std::optional<Value> remove(const Key &key);

size_t size() const
Expand All @@ -217,43 +237,13 @@ namespace mos
private:
void rehash();

TAllocator _allocator;
chain **_table;
size_t _capacity;
size_t _size;
};

template<typename Key, typename Value, typename Allocator>
constexpr HashMap<Key, Value, Allocator>::HashMap(Allocator allocator) : _allocator(std::move(allocator)), _table(nullptr), _capacity(0), _size(0){};

template<typename Key, typename Value, typename Allocator>
HashMap<Key, Value, Allocator>::HashMap(std::initializer_list<entry_type> init, Allocator allocator)
: _allocator(std::move(allocator)), _table(nullptr), _capacity(0), _size(0)
{
/* TODO: we know the size so we don't have to keep rehashing?? */
for (auto &[key, value] : init)
insert(key, value);
}

template<typename Key, typename Value, typename Allocator>
HashMap<Key, Value, Allocator>::~HashMap()
{
for (size_t i = 0; i < _capacity; i++)
{
chain *item = _table[i];
while (item != nullptr)
{
chain *next = item->next;
delete item;
item = next;
}
}

_allocator.free(_table, sizeof(chain *) * _capacity);
}

template<typename Key, typename Value, typename Allocator>
void HashMap<Key, Value, Allocator>::insert(const Key &key, const Value &value)
template<typename Key, typename Value, typename TAllocator>
void HashMap<Key, Value, TAllocator>::insert(const Key &key, const Value &value)
{
if (_size >= _capacity)
rehash();
Expand All @@ -267,8 +257,8 @@ namespace mos
_size++;
}

template<typename Key, typename Value, typename Allocator>
void HashMap<Key, Value, Allocator>::insert(const Key &key, Value &&value)
template<typename Key, typename Value, typename TAllocator>
void HashMap<Key, Value, TAllocator>::insert(const Key &key, Value &&value)
{
if (_size >= _capacity)
rehash();
Expand All @@ -282,8 +272,8 @@ namespace mos
_size++;
}

template<typename Key, typename Value, typename Allocator>
Value &HashMap<Key, Value, Allocator>::operator[](const Key &key)
template<typename Key, typename Value, typename TAllocator>
Value &HashMap<Key, Value, TAllocator>::operator[](const Key &key)
{
/* empty map case */
if (_size == 0)
Expand Down Expand Up @@ -313,8 +303,8 @@ namespace mos
return std::get<1>(item->entry);
}

template<typename Key, typename Value, typename Allocator>
std::optional<Value *> HashMap<Key, Value, Allocator>::get(const Key &key)
template<typename Key, typename Value, typename TAllocator>
std::optional<Value> HashMap<Key, Value, TAllocator>::get(const Key &key)
{
if (_size == 0)
return std::nullopt;
Expand All @@ -324,14 +314,14 @@ namespace mos
for (chain *item = _table[bucket]; item != nullptr; item = item->next)
{
if (std::get<0>(item->entry) == key)
return &std::get<1>(item->entry);
return std::get<1>(item->entry);
}

return std::nullopt;
}

template<typename Key, typename Value, typename Allocator>
std::optional<Value> HashMap<Key, Value, Allocator>::remove(const Key &key)
template<typename Key, typename Value, typename TAllocator>
std::optional<Value> HashMap<Key, Value, TAllocator>::remove(const Key &key)
{
if (_size == 0)
return std::nullopt;
Expand Down Expand Up @@ -360,8 +350,8 @@ namespace mos
return std::nullopt;
}

template<typename Key, typename Value, typename Allocator>
void HashMap<Key, Value, Allocator>::rehash()
template<typename Key, typename Value, typename TAllocator>
void HashMap<Key, Value, TAllocator>::rehash()
{
const size_t new_capacity = std::max(2 * _size, 10lu);

Expand All @@ -384,7 +374,7 @@ namespace mos
}
}

_allocator.free(_table, sizeof(chain *) * _capacity);
TAllocator::free(_table, sizeof(chain *) * _capacity);
_table = new_table;
_capacity = new_capacity;
}
Expand Down
Loading

0 comments on commit 48cd7e6

Please sign in to comment.