Compare commits

..

5 Commits

Author SHA1 Message Date
41b3c8adb2
Convert to_dynamic_unit to OwnedStringView and rename the old variant to to_dynamic_unit_cstr
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-16 18:18:24 +01:00
be22cf6267
Introduce OwnedStringView
A managed String which uses RAII to free its contents. It's not a proper string though, since it's read-only.
So it's a StringView... but an owned one.

Can't be copied automatically, must be either moved or copied manually by calling clone() on it.
2022-12-16 18:17:15 +01:00
d759058b80
Introduce std::nothrow
Let's make sure we explicitly tell new that we don't want exceptions
2022-12-16 18:14:48 +01:00
32c8869973
Option: Simplify release_value
This avoids copying + we don't need to destroy the item if we move it, since it either gets emptied by moving it or doesn't have anything to destroy.
2022-12-16 18:13:40 +01:00
19a4e2ab58
Result, Option: Make sure everything is properly moved 2022-12-16 18:11:17 +01:00
10 changed files with 127 additions and 21 deletions

View File

@ -4,6 +4,7 @@
#include "arch/Timer.h" #include "arch/Timer.h"
#include "boot/Init.h" #include "boot/Init.h"
#include "config.h" #include "config.h"
#include "memory/Heap.h"
#include "memory/MemoryManager.h" #include "memory/MemoryManager.h"
#include "thread/Scheduler.h" #include "thread/Scheduler.h"
#include <luna/Result.h> #include <luna/Result.h>
@ -23,6 +24,13 @@ void async_thread()
} }
} }
void heap_thread()
{
CPU::disable_interrupts();
dump_heap_usage();
while (true) kernel_sleep(UINT64_MAX);
}
Result<void> init() Result<void> init()
{ {
kinfoln("Starting Moon %s", MOON_VERSION); kinfoln("Starting Moon %s", MOON_VERSION);
@ -33,19 +41,15 @@ Result<void> init()
Timer::init(); Timer::init();
char buffer[64]; kinfoln("Total memory: %s", to_dynamic_unit(MemoryManager::total()).release_value().chars());
to_dynamic_unit(MemoryManager::total(), buffer, sizeof(buffer)); kinfoln("Free memory: %s", to_dynamic_unit(MemoryManager::free()).release_value().chars());
kinfoln("Total memory: %s", buffer); kinfoln("Used memory: %s", to_dynamic_unit(MemoryManager::used()).release_value().chars());
to_dynamic_unit(MemoryManager::free(), buffer, sizeof(buffer)); kinfoln("Reserved memory: %s", to_dynamic_unit(MemoryManager::reserved()).release_value().chars());
kinfoln("Free memory: %s", buffer);
to_dynamic_unit(MemoryManager::used(), buffer, sizeof(buffer));
kinfoln("Used memory: %s", buffer);
to_dynamic_unit(MemoryManager::reserved(), buffer, sizeof(buffer));
kinfoln("Reserved memory: %s", buffer);
Scheduler::init(); Scheduler::init();
TRY(Scheduler::new_kernel_thread(async_thread)); TRY(Scheduler::new_kernel_thread(async_thread));
TRY(Scheduler::new_kernel_thread(heap_thread));
CPU::platform_finish_init(); CPU::platform_finish_init();

View File

@ -5,12 +5,18 @@
#include "memory/KernelVM.h" #include "memory/KernelVM.h"
#include "memory/MemoryManager.h" #include "memory/MemoryManager.h"
#include <luna/Alignment.h> #include <luna/Alignment.h>
#include <luna/Alloc.h>
#include <luna/LinkedList.h> #include <luna/LinkedList.h>
#include <luna/SafeArithmetic.h> #include <luna/SafeArithmetic.h>
#include <luna/ScopeGuard.h> #include <luna/ScopeGuard.h>
#include <luna/String.h> #include <luna/String.h>
#include <luna/SystemError.h> #include <luna/SystemError.h>
namespace std
{
const std::nothrow_t nothrow;
}
static constexpr int BLOCK_USED = 1 << 0; static constexpr int BLOCK_USED = 1 << 0;
static constexpr int BLOCK_START_MEM = 1 << 1; static constexpr int BLOCK_START_MEM = 1 << 1;
static constexpr int BLOCK_END_MEM = 1 << 2; static constexpr int BLOCK_END_MEM = 1 << 2;
@ -354,12 +360,12 @@ void dump_heap_usage()
kdbgln("-- Heap memory in use by the kernel: %zu bytes", alloc_used); kdbgln("-- Heap memory in use by the kernel: %zu bytes", alloc_used);
} }
void* operator new(usize size) noexcept void* operator new(usize size, const std::nothrow_t&) noexcept
{ {
return kmalloc(size).value_or(nullptr); return kmalloc(size).value_or(nullptr);
} }
void* operator new[](usize size) noexcept void* operator new[](usize size, const std::nothrow_t&) noexcept
{ {
return kmalloc(size).value_or(nullptr); return kmalloc(size).value_or(nullptr);
} }

View File

@ -9,6 +9,7 @@ set(FREESTANDING_SOURCES
src/Bitmap.cpp src/Bitmap.cpp
src/Stack.cpp src/Stack.cpp
src/Alloc.cpp src/Alloc.cpp
src/OwnedStringView.cpp
) )
set(SOURCES set(SOURCES

View File

@ -1,19 +1,36 @@
#pragma once #pragma once
#include <luna/Result.h> #include <luna/Result.h>
namespace std
{
struct nothrow_t
{
explicit nothrow_t() = default;
};
extern const nothrow_t nothrow;
enum class align_val_t : usize
{
};
};
[[nodiscard]] void* raw_malloc(usize); [[nodiscard]] void* raw_malloc(usize);
void raw_free(void*); void raw_free(void*);
void* operator new(usize size, const std::nothrow_t&) noexcept;
void* operator new[](usize size, const std::nothrow_t&) noexcept;
template <typename T, class... Args> [[nodiscard]] Result<T*> make(Args... args) template <typename T, class... Args> [[nodiscard]] Result<T*> make(Args... args)
{ {
T* const result = new T(args...); T* const result = new (std::nothrow) T(args...);
if (!result) return err(ENOMEM); if (!result) return err(ENOMEM);
return result; return result;
} }
template <typename T> [[nodiscard]] Result<T*> make_array(usize count) template <typename T> [[nodiscard]] Result<T*> make_array(usize count)
{ {
T* const result = new T[count]; T* const result = new (std::nothrow) T[count];
if (!result) return err(ENOMEM); if (!result) return err(ENOMEM);
return result; return result;
} }

View File

@ -50,10 +50,8 @@ template <typename T> class Option
T release_value() T release_value()
{ {
expect(has_value(), "Option::release_value called on an empty Option"); expect(has_value(), "Option::release_value called on an empty Option");
T item = m_storage.fetch_reference();
m_has_value = false; m_has_value = false;
m_storage.destroy(); return move(m_storage.fetch_reference());
return move(item);
} }
T value_or(const T& other) const T value_or(const T& other) const
@ -126,7 +124,7 @@ template <typename T> class Option
void store_moved_reference(T&& ref) void store_moved_reference(T&& ref)
{ {
new (buffer) T(ref); new (buffer) T(move(ref));
} }
void destroy() void destroy()

View File

@ -0,0 +1,27 @@
#pragma once
class OwnedStringView
{
public:
OwnedStringView(char* c_str);
OwnedStringView();
OwnedStringView(OwnedStringView&&);
OwnedStringView(const OwnedStringView&) = delete;
~OwnedStringView();
Result<OwnedStringView> clone();
const char* chars()
{
return m_string;
}
usize length()
{
return m_length;
}
private:
char* m_string{nullptr};
usize m_length{0};
};

View File

@ -25,7 +25,7 @@ template <typename T> class Result
m_has_error = false; m_has_error = false;
} }
Result(T&& value) : m_value(value) Result(T&& value) : m_value(move(value))
{ {
m_has_value = true; m_has_value = true;
m_has_error = false; m_has_error = false;
@ -46,7 +46,7 @@ template <typename T> class Result
} }
} }
Result(Result<T>&& other) : m_value(other.m_value) Result(Result<T>&& other) : m_value(move(other.m_value))
{ {
if (!other.m_has_error) if (!other.m_has_error)
{ {

View File

@ -1,4 +1,6 @@
#pragma once #pragma once
#include <luna/OwnedStringView.h>
#include <luna/Result.h> #include <luna/Result.h>
Result<usize> to_dynamic_unit(usize value, char* buffer, usize max); Result<usize> to_dynamic_unit_cstr(usize value, char* buffer, usize max);
Result<OwnedStringView> to_dynamic_unit(usize value);

View File

@ -0,0 +1,36 @@
#include <luna/Alloc.h>
#include <luna/OwnedStringView.h>
#include <luna/String.h>
OwnedStringView::OwnedStringView()
{
}
OwnedStringView::OwnedStringView(OwnedStringView&& other)
{
m_string = other.m_string;
m_length = other.m_length;
other.m_string = nullptr;
}
OwnedStringView::OwnedStringView(char* c_str)
{
m_string = c_str;
if (m_string) { m_length = strlen(m_string); }
}
OwnedStringView::~OwnedStringView()
{
if (m_string) destroy_array(m_string);
}
Result<OwnedStringView> OwnedStringView::clone()
{
char* buf = TRY(make_array<char>(m_length + 1));
memcpy(buf, m_string, m_length + 1);
return OwnedStringView{buf};
}

View File

@ -1,8 +1,10 @@
#include <luna/Alloc.h>
#include <luna/Format.h> #include <luna/Format.h>
#include <luna/Result.h> #include <luna/Result.h>
#include <luna/ScopeGuard.h>
#include <luna/Units.h> #include <luna/Units.h>
Result<usize> to_dynamic_unit(usize value, char* buffer, usize max) Result<usize> to_dynamic_unit_cstr(usize value, char* buffer, usize max)
{ {
if (value < 1024) { return string_format(buffer, max, "%u bytes", value); } if (value < 1024) { return string_format(buffer, max, "%u bytes", value); }
@ -14,4 +16,17 @@ Result<usize> to_dynamic_unit(usize value, char* buffer, usize max)
} }
return string_format(buffer, max, "%u.%u %ciB", value / 1024, (value % 1024) / 103, *unit_prefixes); return string_format(buffer, max, "%u.%u %ciB", value / 1024, (value % 1024) / 103, *unit_prefixes);
}
Result<OwnedStringView> to_dynamic_unit(usize value)
{
char* buf = TRY(make_array<char>(64));
auto guard = make_scope_guard([&] { destroy_array(buf); });
TRY(to_dynamic_unit_cstr(value, buf, 64));
guard.deactivate();
return OwnedStringView{buf};
} }