Implement the CRT heap and use that in the kernel
authorcoderain <coderain@sdf.org>
Sun, 22 Oct 2017 14:31:10 +0000 (16:31 +0200)
committercoderain <coderain@sdf.org>
Sun, 22 Oct 2017 14:31:10 +0000 (16:31 +0200)
crt/include/malloc.h [new file with mode: 0644]
crt/include/stdlib.h
crt/src/malloc.c [new file with mode: 0644]
kernel/include/heap.h
kernel/src/heap.c

diff --git a/crt/include/malloc.h b/crt/include/malloc.h
new file mode 100644 (file)
index 0000000..b3001e8
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * malloc.h
+ *
+ * Copyright (C) 2017 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _MALLOC_H_
+#define _MALLOC_H_
+
+#define __CRT_HEAP_FLAG_READY    (1 << 0)
+#define __CRT_HEAP_FLAG_ZEROFILL (1 << 1)
+#define __CRT_HEAP_FLAG_BESTFIT  (1 << 2)
+
+enum
+{
+    __CRT_HEAP_CORRUPTED,
+    __CRT_HEAP_DOUBLE_FREE,
+    __CRT_HEAP_BAD_POINTER,
+    __CRT_HEAP_OUT_OF_MEMORY,
+};
+
+typedef struct
+{
+    uint32_t magic;
+    void *base;
+    size_t size;
+    uint32_t flags;
+    uintptr_t next_offset;
+    void *mutex;
+    void (*lock_mutex_proc)(void*);
+    void (*unlock_mutex_proc)(void*);
+    void (*problem)(int);
+} __crt_heap_t;
+
+void *malloc(size_t size);
+void free(void *ptr);
+void *calloc(size_t nmemb, size_t size);
+void *realloc(void *ptr, size_t size);
+
+#endif
index e1310ba87d341abeb3b954839e2c3ffebd720da9..6a6df69166c6654d08e4665cb3961dca3da59304 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <stddef.h>
 #include <stdint.h>
+#include <malloc.h>
 
 char *itoa(int value, char *str, int base);
 int atoi(char *str);
@@ -29,11 +30,6 @@ int strtol(const char *str, char **endptr, int base);
 unsigned long strtoul(const char *str, char **endptr, int base);
 unsigned long long strtoull(const char *str, char **endptr, int base);
 
-void *malloc(size_t size);
-void free(void *ptr);
-void *calloc(size_t nmemb, size_t size);
-void *realloc(void *ptr, size_t size);
-
 void qsort(void *base, size_t nmemb, size_t size, int (*compare)(const void*, const void*));
 void *bsearch(const void *key, const void *base, size_t nmemb, size_t size, int (*compare)(const void*, const void*));
 
@@ -42,4 +38,10 @@ void *bsearch(const void *key, const void *base, size_t nmemb, size_t size, int
 int atexit(void (*function)(void));
 void __attribute__((__noreturn__)) exit(int status);
 
+typedef uint32_t pid_t;
+
+pid_t getpid(void);
+pid_t getppid(void);
+pid_t fork(void);
+
 #endif
diff --git a/crt/src/malloc.c b/crt/src/malloc.c
new file mode 100644 (file)
index 0000000..40d5cb4
--- /dev/null
@@ -0,0 +1,345 @@
+/*
+ * heap.c
+ *
+ * Copyright (C) 2017 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <monolithium.h>
+
+#define ALLOCATED (1 << 0)
+
+typedef struct
+{
+    uint32_t magic;
+    uint32_t flags;
+    size_t size;
+} heap_header_t;
+
+__crt_heap_t *__crt_default_heap;
+
+static void __crt_heap_coalesce(__crt_heap_t *heap)
+{
+    heap_header_t *ptr = (heap_header_t*)heap->base;
+    heap_header_t *previous = NULL;
+
+    while ((uintptr_t)ptr >= (uintptr_t)heap->base && (uintptr_t)ptr < (uintptr_t)heap->base + heap->size)
+    {
+        heap_header_t *next = (heap_header_t*)((uintptr_t)ptr + sizeof(heap_header_t) + ptr->size);
+
+        if (previous && !(previous->flags & ALLOCATED) && !(ptr->flags & ALLOCATED))
+        {
+            previous->size += ptr->size + sizeof(heap_header_t);
+        }
+        else
+        {
+            previous = ptr;
+        }
+
+        ptr = next;
+    }
+}
+
+void *__crt_heap_realloc(__crt_heap_t *heap, void *ptr, size_t alignment, size_t size)
+{
+    if (!alignment || (alignment & (alignment - 1))) return NULL;
+
+    heap->lock_mutex_proc(heap->mutex);
+
+    if (!(heap->flags & __CRT_HEAP_FLAG_READY))
+    {
+        heap_header_t *header = (heap_header_t*)heap->base;
+        header->magic = heap->magic;
+        header->flags = 0;
+        header->size = heap->size - sizeof(heap_header_t);
+
+        heap->flags |= __CRT_HEAP_FLAG_READY;
+    }
+
+    if (!size)
+    {
+        if (ptr)
+        {
+            heap_header_t *header = (heap_header_t*)((uintptr_t)ptr - sizeof(heap_header_t));
+
+            if (header->flags & ALLOCATED)
+            {
+                header->flags &= ~ALLOCATED;
+                __crt_heap_coalesce(heap);
+            }
+            else
+            {
+                heap->problem(__CRT_HEAP_DOUBLE_FREE);
+            }
+        }
+
+        heap->unlock_mutex_proc(heap->mutex);
+        return NULL;
+    }
+
+    heap_header_t *source_block = NULL;
+
+    if (ptr)
+    {
+        heap_header_t *header = (heap_header_t*)((uintptr_t)ptr - sizeof(heap_header_t));
+
+        if (!(header->flags & ALLOCATED) || header->magic != heap->magic)
+        {
+            heap->problem(__CRT_HEAP_BAD_POINTER);
+            heap->unlock_mutex_proc(heap->mutex);
+            return NULL;
+        }
+
+        if (size > header->size)
+        {
+             heap_header_t *next = (heap_header_t*)((uintptr_t)ptr + header->size);
+
+             if (!(next->flags & ALLOCATED) && (header->size + next->size + sizeof(heap_header_t)) >= size)
+             {
+                 header->size += next->size + sizeof(heap_header_t);
+                 if (heap->flags & __CRT_HEAP_FLAG_ZEROFILL) memset(next, 0, size - header->size - size);
+             }
+             else
+             {
+                 source_block = header;
+             }
+        }
+
+        if (size < (header->size - sizeof(heap_header_t)))
+        {
+            heap_header_t *new_block = (heap_header_t*)((uintptr_t)ptr + size);
+            new_block->magic = heap->magic;
+            new_block->flags = 0;
+            new_block->size = header->size - size - sizeof(heap_header_t);
+            header->size = size;
+            __crt_heap_coalesce(heap);
+        }
+
+        if (!source_block)
+        {
+            heap->unlock_mutex_proc(heap->mutex);
+            return ptr;
+        }
+    }
+
+    heap_header_t *hole = NULL;
+
+    if (heap->flags & __CRT_HEAP_FLAG_BESTFIT)
+    {
+        heap_header_t *current = (heap_header_t*)heap->base;
+        size_t minimum_size;
+
+        while ((uintptr_t)current < (uintptr_t)heap->base + heap->size)
+        {
+            if (current->magic != heap->magic)
+            {
+                heap->problem(__CRT_HEAP_CORRUPTED);
+                heap->unlock_mutex_proc(heap->mutex);
+                return NULL;
+            }
+
+            if (!(current->flags & ALLOCATED))
+            {
+                uintptr_t current_start = (uintptr_t)current + sizeof(heap_header_t);
+                uintptr_t aligned_start = (current_start + alignment - 1) & ~(alignment - 1);
+                size_t padding = aligned_start - current_start;
+
+                if (current->size > padding)
+                {
+                    size_t adjusted_size = current->size - padding;
+
+                    if (adjusted_size >= size && (!hole || adjusted_size < minimum_size))
+                    {
+                        hole = current;
+                        minimum_size = adjusted_size;
+                    }
+                }
+            }
+
+            heap_header_t *next = (heap_header_t*)((uintptr_t)current + sizeof(heap_header_t) + current->size);
+
+            if ((uintptr_t)next <= (uintptr_t)current)
+            {
+                heap->problem(__CRT_HEAP_CORRUPTED);
+                heap->unlock_mutex_proc(heap->mutex);
+                return NULL;
+            }
+
+            current = next;
+        }
+    }
+    else
+    {
+        uintptr_t offset = heap->next_offset;
+        int cycles = 0;
+
+        do
+        {
+            heap_header_t *current = (heap_header_t*)(heap->base + offset);
+
+            if (current->magic != heap->magic)
+            {
+                heap->problem(__CRT_HEAP_CORRUPTED);
+                heap->unlock_mutex_proc(heap->mutex);
+                return NULL;
+            }
+
+            if (!(current->flags & ALLOCATED))
+            {
+                uintptr_t current_start = (uintptr_t)current + sizeof(heap_header_t);
+                uintptr_t aligned_start = (current_start + alignment - 1) & ~(alignment - 1);
+                size_t padding = aligned_start - current_start;
+
+                if (current->size >= padding && (current->size - padding) >= size)
+                {
+                    hole = current;
+                    break;
+                }
+            }
+
+            offset += sizeof(heap_header_t) + current->size;
+            if (offset > heap->size)
+            {
+                offset = 0;
+                if (++cycles > 1)
+                {
+                    heap->problem(__CRT_HEAP_CORRUPTED);
+                    heap->unlock_mutex_proc(heap->mutex);
+                    return NULL;
+                }
+            }
+        }
+        while (offset != heap->next_offset);
+
+        heap->next_offset = offset;
+    }
+
+    if (!hole)
+    {
+        heap->problem(__CRT_HEAP_OUT_OF_MEMORY);
+        heap->unlock_mutex_proc(heap->mutex);
+        return NULL;
+    }
+
+    int coalesce = 0;
+    uintptr_t start_address = (uintptr_t)hole + sizeof(heap_header_t);
+    uintptr_t aligned_start = (start_address + alignment - 1) & ~(alignment - 1);
+    size_t padding = aligned_start - start_address;
+
+    if (padding > sizeof(heap_header_t))
+    {
+        heap_header_t *new_block = (heap_header_t*)(aligned_start - sizeof(heap_header_t));
+        new_block->magic = heap->magic;
+        new_block->flags = 0;
+        new_block->size = hole->size - padding;
+        hole->size -= padding + sizeof(heap_header_t);
+
+        hole = new_block;
+        coalesce = 1;
+    }
+    else if (padding)
+    {
+        heap_header_t *previous = (heap_header_t*)heap->base;
+
+        while ((uintptr_t)previous < (uintptr_t)heap->base + heap->size)
+        {
+            heap_header_t *next = (heap_header_t*)((uintptr_t)previous + sizeof(heap_header_t) + previous->size);
+            if (next == hole) break;
+
+            if ((uintptr_t)next <= (uintptr_t)previous)
+            {
+                heap->problem(__CRT_HEAP_CORRUPTED);
+                heap->unlock_mutex_proc(heap->mutex);
+                return NULL;
+            }
+
+            previous = next;
+        }
+
+        if ((uintptr_t)previous < (uintptr_t)heap->base
+            || (uintptr_t)previous >= (uintptr_t)heap->base + heap->size
+            || previous->magic != heap->magic)
+        {
+            heap->problem(__CRT_HEAP_CORRUPTED);
+            heap->unlock_mutex_proc(heap->mutex);
+            return NULL;
+        }
+
+        previous->size += padding;
+
+        heap_header_t *new_block = (heap_header_t*)(aligned_start - sizeof(heap_header_t));
+        memmove(new_block, hole, sizeof(heap_header_t));
+        hole = new_block;
+        hole->size -= padding;
+    }
+
+    hole->flags |= ALLOCATED;
+
+    if (hole->size > sizeof(heap_header_t) && size < (hole->size - sizeof(heap_header_t)))
+    {
+        heap_header_t *new_block = (heap_header_t*)((uintptr_t)hole + size + sizeof(heap_header_t));
+        new_block->magic = heap->magic;
+        new_block->flags = 0;
+        new_block->size = hole->size - size - sizeof(heap_header_t);
+        hole->size = size;
+        coalesce = 1;
+    }
+
+    void *destination = (void*)((uintptr_t)hole + sizeof(heap_header_t));
+    if (heap->flags & __CRT_HEAP_FLAG_ZEROFILL) memset(destination, 0, size);
+
+    if (source_block)
+    {
+        void *source = (void*)((uintptr_t)source_block + sizeof(heap_header_t));
+        memcpy(destination, source, source_block->size);
+        source_block->flags &= ~ALLOCATED;
+        coalesce = 1;
+    }
+
+    if (coalesce) __crt_heap_coalesce(heap);
+    heap->unlock_mutex_proc(heap->mutex);
+    return destination;
+}
+
+void *aligned_alloc(size_t alignment, size_t size)
+{
+    return __crt_heap_realloc(__crt_default_heap, NULL, alignment, size);
+}
+
+void *realloc(void *ptr, size_t size)
+{
+    return __crt_heap_realloc(__crt_default_heap, ptr, 1, size);
+}
+
+void *malloc(size_t size)
+{
+    return __crt_heap_realloc(__crt_default_heap, NULL, 1, size);
+}
+
+void free(void *ptr)
+{
+    __crt_heap_realloc(__crt_default_heap, ptr, 1, 0);
+}
+
+void *calloc(size_t nmemb, size_t size)
+{
+    void *ptr = malloc(nmemb * size);
+    if (!ptr) return NULL;
+
+    memset(ptr, 0, nmemb * size);
+    return ptr;
+}
index 669bc4ee768e59771d307492803192c27e4699e1..533c9f93a86c07100d0d274c17a8f41c625ceb22 100644 (file)
@@ -21,6 +21,8 @@
 #define _HEAP_H_
 
 #include <common.h>
+#include <sync.h>
+#include <crt/include/malloc.h>
 
 #define SYSTEM_HEAP_START    KERNEL_POOL_START
 #define SYSTEM_HEAP_END      (EVICTABLE_HEAP_START - 1)
@@ -42,11 +44,8 @@ typedef struct _heap_header_t
 
 typedef struct
 {
-    uintptr_t start;
-    uintptr_t end;
-    uintptr_t max_end;
-    dword_t flags;
-    dword_t magic;
+    __crt_heap_t crt;
+    lock_t lock;
 } heap_t;
 
 extern heap_t system_heap;
@@ -57,9 +56,6 @@ void heap_free(heap_t *heap, void *ptr);
 void *heap_realloc(heap_t *heap, void *ptr, uintptr_t size);
 dword_t heap_create(heap_t *heap, uintptr_t start, uintptr_t end, dword_t flags, dword_t magic);
 dword_t heap_destroy(heap_t *heap);
-void *malloc(uintptr_t size);
-void free(void *ptr);
-void *realloc(void *ptr, uintptr_t size);
 void heap_init(void);
 
 #endif
index 7717779968de3a708d4f58abf7243392653eed9c..c6d2414b4fbf2d999efa6533f1068452ad1eea7d 100644 (file)
 #include <exception.h>
 #include <memory.h>
 
+void *__crt_heap_realloc(__crt_heap_t *heap, void *ptr, size_t alignment, size_t size);
+extern __crt_heap_t *__crt_default_heap;
+
 heap_t system_heap;
 heap_t evictable_heap;
 
-static inline void validate_heap_header(heap_t *heap, heap_header_t *ptr)
-{
-    ASSERT(((uintptr_t)ptr >= heap->start) && ((uintptr_t)ptr < heap->end));
-
-    uintptr_t last_addr = (uintptr_t)ptr + sizeof(heap_header_t) + ptr->length - 1;
-    ASSERT((last_addr >= heap->start) && (last_addr < heap->end) && ((uintptr_t)ptr < last_addr) && heap->magic == ptr->magic);
-}
-
-static void *heap_expand(heap_t *heap, dword_t size)
+static void heap_problem(int problem)
 {
-    void *address = (void*)heap->end;
-    dword_t new_end = heap->end + size;
-    if (new_end >= heap->max_end) return NULL;
-    heap->end = new_end;
-    return address;
-}
-
-void *heap_alloc(heap_t *heap, uintptr_t size)
-{
-    heap_header_t *ptr = (heap_header_t*)heap->start;
-
-    while ((uintptr_t)ptr < heap->end)
+    switch (problem)
     {
-        validate_heap_header(heap, ptr);
-
-        if (ptr->free && ptr->length >= size)
-        {
-            if ((ptr->length - size) > sizeof(heap_header_t))
-            {
-                heap_header_t *new_header = (heap_header_t*)((uintptr_t)ptr + sizeof(heap_header_t) + size);
-                new_header->free = TRUE;
-                new_header->length = (ptr->length - size) - sizeof(heap_header_t);
-                new_header->magic = heap->magic;
-                ptr->length = size;
-            }
-
-            ptr->free = FALSE;
-            void *pointer = (void*)((uintptr_t)ptr + sizeof(heap_header_t));
-            if (heap->flags & HEAP_ZEROFILL) memset(pointer, 0, size);
-            return pointer;
-        }
-
-        ptr = (heap_header_t*)((uintptr_t)ptr + ptr->length + sizeof(heap_header_t));
-    }
-
-    heap_header_t *new_header = heap_expand(heap, size + sizeof(heap_header_t));
-    if (new_header == NULL) return NULL;
-
-    new_header->length = size;
-    new_header->free = FALSE;
-    new_header->magic = heap->magic;
-
-    void *pointer = (void*)((uintptr_t)new_header + sizeof(heap_header_t));
-    if (heap->flags & HEAP_ZEROFILL) memset(pointer, 0, size);
-    return pointer;
-}
+    case __CRT_HEAP_CORRUPTED:
+        KERNEL_CRASH("Heap corrupted");
 
-void heap_free(heap_t *heap, void *ptr)
-{
-    heap_header_t *header = (heap_header_t*)((uintptr_t)ptr - sizeof(heap_header_t));
-    validate_heap_header(heap, header);
-    header->free = TRUE;
-
-    heap_header_t *prev = (heap_header_t*)heap->start;
-    heap_header_t *current = (heap_header_t*)((uintptr_t)prev + prev->length + sizeof(heap_header_t));
-    validate_heap_header(heap, prev);
+    case __CRT_HEAP_DOUBLE_FREE:
+        KERNEL_CRASH("Attempt to free an already released region");
 
-    while ((uintptr_t)current < heap->end)
-    {
-        validate_heap_header(heap, current);
-
-        if (prev->free && current->free)
-        {
-            prev->length += sizeof(heap_header_t) + current->length;
-        }
-        else
-        {
-            prev = current;
-        }
-
-        current = (heap_header_t*)((uintptr_t)prev + prev->length + sizeof(heap_header_t));
+    case __CRT_HEAP_BAD_POINTER:
+        KERNEL_CRASH("Bad pointer passed to heap function");
     }
 }
 
 void *heap_realloc(heap_t *heap, void *ptr, uintptr_t size)
 {
-    if (size == 0)
-    {
-        heap_free(heap, ptr);
-        return NULL;
-    }
-
-    if (ptr == NULL)
-    {
-        return heap_alloc(heap, size);
-    }
-
-    heap_header_t *header = (heap_header_t*)((uintptr_t)ptr - sizeof(heap_header_t));
-    validate_heap_header(heap, header);
-    ASSERT(!header->free);
-
-    if (size > header->length)
-    {
-        heap_header_t *next = (heap_header_t*)((uintptr_t)header + header->length + sizeof(heap_header_t));
-
-        if ((uintptr_t)next == heap->end)
-        {
-            if (heap_expand(heap, size - header->length))
-            {
-                header->length = size;
-                return ptr;
-            }
-            else
-            {
-                return NULL;
-            }
-        }
-
-        validate_heap_header(heap, next);
-        dword_t max_size = header->length + next->length + sizeof(heap_header_t);
-
-        if (next->free && size < max_size)
-        {
-            if ((max_size - size) > sizeof(heap_header_t))
-            {
-                header->length = size;
-                heap_header_t *new_free_block = (heap_header_t*)((uintptr_t)header + header->length + sizeof(heap_header_t));
-                new_free_block->free = TRUE;
-                new_free_block->length = (max_size - size) - sizeof(heap_header_t);
-                new_free_block->magic = heap->magic;
-            }
-            else
-            {
-                header->length = max_size;
-            }
-
-            return ptr;
-        }
-        else
-        {
-            void *new_block = heap_alloc(heap, size);
-            if (new_block)
-            {
-                memcpy(new_block, ptr, header->length);
-                free(ptr);
-            }
-
-            return new_block;
-        }
-    }
-    else if (size == header->length)
-    {
-        return ptr;
-    }
-    else if (size < header->length)
-    {
-        if ((header->length - size) > sizeof(heap_header_t))
-        {
-            dword_t capacity = header->length;
-            header->length = size;
-            heap_header_t *new_free_block = (heap_header_t*)((uintptr_t)header + header->length + sizeof(heap_header_t));
-            new_free_block->free = TRUE;
-            new_free_block->length = (capacity - size) - sizeof(heap_header_t);
-            new_free_block->magic = heap->magic;
-        }
-
-        return ptr;
-    }
-
-    return NULL;
-}
-
-void *malloc(uintptr_t size)
-{
-    return heap_alloc(&system_heap, size);
+    return __crt_heap_realloc(&heap->crt, ptr, 1, size);
 }
 
-void free(void *ptr)
+void *heap_alloc(heap_t *heap, uintptr_t size)
 {
-    heap_free(&system_heap, ptr);
+    return __crt_heap_realloc(&heap->crt, NULL, 1, size);
 }
 
-void *realloc(void *ptr, uintptr_t size)
+void heap_free(heap_t *heap, void *ptr)
 {
-    return heap_realloc(&system_heap, ptr, size);
+    __crt_heap_realloc(&heap->crt, ptr, 1, 0);
 }
 
 dword_t heap_create(heap_t *heap, uintptr_t start, uintptr_t end, dword_t flags, dword_t magic)
@@ -219,23 +65,31 @@ dword_t heap_create(heap_t *heap, uintptr_t start, uintptr_t end, dword_t flags,
 
     ASSERT(start < end);
 
-    heap->start = heap->end = start;
-    heap->max_end = end;
-    heap->flags = flags;
-    heap->magic = magic;
+    heap->crt.magic = magic;
+    heap->crt.base = (void*)start;
+    heap->crt.size = end - start;
+    heap->crt.next_offset = 0;
+    heap->crt.flags = 0;
+    heap->crt.mutex = (void*)&heap->lock;
+    heap->crt.problem = heap_problem;
+    heap->crt.lock_mutex_proc = (void (*)(void*))&acquire_lock;
+    heap->crt.unlock_mutex_proc = (void (*)(void*))&release_lock;
+    heap->lock = 0;
+
+    if (flags & HEAP_ZEROFILL) heap->crt.flags |= __CRT_HEAP_FLAG_ZEROFILL;
 
     dword_t block_flags = MEMORY_BLOCK_ACCESSIBLE | MEMORY_BLOCK_WRITABLE;
-    if (heap->flags & HEAP_EVICTABLE) block_flags |= MEMORY_BLOCK_EVICTABLE;
+    if (flags & HEAP_EVICTABLE) block_flags |= MEMORY_BLOCK_EVICTABLE;
 
-    void *address = alloc_pool((void*)heap->start, heap->max_end - heap->start, block_flags);
-    ASSERT(address != NULL);
+    void *address = alloc_pool(heap->crt.base, heap->crt.size, block_flags);
+    ASSERT(address == heap->crt.base);
 
     return ERR_SUCCESS;
 }
 
 dword_t heap_destroy(heap_t *heap)
 {
-    free_pool((void*)heap->start);
+    free_pool(heap->crt.base);
     return ERR_SUCCESS;
 }
 
@@ -243,4 +97,6 @@ void heap_init(void)
 {
     heap_create(&system_heap, SYSTEM_HEAP_START, SYSTEM_HEAP_END, 0, SYSTEM_HEAP_MAGIC);
     heap_create(&evictable_heap, EVICTABLE_HEAP_START, EVICTABLE_HEAP_END, HEAP_EVICTABLE, EVICTABLE_HEAP_MAGIC);
+
+    __crt_default_heap = &system_heap.crt;
 }