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 "boot/Init.h"
#include "config.h"
#include "memory/Heap.h"
#include "memory/MemoryManager.h"
#include "thread/Scheduler.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()
{
kinfoln("Starting Moon %s", MOON_VERSION);
@ -33,19 +41,15 @@ Result<void> init()
Timer::init();
char buffer[64];
to_dynamic_unit(MemoryManager::total(), buffer, sizeof(buffer));
kinfoln("Total memory: %s", buffer);
to_dynamic_unit(MemoryManager::free(), buffer, sizeof(buffer));
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);
kinfoln("Total memory: %s", to_dynamic_unit(MemoryManager::total()).release_value().chars());
kinfoln("Free memory: %s", to_dynamic_unit(MemoryManager::free()).release_value().chars());
kinfoln("Used memory: %s", to_dynamic_unit(MemoryManager::used()).release_value().chars());
kinfoln("Reserved memory: %s", to_dynamic_unit(MemoryManager::reserved()).release_value().chars());
Scheduler::init();
TRY(Scheduler::new_kernel_thread(async_thread));
TRY(Scheduler::new_kernel_thread(heap_thread));
CPU::platform_finish_init();

View File

@ -5,12 +5,18 @@
#include "memory/KernelVM.h"
#include "memory/MemoryManager.h"
#include <luna/Alignment.h>
#include <luna/Alloc.h>
#include <luna/LinkedList.h>
#include <luna/SafeArithmetic.h>
#include <luna/ScopeGuard.h>
#include <luna/String.h>
#include <luna/SystemError.h>
namespace std
{
const std::nothrow_t nothrow;
}
static constexpr int BLOCK_USED = 1 << 0;
static constexpr int BLOCK_START_MEM = 1 << 1;
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);
}
void* operator new(usize size) noexcept
void* operator new(usize size, const std::nothrow_t&) noexcept
{
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);
}

View File

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

View File

@ -1,19 +1,36 @@
#pragma once
#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);
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)
{
T* const result = new T(args...);
T* const result = new (std::nothrow) T(args...);
if (!result) return err(ENOMEM);
return result;
}
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);
return result;
}

View File

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

View File

@ -1,4 +1,6 @@
#pragma once
#include <luna/OwnedStringView.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/Result.h>
#include <luna/ScopeGuard.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); }
@ -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);
}
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};
}