From b3b1385e7af85ba2cb1f92bc31706099f1b9d562 Mon Sep 17 00:00:00 2001 From: Aqua-sama Date: Sun, 28 Mar 2021 12:41:57 +0300 Subject: Move MemoryAllocator to libk --- libk/makefile | 1 + libk/memory.h | 39 +++++++++++++++++++++ libk/memory/allocator.cc | 90 ++++++++++++++++++++++++++++++++++++++++++++++++ makefile | 9 +++-- src/allocator.cc | 90 ------------------------------------------------ src/allocator.h | 39 --------------------- src/kernel.cc | 3 +- src/makefile | 1 - 8 files changed, 135 insertions(+), 137 deletions(-) create mode 100644 libk/memory.h create mode 100644 libk/memory/allocator.cc delete mode 100644 src/allocator.cc delete mode 100644 src/allocator.h diff --git a/libk/makefile b/libk/makefile index f3b9aeb..eafa98c 100644 --- a/libk/makefile +++ b/libk/makefile @@ -1,4 +1,5 @@ CXX_OBJ = string/integerview.o string/memory.o \ + memory/allocator.o \ stdlib/abort.o stdlib/console.o stdlib/virtual.o CXX_OBJ := $(addprefix $(OBJ_DIR)/, $(CXX_OBJ)) CXX_DEP = $(CXX_OBJ:%.o=%.d) diff --git a/libk/memory.h b/libk/memory.h new file mode 100644 index 0000000..a01252c --- /dev/null +++ b/libk/memory.h @@ -0,0 +1,39 @@ +#pragma once + +#include + +class MemoryAllocator { +public: + MemoryAllocator(uint32_t start, size_t size); + + void* allocate(size_t size); + void deallocate(void* ptr); + + size_t free_space() const; + size_t used_space() const; + +private: + struct MemoryChunk { + MemoryChunk* prev = nullptr; + MemoryChunk* next = nullptr; + bool allocated = false; + size_t size = 0; + }; + MemoryChunk* begin; +}; + +namespace std { +struct nothrow_t { + explicit nothrow_t() = default; +}; +}; // namespace std + +void* operator new(unsigned, const std::nothrow_t&) noexcept; +void* operator new[](unsigned, const std::nothrow_t&) noexcept; + +void operator delete(void* ptr); +void operator delete[](void* ptr); + +// placement new +void* operator new(unsigned, void*); +void* operator new[](unsigned, void*); diff --git a/libk/memory/allocator.cc b/libk/memory/allocator.cc new file mode 100644 index 0000000..351646f --- /dev/null +++ b/libk/memory/allocator.cc @@ -0,0 +1,90 @@ +#include + +static MemoryAllocator* mem_alloc = nullptr; + +MemoryAllocator::MemoryAllocator(uint32_t start, size_t size) { + if (size < sizeof(MemoryChunk)) { + begin = nullptr; + return; + } + begin = new (reinterpret_cast(start)) MemoryChunk{.size = static_cast(size - sizeof(MemoryChunk))}; + if (mem_alloc == nullptr) mem_alloc = this; +} + +void* MemoryAllocator::allocate(size_t size) { + // TODO spinlock + // TODO memset 0 over allocated memory + MemoryChunk* result = nullptr; + + // find the first chunk that is at least size and not allocated + for (auto* iter = begin; iter != nullptr; iter = iter->next) { + if (iter->size >= size && !iter->allocated) { + result = iter; + + // split chunk if there is at least one byte left over + if (result->size >= size + sizeof(MemoryChunk) + 1) { + auto* _new = new (result + sizeof(MemoryChunk) + size) MemoryChunk{ + .prev = result, .next = result->next, .size = static_cast(result->size - sizeof(MemoryChunk))}; + result->next = _new; + } + + break; + } + } + + return result + sizeof(MemoryChunk); +} +void MemoryAllocator::deallocate(void* ptr) { + auto* chunk = reinterpret_cast(reinterpret_cast(ptr) - sizeof(MemoryChunk)); + chunk->allocated = false; + + // merge in next chunk + if (chunk->next != nullptr && !chunk->next->allocated) { + chunk->size += chunk->next->size + sizeof(MemoryChunk); + chunk->next = chunk->next->next; + if (chunk->next != nullptr) chunk->next->prev = chunk; + } + + // merge into previous chunk + if (chunk->prev != nullptr && !chunk->prev->allocated) { + chunk->prev->size += chunk->size + sizeof(MemoryChunk); + chunk->prev->next = chunk->next; + if (chunk->next != nullptr) chunk->next->prev = chunk->prev; + } +}; + +size_t MemoryAllocator::free_space() const { + size_t r = 0; + for (auto* iter = begin; iter != nullptr; iter = iter->next) + if (!iter->allocated) r += iter->size; + return r; +} +size_t MemoryAllocator::used_space() const { + size_t r = 0; + for (auto* iter = begin; iter != nullptr; iter = iter->next) + if (iter->allocated) r += iter->size; + return r; +} + +void* operator new(unsigned sz, const std::nothrow_t&) noexcept { + if (mem_alloc == nullptr) return nullptr; + return mem_alloc->allocate(sz); +} +void* operator new[](unsigned sz, const std::nothrow_t&) noexcept { + if (mem_alloc == nullptr) return nullptr; + return mem_alloc->allocate(sz); +} + +void operator delete(void* ptr) { + if (mem_alloc != nullptr) mem_alloc->deallocate(ptr); +} +void operator delete[](void* ptr) { + if (mem_alloc != nullptr) mem_alloc->deallocate(ptr); +} + +void* operator new(unsigned /* size_bytes */, void* ptr) { + return ptr; +} +void* operator new[](unsigned /* size_bytes */, void* ptr) { + return ptr; +} diff --git a/makefile b/makefile index 87f229f..6f49e6d 100644 --- a/makefile +++ b/makefile @@ -2,9 +2,8 @@ include .config OBJ_DIR != echo $(CONFIG_OBJ_DIR) include toolchain.makefile -.PHONY: all libk clean test tidy todo run menuconfig +.PHONY: all libk libd clean test tidy todo run menuconfig all: $(OBJ_DIR)/src/glitch.elf -libk: $(OBJ_DIR)/libk.a LIBS := $(OBJ_DIR)/libk.a $(OBJ_DIR)/libd.a LD_FLAGS := $(LD_FLAGS) --library-path $(CURDIR)/$(OBJ_DIR) @@ -14,13 +13,13 @@ export AR AR_FLAGS AS AS_FLAGS NM SED \ TEST_CXX TEST_CXX_FLAGS \ LD LD_FLAGS -$(OBJ_DIR)/src/glitch.elf: $(LIBS) +$(OBJ_DIR)/src/glitch.elf: libk libd @make -C src OBJ_DIR=$(CURDIR)/$(OBJ_DIR)/src $(CURDIR)/$(OBJ_DIR)/src/glitch.elf -$(OBJ_DIR)/libk.a: +libk: @make -C libk OBJ_DIR=$(CURDIR)/$(OBJ_DIR)/libk $(CURDIR)/$(OBJ_DIR)/libk.a -$(OBJ_DIR)/libd.a: +libd: @make -C drivers OBJ_DIR=$(CURDIR)/$(OBJ_DIR)/drivers $(CURDIR)/$(OBJ_DIR)/libd.a compile_commands: diff --git a/src/allocator.cc b/src/allocator.cc deleted file mode 100644 index 77736cc..0000000 --- a/src/allocator.cc +++ /dev/null @@ -1,90 +0,0 @@ -#include "allocator.h" - -static MemoryAllocator* mem_alloc = nullptr; - -MemoryAllocator::MemoryAllocator(uint32_t start, size_t size) { - if (size < sizeof(MemoryChunk)) { - begin = nullptr; - return; - } - begin = new (reinterpret_cast(start)) MemoryChunk{.size = static_cast(size - sizeof(MemoryChunk))}; - if (mem_alloc == nullptr) mem_alloc = this; -} - -void* MemoryAllocator::malloc(size_t size) { - // TODO spinlock - // TODO memset 0 over allocated memory - MemoryChunk* result = nullptr; - - // find the first chunk that is at least size and not allocated - for (auto* iter = begin; iter != nullptr; iter = iter->next) { - if (iter->size >= size && !iter->allocated) { - result = iter; - - // split chunk if there is at least one byte left over - if (result->size >= size + sizeof(MemoryChunk) + 1) { - auto* _new = new (result + sizeof(MemoryChunk) + size) MemoryChunk{ - .prev = result, .next = result->next, .size = static_cast(result->size - sizeof(MemoryChunk))}; - result->next = _new; - } - - break; - } - } - - return result + sizeof(MemoryChunk); -} -void MemoryAllocator::free(void* ptr) { - auto* chunk = reinterpret_cast(reinterpret_cast(ptr) - sizeof(MemoryChunk)); - chunk->allocated = false; - - // merge in next chunk - if (chunk->next != nullptr && !chunk->next->allocated) { - chunk->size += chunk->next->size + sizeof(MemoryChunk); - chunk->next = chunk->next->next; - if (chunk->next != nullptr) chunk->next->prev = chunk; - } - - // merge into previous chunk - if (chunk->prev != nullptr && !chunk->prev->allocated) { - chunk->prev->size += chunk->size + sizeof(MemoryChunk); - chunk->prev->next = chunk->next; - if (chunk->next != nullptr) chunk->next->prev = chunk->prev; - } -}; - -size_t MemoryAllocator::free_space() const { - size_t r = 0; - for (auto* iter = begin; iter != nullptr; iter = iter->next) - if (!iter->allocated) r += iter->size; - return r; -} -size_t MemoryAllocator::used_space() const { - size_t r = 0; - for (auto* iter = begin; iter != nullptr; iter = iter->next) - if (iter->allocated) r += iter->size; - return r; -} - -void* operator new(unsigned sz, const std::nothrow_t&) noexcept { - if (mem_alloc == nullptr) return nullptr; - return mem_alloc->malloc(sz); -} -void* operator new[](unsigned sz, const std::nothrow_t&) noexcept { - if (mem_alloc == nullptr) return nullptr; - return mem_alloc->malloc(sz); -} - -void operator delete(void* ptr) { - if (mem_alloc != nullptr) mem_alloc->free(ptr); -} -void operator delete[](void* ptr) { - if (mem_alloc != nullptr) mem_alloc->free(ptr); -} - -void* operator new(unsigned /* size_bytes */, void* ptr) { - return ptr; -} -void* operator new[](unsigned /* size_bytes */, void* ptr) { - return ptr; -} diff --git a/src/allocator.h b/src/allocator.h deleted file mode 100644 index 8a12be8..0000000 --- a/src/allocator.h +++ /dev/null @@ -1,39 +0,0 @@ -#pragma once - -#include - -class MemoryAllocator { -public: - MemoryAllocator(uint32_t start, size_t size); - - void* malloc(size_t size); - void free(void* ptr); - - size_t free_space() const; - size_t used_space() const; - -private: - struct MemoryChunk { - MemoryChunk* prev = nullptr; - MemoryChunk* next = nullptr; - bool allocated = false; - size_t size = 0; - }; - MemoryChunk* begin; -}; - -namespace std { -struct nothrow_t { - explicit nothrow_t() = default; -}; -}; // namespace std - -void* operator new(unsigned, const std::nothrow_t&) noexcept; -void* operator new[](unsigned, const std::nothrow_t&) noexcept; - -void operator delete(void* ptr); -void operator delete[](void* ptr); - -// placement new -void* operator new(unsigned, void*); -void* operator new[](unsigned, void*); diff --git a/src/kernel.cc b/src/kernel.cc index 578344c..fc02f5b 100644 --- a/src/kernel.cc +++ b/src/kernel.cc @@ -8,9 +8,8 @@ #error "This tutorial needs to be compiled with a ix86-elf compiler" #endif +#include #include -#include -#include "allocator.h" #include "cga.h" #include "cpu/cpu.h" #include "gdt.h" diff --git a/src/makefile b/src/makefile index 1d85f4b..d1e2147 100644 --- a/src/makefile +++ b/src/makefile @@ -9,7 +9,6 @@ CXX_OBJ = kernel.o \ idt.o \ idt/exception.o idt/interruptgate.o idt/interrupthandler.o \ vmm.o \ - allocator.o \ scheduler.o scheduler/task.o CXX_OBJ := $(addprefix $(OBJ_DIR)/, $(CXX_OBJ)) CXX_DEP = $(CXX_OBJ:%.o=%.d) -- cgit v1.2.1