From 5b585e5b70a9489cc5af4e14fc05ff8f51d9f9a0 Mon Sep 17 00:00:00 2001 From: Julian Barathieu Date: Mon, 18 Mar 2019 17:25:44 +0100 Subject: [PATCH] Heap & memory allocation stuff --- Makefile | 19 +++-- ProjectTree | 13 ++- kaleid/crtlib/{memory.c => mem.c} | 22 +++++ kaleid/extras/prog.c | 10 +-- kaleid/include/base/bdefs.h | 13 +++ kaleid/include/base/crtlib.h | 7 +- kaleid/include/base/errno.h | 39 ++++----- kaleid/include/extras/malloc.h | 36 ++++++--- kaleid/include/extras/prog.h | 4 +- kaleid/include/kernel/base.h | 1 - kaleid/include/kernel/cpu.h | 13 +++ kaleid/include/kernel/heap.h | 58 ++++++++++++++ kaleid/include/kernel/iomisc.h | 1 - kaleid/include/kernel/mm.h | 1 + kaleid/kernel/init/init.c | 10 +-- kaleid/kernel/io/term.c | 18 ++--- kaleid/kernel/io/vga.c | 6 +- kaleid/kernel/ke/panic.c | 8 +- kaleid/kernel/mm/.placeholder | 0 kaleid/kernel/mm/heap.c | 129 ++++++++++++++++++++++++++++++ kaleid/kernel/mm/malloc.c | 70 ++++++++++++++++ 21 files changed, 411 insertions(+), 67 deletions(-) rename kaleid/crtlib/{memory.c => mem.c} (94%) create mode 100644 kaleid/include/kernel/heap.h delete mode 100644 kaleid/kernel/mm/.placeholder create mode 100644 kaleid/kernel/mm/heap.c create mode 100644 kaleid/kernel/mm/malloc.c diff --git a/Makefile b/Makefile index eddffe6..c224923 100644 --- a/Makefile +++ b/Makefile @@ -32,11 +32,11 @@ CCNAME=x86_64-elf-gcc ASMFLAGS=-f elf64 LDFLAGS=-melf_x86_64 COPTIM=-O2 -CWARNS=-Wall -Wextra # -Werror=implicit-function-declaration +CWARNS=-Wall -Wextra -Werror=implicit-function-declaration CINCLUDES=-Ikaleid/include -CFLAGS1=-nostdlib -ffreestanding -mcmodel=large # -std=gnu11 +CFLAGS1=-nostdlib -ffreestanding -mcmodel=large -std=gnu11 CFLAGS2= -c -mno-red-zone -mno-mmx -mno-sse -mno-sse2 -fno-strict-aliasing -CFLAGS=$(CFLAGS1) $(CFLAGS2) -DNDEBUG +CFLAGS=$(CFLAGS1) $(CFLAGS2) KCC=$(CCNAME) $(COPTIM) $(CWARNS) $(CFLAGS) $(CINCLUDES) -D_OSK_SOURCE -D_KALEID_KERNEL #Folders @@ -62,7 +62,7 @@ all : OS/K # Common objects kal_com_obj= $(KOBJDIR)/atoi.o $(KOBJDIR)/ctype.o \ - $(KOBJDIR)/itoa.o $(KOBJDIR)/memory.o \ + $(KOBJDIR)/itoa.o $(KOBJDIR)/mem.o \ $(KOBJDIR)/rand.o $(KOBJDIR)/sprintf.o \ $(KOBJDIR)/status.o $(KOBJDIR)/string.o \ $(KOBJDIR)/strtol.o $(KOBJDIR)/argv.o \ @@ -98,7 +98,7 @@ $(KOBJDIR)/utoa.o: $(KERNELDIR)/crtlib/itoa.c $(KOBJDIR)/ultoa.o: $(KERNELDIR)/crtlib/itoa.c @$(KCC) -D_NEED_ULTOA $< -o $@ @echo ${CL2}[$@] ${CL}Compiled.${CL3} -$(KOBJDIR)/memory.o: $(KERNELDIR)/crtlib/memory.c +$(KOBJDIR)/mem.o: $(KERNELDIR)/crtlib/mem.c @$(KCC) -fno-strict-aliasing $< -o $@ @echo ${CL2}[$@] ${CL}Compiled.${CL3} $(KOBJDIR)/rand.o: $(KERNELDIR)/crtlib/rand.c @@ -127,7 +127,8 @@ $(KOBJDIR)/prog.o: $(KERNELDIR)/extras/prog.c kal_kern_obj= $(KOBJDIR)/kernel/cpuid.o $(KOBJDIR)/kernel/init.o \ $(KOBJDIR)/kernel/table.o $(KOBJDIR)/kernel/cursor.o \ $(KOBJDIR)/kernel/term.o $(KOBJDIR)/kernel/vga.o \ - $(KOBJDIR)/kernel/panic.o + $(KOBJDIR)/kernel/panic.o $(KOBJDIR)/kernel/heap.o \ + $(KOBJDIR)/kernel/malloc.o $(KOBJDIR)/kernel/cpuid.o: $(KERNELDIR)/kernel/cpu/cpuid.c @$(KCC) $< -o $@ @@ -150,6 +151,12 @@ $(KOBJDIR)/kernel/vga.o: $(KERNELDIR)/kernel/io/vga.c $(KOBJDIR)/kernel/panic.o: $(KERNELDIR)/kernel/ke/panic.c @$(KCC) $< -o $@ @echo ${CL2}[$@] ${CL}Compiled.${CL3} +$(KOBJDIR)/kernel/heap.o: $(KERNELDIR)/kernel/mm/heap.c + @$(KCC) $< -o $@ + @echo ${CL2}[$@] ${CL}Compiled.${CL3} +$(KOBJDIR)/kernel/malloc.o: $(KERNELDIR)/kernel/mm/malloc.c + @$(KCC) $< -o $@ + @echo ${CL2}[$@] ${CL}Compiled.${CL3} ## MISC MAKEFILE ------------------------------------------------------------- # ./ProjectTree: ./.stylehlp_sh diff --git a/ProjectTree b/ProjectTree index 134aab8..954b888 100644 --- a/ProjectTree +++ b/ProjectTree @@ -62,11 +62,14 @@ │   ├── atol.o │   ├── atoul.o │   ├── atou.o +│   ├── crtlib │   ├── ctype.o +│   ├── extras │   ├── itoa.o │   ├── kernel │   │   ├── cpuid.o │   │   ├── cursor.o +│   │   ├── heap.o │   │   ├── init │   │   │   ├── init.o │   │   │   └── table.o @@ -77,12 +80,13 @@ │   │   │   └── vga.o │   │   ├── ke │   │   │   └── panic.o +│   │   ├── malloc.o │   │   ├── panic.o │   │   ├── table.o │   │   ├── term.o │   │   └── vga.o │   ├── ltoa.o -│   ├── memory.o +│   ├── mem.o │   ├── prog.o │   ├── rand.o │   ├── sprintf.o @@ -99,7 +103,7 @@ │   │   ├── atoi.c │   │   ├── ctype.c │   │   ├── itoa.c -│   │   ├── memory.c +│   │   ├── mem.c │   │   ├── rand.c │   │   ├── sprintf.c │   │   ├── status.c @@ -129,6 +133,7 @@ │   │   ├── kernel │   │   │   ├── base.h │   │   │   ├── cpu.h +│   │   │   ├── heap.h │   │   │   ├── iomisc.h │   │   │   ├── mm.h │   │   │   ├── panic.h @@ -151,6 +156,8 @@ │   ├── ke │   │   └── panic.c │   ├── mm +│   │   ├── heap.c +│   │   └── malloc.c │   └── proc │   ├── Makefile │   └── sched.c @@ -161,4 +168,4 @@ ├── qemu.log └── Readme.md -31 directories, 105 files +33 directories, 110 files diff --git a/kaleid/crtlib/memory.c b/kaleid/crtlib/mem.c similarity index 94% rename from kaleid/crtlib/memory.c rename to kaleid/crtlib/mem.c index 16230a2..7d03682 100644 --- a/kaleid/crtlib/memory.c +++ b/kaleid/crtlib/mem.c @@ -23,9 +23,31 @@ //----------------------------------------------------------------------------// #include +#include /* DO NOT compile with strict aliasing on */ +//------------------------------------------// +// Memory allocation // +//------------------------------------------// + +void *malloc(size_t n) +{ + void *ptr; + error_t rc; + + rc = KalAllocMemory(&ptr, n, 0, 0); + __set_errno(rc); + + return ptr; +} + +void free(void *ptr) +{ + error_t rc = KalFreeMemory(ptr); + (void)rc; +} + //------------------------------------------// // memset() family // //------------------------------------------// diff --git a/kaleid/extras/prog.c b/kaleid/extras/prog.c index 77dfbbc..fb467f8 100644 --- a/kaleid/extras/prog.c +++ b/kaleid/extras/prog.c @@ -47,17 +47,15 @@ const char *KalGetProgVersion(void) return __progvers; } -bool KalSetProgVers(const char *vers) +error_t KalSetProgVers(const char *vers) { (void)vers; - __set_errno(ENOSYS); - return false; + return ENOSYS; } -bool KalSetProgName(const char *name) +error_t KalSetProgName(const char *name) { (void)name; - __set_errno(ENOSYS); - return false; + return ENOSYS; } diff --git a/kaleid/include/base/bdefs.h b/kaleid/include/base/bdefs.h index 0229f41..8a33b9e 100644 --- a/kaleid/include/base/bdefs.h +++ b/kaleid/include/base/bdefs.h @@ -45,6 +45,19 @@ //------------------------------------------// +#ifndef _NO_UNITS +#define KB (1UL << 10) +#define MB (1UL << 20) +#define GB (1UL << 30) +#define TB (1UL << 40) +#endif + +#ifndef _ALIGN_UP +#define _ALIGN_UP(x, s) (((x) + (s) - 1) & (~((s) - 1))) +#endif + +//------------------------------------------// + #ifndef __BEGIN_DECLS #ifdef __cpluplus # define __EXTERN_C extern "C" diff --git a/kaleid/include/base/crtlib.h b/kaleid/include/base/crtlib.h index c74dd3a..9aa697d 100644 --- a/kaleid/include/base/crtlib.h +++ b/kaleid/include/base/crtlib.h @@ -66,7 +66,7 @@ extern error_t __errno; #define errno __errno #endif -#define __get_errno(x) error_t x = errno; +#define __get_errno(x) error_t x = errno #define __set_errno(x) (errno = (x)) #else @@ -183,6 +183,11 @@ unsigned long strtoul(const char *restrict, char **restrict, int); //------------------------------------------// +void *malloc(size_t) __attribute__((__malloc__)); +void free(void *); + +//------------------------------------------// + int rand(void); void srand(unsigned int); diff --git a/kaleid/include/base/errno.h b/kaleid/include/base/errno.h index 8b43d46..d063504 100644 --- a/kaleid/include/base/errno.h +++ b/kaleid/include/base/errno.h @@ -28,52 +28,55 @@ //------------------------------------------// // Everything went fine -#define EOK 0 +#define EOK 0 // Operation not permitted -#define EPERM 1 +#define EPERM 1 // No such file or directory -#define ENOENT 2 +#define ENOENT 2 // No such process -#define ESRCH 3 +#define ESRCH 3 // Syscall interrupted (e.g. by signal) -#define EINTR 4 +#define EINTR 4 // I/0 error -#define EIO 5 +#define EIO 5 // No such device or address -#define ENXIO 6 +#define ENXIO 6 // Argument list too long -#define E2BIG 7 +#define E2BIG 7 // Not an executable format -#define ENOEXEC 8 +#define ENOEXEC 8 // Bad file number -#define EBADF 9 +#define EBADF 9 // Try again -#define EAGAIN 11 +#define EAGAIN 11 // Out of memory -#define ENOMEM 12 +#define ENOMEM 12 // Invalid argument -#define EINVAL 22 +#define EINVAL 22 // Functionality not implemented -#define ENOSYS 38 +#define ENOSYS 38 -// Component crashed -#define ECRASH 500 +// Address already in use +#define EADDRINUSE 98 -// System is panicking -#define EPANIC 600 +// Failure (unspecified reason) +#define EFAILED 256 + +// Alignment error +#define EALIGN 257 //------------------------------------------// diff --git a/kaleid/include/extras/malloc.h b/kaleid/include/extras/malloc.h index 4e2d30a..6c478c9 100644 --- a/kaleid/include/extras/malloc.h +++ b/kaleid/include/extras/malloc.h @@ -35,16 +35,34 @@ extern "C" { //------------------------------------------// -// -// ¯\_(ツ)_/¯ -// -#ifndef _STDLIB_H -void *malloc(unsigned long); -void free(void *); -#endif +// Flags for KalAllocMemory +enum +{ + // Return zeroed-out memory + M_ZEROED = 1, -#define KalAllocMemory malloc -#define KalFreeMemory free + // Crash if allocation fails (ENABLED by default in the kernel) + M_FAILCRASH = 2, + + // Do NOT crash if allocation failed (meaningless outside of the kernel) + M_CANFAIL = 4, +}; + +enum +{ + // Default memory allocation alignment (in bytes) + // Asking KalAllocMemory for an alignment of 0 + // will cause it to use this value + M_DEFAULT_ALIGNMENT = alignof(QWORD), + + // Minimal memory allocation alignment (in bytes) + // Asking KalAllocMemory for an nonzero alignment + // lower than this value will cause a EALIGN error + M_MINIMAL_ALIGNMENT = M_DEFAULT_ALIGNMENT +}; + +error_t KalAllocMemory(void **ptr, size_t req, int flags, size_t align); +error_t KalFreeMemory(void *ptr); //------------------------------------------// diff --git a/kaleid/include/extras/prog.h b/kaleid/include/extras/prog.h index 9d7cfa0..3af6461 100644 --- a/kaleid/include/extras/prog.h +++ b/kaleid/include/extras/prog.h @@ -43,8 +43,8 @@ extern const char *__progvers; const char *KalGetProgName(void); const char *KalGetProgVersion(void); -bool KalSetProgVers(const char *); -bool KalSetProgName(const char *); +error_t KalSetProgVers(const char *); +error_t KalSetProgName(const char *); //------------------------------------------// diff --git a/kaleid/include/kernel/base.h b/kaleid/include/kernel/base.h index cb5a160..f951a42 100644 --- a/kaleid/include/kernel/base.h +++ b/kaleid/include/kernel/base.h @@ -45,7 +45,6 @@ typedef struct Processor_t Processor_t; typedef enum ProcState_t ProcState_t; typedef enum TermColor_t TermColor_t; -typedef enum KernelState_t KernelState_t; //------------------------------------------// // Multiprocessor misc. // diff --git a/kaleid/include/kernel/cpu.h b/kaleid/include/kernel/cpu.h index f347d99..ebb5268 100644 --- a/kaleid/include/kernel/cpu.h +++ b/kaleid/include/kernel/cpu.h @@ -22,8 +22,21 @@ // along with OS/K. If not, see . // //----------------------------------------------------------------------------// +#ifndef _KALKERN_BASE_H +#include +#endif + +#ifndef _KALKERN_CPU_H +#define _KALKERN_CPU_H + +//------------------------------------------// + #define cpuid(in, a, b, c, d) asm("cpuid" \ : "=a" (a), "=b" (b), "=c" (c), "=d" (d) \ : "a" (in) \ ); +//------------------------------------------// + +#endif + diff --git a/kaleid/include/kernel/heap.h b/kaleid/include/kernel/heap.h new file mode 100644 index 0000000..9f9729b --- /dev/null +++ b/kaleid/include/kernel/heap.h @@ -0,0 +1,58 @@ +//----------------------------------------------------------------------------// +// GNU GPL OS/K // +// // +// Desc: Memory related functions // +// // +// // +// Copyright © 2018-2019 The OS/K Team // +// // +// This file is part of OS/K. // +// // +// OS/K is free software: you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation, either version 3 of the License, or // +// any later version. // +// // +// OS/K is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY//without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with OS/K. If not, see . // +//----------------------------------------------------------------------------// + +#ifndef _KALKERN_BASE_H +#include +#endif + +#ifndef _KALKERN_MM_H +#define _KALKERN_MM_H + +//------------------------------------------// + +void *GetMemoryMap(void); + +size_t GetMemorySize(void); +size_t GetAvailZoneSize(void *); + +//------------------------------------------// + +#define _HEAP_START (4 * MB) + +void InitHeap(void); + +void LockHeap(void); +void UnlockHeap(void); + +size_t GetHeapSize(void); +size_t GetMaxHeapSize(void); +error_t SetMaxHeapSize(size_t); + +error_t GrowHeap(size_t); +error_t ShrinkHeap(size_t); + +//------------------------------------------// + +#endif + diff --git a/kaleid/include/kernel/iomisc.h b/kaleid/include/kernel/iomisc.h index a07723d..615875d 100644 --- a/kaleid/include/kernel/iomisc.h +++ b/kaleid/include/kernel/iomisc.h @@ -22,7 +22,6 @@ // along with OS/K. If not, see . // //----------------------------------------------------------------------------// - #ifndef _KALKERN_BASE_H #include #endif diff --git a/kaleid/include/kernel/mm.h b/kaleid/include/kernel/mm.h index 95971fe..b015971 100644 --- a/kaleid/include/kernel/mm.h +++ b/kaleid/include/kernel/mm.h @@ -21,3 +21,4 @@ // You should have received a copy of the GNU General Public License // // along with OS/K. If not, see . // //----------------------------------------------------------------------------// + diff --git a/kaleid/kernel/init/init.c b/kaleid/kernel/init/init.c index ef857cf..8fef98b 100644 --- a/kaleid/kernel/init/init.c +++ b/kaleid/kernel/init/init.c @@ -21,13 +21,11 @@ // You should have received a copy of the GNU General Public License // // along with OS/K. If not, see . // //----------------------------------------------------------------------------// + #include #include #include - -extern void testf(void); - // // Entry point of the Kaleid kernel // @@ -39,8 +37,7 @@ noreturn void StartKern(multiboot_info_t *mbInfo, int mbMagic) // Kernel terminals InitTerms(); - // We're out - StartPanic( "We were loaded by : %s\n\n\n" + KernLog( "We were loaded by : %s\n\n" "We get\n" " *mbInfo : %p\n" " mbMagic : %x\n" @@ -56,4 +53,7 @@ noreturn void StartKern(multiboot_info_t *mbInfo, int mbMagic) mbInfo->mmap_addr, mbInfo->mmap_length ); + + // Get out + CrashSystem(); } diff --git a/kaleid/kernel/io/term.c b/kaleid/kernel/io/term.c index 618919b..ce34545 100644 --- a/kaleid/kernel/io/term.c +++ b/kaleid/kernel/io/term.c @@ -28,7 +28,7 @@ extern void VGA_Init(void); extern Terminal_t VGA_Terminal; // -// Initialize standard output +// Initializes standard output // void InitTerms(void) { @@ -43,7 +43,7 @@ void InitTerms(void) } // -// Fill terminal with spaces +// Fills terminal with spaces // error_t ClearTerm(Terminal_t *term) { @@ -60,7 +60,7 @@ error_t ClearTerm(Terminal_t *term) } // -// Change the color code +// Changes the color code // error_t ChTermColor(Terminal_t *term, TermColor_t fgColor, TermColor_t bgColor) { @@ -81,7 +81,7 @@ error_t ChTermColor(Terminal_t *term, TermColor_t fgColor, TermColor_t bgColor) } // -// Write a single character on the terminal +// Writes a single character on the terminal // error_t PutOnTerm(Terminal_t *term, char ch) { @@ -98,7 +98,7 @@ error_t PutOnTerm(Terminal_t *term, char ch) } // -// Print string on terminal +// Prints string on terminal // error_t PrintOnTerm(Terminal_t *term, const char *str) { @@ -117,7 +117,7 @@ error_t PrintOnTerm(Terminal_t *term, const char *str) } // -// Print formatted string on standard output +// Prints formatted string on standard output // Prints at most KLOG_MAX_BUFSIZE characters // error_t KernLog(const char *fmt, ...) @@ -130,12 +130,12 @@ error_t KernLog(const char *fmt, ...) vsnprintf(logbuf, KLOG_MAX_BUFSIZE, fmt, ap); va_end(ap); - return PrintOnTerm(stdOut, logbuf); + return PrintOnTerm(GetStdOut(), logbuf); } #ifndef _NO_DEBUG // -// Print formatted string on debug output +// Prints formatted string on debug output // Prints at most KLOG_MAX_BUFSIZE characters // error_t DebugLog(const char *fmt, ...) @@ -148,7 +148,7 @@ error_t DebugLog(const char *fmt, ...) vsnprintf(logbuf, KLOG_MAX_BUFSIZE, fmt, ap); va_end(ap); - return PrintOnTerm(stdDbg, logbuf); + return PrintOnTerm(GetStdDbg(), logbuf); } #endif diff --git a/kaleid/kernel/io/vga.c b/kaleid/kernel/io/vga.c index 9a75cdb..de00c35 100644 --- a/kaleid/kernel/io/vga.c +++ b/kaleid/kernel/io/vga.c @@ -37,7 +37,7 @@ #define VGA_ComputeEntry(ch, cl) (((ushort)(ch)) | (ushort)(cl) << 8) // -// Clear terminal +// Clears terminal // error_t VGA_ClearTermUnlocked(Terminal_t *term) { @@ -55,7 +55,7 @@ error_t VGA_ClearTermUnlocked(Terminal_t *term) } // -// Write a single character on the terminal +// Writes a single character on the terminal // error_t VGA_PutOnTermUnlocked(Terminal_t *term, char ch) { @@ -106,7 +106,7 @@ error_t VGA_PutOnTermUnlocked(Terminal_t *term, char ch) } // -// Print string on terminal +// Prints string on terminal // error_t VGA_PrintOnTermUnlocked(Terminal_t *term, const char *str) { diff --git a/kaleid/kernel/ke/panic.c b/kaleid/kernel/ke/panic.c index c799d19..def362c 100644 --- a/kaleid/kernel/ke/panic.c +++ b/kaleid/kernel/ke/panic.c @@ -37,7 +37,7 @@ noreturn void __assert_handler(const char *msg, (void)file; (void)line; (void)func; - StartPanic("cpu%d: In function '%s', from %s line %s - assert() failed: '%s'", + StartPanic("cpu%d: In function '%s', from %s line %d - assert() failed: '%s'", _GetCurCPU(), func, file, line, msg); } @@ -80,7 +80,9 @@ noreturn void StartPanic(const char *fmt, ...) // noreturn void CrashSystem(void) { - DisableIRQs(); - HaltCPU(); + while (1) { + DisableIRQs(); + HaltCPU(); + } } diff --git a/kaleid/kernel/mm/.placeholder b/kaleid/kernel/mm/.placeholder deleted file mode 100644 index e69de29..0000000 diff --git a/kaleid/kernel/mm/heap.c b/kaleid/kernel/mm/heap.c new file mode 100644 index 0000000..dd3d18c --- /dev/null +++ b/kaleid/kernel/mm/heap.c @@ -0,0 +1,129 @@ +//----------------------------------------------------------------------------// +// GNU GPL OS/K // +// // +// Desc: Early and very dumb heap managment // +// // +// // +// Copyright © 2018-2019 The OS/K Team // +// // +// This file is part of OS/K. // +// // +// OS/K is free software: you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation, either version 3 of the License, or // +// any later version. // +// // +// OS/K is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY//without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with OS/K. If not, see . // +//----------------------------------------------------------------------------// + +#include + +// Least address out of the heap +static void *_heap_end; + +// Maximal value of the heap +static size_t _heap_max; + +// Lock NOT used internally, but used by KalAllocMemory() & co. +static Lock_t _heap_lock = INITLOCK(KLOCK_SPINLOCK); + +// Debugging stub +size_t GetAvailZoneSize(void *x) { (void)x; return 8 * MB; } + +// +// Initializes heap managment +// +void InitHeap(void) +{ + assert(_heap_end == NULL); + _heap_end = (void *)_HEAP_START; + _heap_max = lmin(8 * MB, GetAvailZoneSize((void *)_HEAP_START)); +} + +// +// Aquires control of the heap's lock +// +void LockHeap(void) +{ + AquireLock(&_heap_lock); +} + +// +// Releases control of the heap's lock +// +void UnlockHeap(void) +{ + ReleaseLock(&_heap_lock); +} + +// +// Returns the heap's current size +// +size_t GetHeapSize(void) +{ + return (size_t)_heap_end - _HEAP_START; +} + +// +// Returns the heap's maximum size +// +size_t GetMaxHeapSize(void) +{ + return _heap_max; +} + +// +// Changes the heap's maximal size +// +error_t SetMaxHeapSize(size_t new) +{ + if (new > GetAvailZoneSize((void *)_HEAP_START)) { + return ENOMEM; + } + + if (new < (size_t)_heap_end - _HEAP_START) { + return EADDRINUSE; + } + + _heap_max = new; + + return EOK; +} + +// +// Extends the heap's size +// +error_t GrowHeap(size_t req) +{ + assert(req % alignof(QWORD)); + + if ((size_t)_heap_end + req > _HEAP_START + _heap_max) { + return ENOMEM; + } + + _heap_end += req; + + return EOK; +} + +// +// Reduces the heap's size +// +error_t ShrinkHeap(size_t req) +{ + assert(req % alignof(QWORD)); + + if (req > (size_t)_heap_end - _HEAP_START) { + return EADDRINUSE; + } + + _heap_end -= req; + + return EOK; +} diff --git a/kaleid/kernel/mm/malloc.c b/kaleid/kernel/mm/malloc.c new file mode 100644 index 0000000..e46e94c --- /dev/null +++ b/kaleid/kernel/mm/malloc.c @@ -0,0 +1,70 @@ +//----------------------------------------------------------------------------// +// GNU GPL OS/K // +// // +// Desc: Early and very dumb memory managment // +// // +// // +// Copyright © 2018-2019 The OS/K Team // +// // +// This file is part of OS/K. // +// // +// OS/K is free software: you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation, either version 3 of the License, or // +// any later version. // +// // +// OS/K is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY//without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with OS/K. If not, see . // +//----------------------------------------------------------------------------// + +#include +#include + +error_t KalAllocMemory(void **ptr, size_t req, int flags, size_t align) +{ + error_t rc; + size_t brk; + + if (align == 0) align = M_DEFAULT_ALIGNMENT; + + if (align < M_MINIMAL_ALIGNMENT) { + return EALIGN; + } + + LockHeap(); + + brk = _HEAP_START + GetHeapSize(); + req = _ALIGN_UP(req + brk, align) - brk; + + rc = GrowHeap(req); + + UnlockHeap(); + + if (rc) { + if ((flags & M_CANFAIL) == 0) + return rc; + StartPanic("Out of memory"); + } + + if (flags & M_ZEROED) { + memzero(*ptr, req); + } + + *ptr = (void *)brk; + + return rc; +} + +// +// Frees allocated memory +// +error_t KalFreeMemory(void *ptr) +{ + (void)ptr; +} +