From 01665d725a200c3c51bcd834cc8324ec057286c4 Mon Sep 17 00:00:00 2001 From: Alexis211 Date: Tue, 13 Oct 2009 18:32:26 +0200 Subject: Heap is now in a separate class, Heap. --- Source/Kernel/Core/kmain.wtf.cpp | 3 +- Source/Kernel/Makefile | 2 + Source/Kernel/Melon.ke | Bin 609187 -> 614224 bytes Source/Kernel/MemoryManager/Heap-index.class.cpp | 51 +++++ Source/Kernel/MemoryManager/Heap.class.cpp | 195 ++++++++++++++++++ Source/Kernel/MemoryManager/Heap.class.h | 61 ++++++ Source/Kernel/MemoryManager/Mem.ns.cpp | 240 ++--------------------- Source/Kernel/MemoryManager/Mem.ns.h | 25 +-- Source/Kernel/Shell/KernelShell-sys.class.cpp | 2 +- 9 files changed, 332 insertions(+), 247 deletions(-) create mode 100644 Source/Kernel/MemoryManager/Heap-index.class.cpp create mode 100644 Source/Kernel/MemoryManager/Heap.class.cpp create mode 100644 Source/Kernel/MemoryManager/Heap.class.h (limited to 'Source') diff --git a/Source/Kernel/Core/kmain.wtf.cpp b/Source/Kernel/Core/kmain.wtf.cpp index 8b6a0de..c7b47e1 100644 --- a/Source/Kernel/Core/kmain.wtf.cpp +++ b/Source/Kernel/Core/kmain.wtf.cpp @@ -80,6 +80,7 @@ u32int logoAnimation(void* p) { } Task::currThread()->sleep(20); } + delete wat; return 0; } @@ -134,7 +135,7 @@ void kmain(multiboot_info_t* mbd, u32int magic) { PROCESSING(kvt, "Creating kernel heap..."); Mem::createHeap(); OK(kvt); INFO(kvt); *kvt << "Free frames : " << (s32int)PhysMem::free() << "/" << (s32int)PhysMem::total() << "\n"; - + PROCESSING(kvt,"Initializing PIT..."); Dev::registerDevice(new Timer()); OK(kvt); diff --git a/Source/Kernel/Makefile b/Source/Kernel/Makefile index 06b4d47..b28f487 100644 --- a/Source/Kernel/Makefile +++ b/Source/Kernel/Makefile @@ -17,6 +17,8 @@ Objects = Core/loader.wtf.o \ Core/CMem.ns.o \ Core/Log.ns.o \ MemoryManager/Mem.ns.o \ + MemoryManager/Heap.class.o \ + MemoryManager/Heap-index.class.o \ MemoryManager/PhysMem.ns.o \ MemoryManager/GDT.wtf.o \ MemoryManager/GDT.ns.o \ diff --git a/Source/Kernel/Melon.ke b/Source/Kernel/Melon.ke index 61c87df..c8b784a 100755 Binary files a/Source/Kernel/Melon.ke and b/Source/Kernel/Melon.ke differ diff --git a/Source/Kernel/MemoryManager/Heap-index.class.cpp b/Source/Kernel/MemoryManager/Heap-index.class.cpp new file mode 100644 index 0000000..3280736 --- /dev/null +++ b/Source/Kernel/MemoryManager/Heap-index.class.cpp @@ -0,0 +1,51 @@ +#include "Heap.class.h" + +/* + * Implementation of the functions for managing heap index + */ + +void Heap::insertIntoIndex(heap_header_t *e) { + //If index is full, return + if ((m_index.size * sizeof(heap_header_t*) + (u32int)m_index.data) >= m_start) return; + + u32int iterator = 0; + while (iterator < m_index.size && m_index.data[iterator]->size < e->size) { + if (m_index.data[iterator] == e) return; + iterator++; + } + if (iterator == m_index.size) { + m_index.data[m_index.size++] = e; + } else { + u32int pos = iterator; + iterator = m_index.size; + while (iterator > pos) { + m_index.data[iterator] = m_index.data[iterator - 1]; + iterator--; + } + m_index.size++; + m_index.data[pos] = e; + } +} + +u32int Heap::findIndexEntry(heap_header_t *e) { + for (u32int i = 0; i < m_index.size; i++) { + if (m_index.data[i] == e) + return i; + } + return (u32int) - 1; +} + +void Heap::removeFromIndex(u32int idx) { + m_index.size--; + while (idx < m_index.size) { + m_index.data[idx] = m_index.data[idx + 1]; + idx++; + } +} + +void Heap::removeFromIndex(heap_header_t *e) { + u32int i = findIndexEntry(e); + if (i != (u32int) - 1) { + removeFromIndex(i); + } +} diff --git a/Source/Kernel/MemoryManager/Heap.class.cpp b/Source/Kernel/MemoryManager/Heap.class.cpp new file mode 100644 index 0000000..f5bbe0a --- /dev/null +++ b/Source/Kernel/MemoryManager/Heap.class.cpp @@ -0,0 +1,195 @@ +#include "Heap.class.h" +#include + +Heap::Heap() { + m_usable = false; + m_index.data = 0; + m_index.size = 0; +} + +Heap::~Heap() { + //TODO (optionnal) : free pages. +} + +void Heap::create(u32int start, u32int size, u32int idxsize, PageDirectory* pagedir, bool user, bool rw) { + if (start & 0x0FFF) start = (start & 0xFFFFF000) + 0x1000; + if (size & 0x0FFF) size = (size & 0xFFFFF000) + 0x1000; + m_start = start + idxsize; //m_start is start of real data, start is start of index. + m_end = start + size; + + m_pagedir = pagedir; + m_user = user; + m_rw = rw; + + //Allocate frames for heap + for (u32int i = start ; i < m_end; i += 0x1000) { + m_pagedir->allocFrame(i, m_user, m_rw); + } + + m_index.data = (heap_header_t **)start; //Set index start. start == start of all heap + m_index.size = 0; + + heap_header_t *hole = (heap_header_t*) m_start; //m_start == start of data + hole->size = (m_end - m_start); + hole->magic = HEAP_MAGIC; + hole->is_hole = true; + + heap_footer_t *hole_footer = (heap_footer_t*) (m_end - sizeof(heap_footer_t)); + hole_footer->header = hole; + hole_footer->magic = HEAP_MAGIC; + + insertIntoIndex(hole); + + m_usable = true; + m_free = (m_end - m_start); +} + +void Heap::expand(u32int quantity) { + if (quantity & 0x00000FFF) + quantity = (quantity & 0xFFFFF000) + 0x1000; + + u32int newEnd = m_end + quantity; + + for (u32int i = m_end; i < newEnd; i++) { + m_pagedir->allocFrame(i, m_user, m_rw); + } + + heap_footer_t *last_footer = (heap_footer_t*) (m_end - sizeof(heap_footer_t)); + heap_header_t *last_header = last_footer->header; + if (last_header->is_hole) { //Last block of heap is a hole, update its size + removeFromIndex(last_header); + last_header->size += quantity; + + last_footer = (heap_footer_t*) (newEnd - sizeof(heap_footer_t)); + + last_footer->magic = HEAP_MAGIC; + last_footer->header = last_header; + + insertIntoIndex(last_header); + } else { //Last block is not a hole. Just add a new hole at the end + last_header = (heap_header_t*)m_end; + last_footer = (heap_footer_t*) (newEnd - sizeof(heap_footer_t)); + + last_header->is_hole = true; + last_header->magic = HEAP_MAGIC; + last_header->size = quantity; + + last_footer->magic = HEAP_MAGIC; + last_footer->header = last_header; + + insertIntoIndex(last_header); + } + + m_end = newEnd; + m_free += quantity; +} + +void Heap::contract() { //Automatically work out how much we can contract + heap_footer_t *last_footer = (heap_footer_t*) (m_end - sizeof(heap_footer_t)); + heap_header_t *last_header = last_footer->header; + if (last_header->is_hole == false) return; //We need a hole at end of heap + + u32int quantity = 0; + while ((m_end - m_start) - quantity > HEAP_MIN_SIZE and + (last_header->size - quantity) > 0x1000) //Always keep at least 0x1000 free at end + quantity += 0x1000; + if (quantity == 0) return; + + u32int newEnd = m_end - quantity; + m_free -= quantity; + + removeFromIndex(last_header); + last_header->size -= quantity; + last_footer = (heap_footer_t*)((u32int)last_footer - quantity); + last_footer->magic = HEAP_MAGIC; + last_footer->header = last_header; + insertIntoIndex(last_header); + + for (u32int i = newEnd; i < m_end; i += 0x1000) { + m_pagedir->freeFrame(i); + } + + m_end = newEnd; +} + +void *Heap::alloc(u32int sz, bool no_expand) { + u32int newsize = sz + sizeof(heap_header_t) + sizeof(heap_footer_t); + u32int iterator = 0; + while (iterator < m_index.size) { + if (m_index.data[iterator]->size >= newsize) break; + iterator++; + } + if (iterator == m_index.size) { //No hole is big enough + if (no_expand) return 0; + expand((sz & 0xFFFFF000) + 0x1000); + return alloc(sz, true); //Recurse call + } + + heap_header_t *loc = m_index.data[iterator]; + heap_footer_t *footer = (heap_footer_t*)((u32int)loc + loc->size - sizeof(heap_footer_t)); + loc->is_hole = false; //Update current header + + removeFromIndex(loc); + + //Here we create a new hole after currently allocated block, but only if we have enough space. If we don't, we simply allocate a bigger block so that we don't loose space + if (loc->size > (newsize + sizeof(heap_header_t) + sizeof(heap_footer_t))) { + loc->size = newsize; //Update header for return block + + heap_footer_t *newfooter = (heap_footer_t*)((u32int)loc + newsize - sizeof(heap_footer_t)); //Write footer for return block + newfooter->header = loc; + newfooter->magic = HEAP_MAGIC; + + heap_header_t *nextloc = (heap_header_t*)((u32int)loc + newsize); //Write header for new hole + nextloc->is_hole = true; + nextloc->magic = HEAP_MAGIC; + nextloc->size = ((u32int)footer - (u32int)nextloc + sizeof(heap_footer_t)); + + footer->header = nextloc; //Write footer for new hole + footer->magic = HEAP_MAGIC; + + insertIntoIndex(nextloc); + } + + m_free -= loc->size; + + return (void*)((u32int)loc + sizeof(heap_header_t)); +} + +void Heap::free(void *ptr) { + if (ptr == 0) return; + + heap_header_t *header = (heap_header_t*) ((u32int)ptr - sizeof(heap_header_t)); + heap_footer_t *footer = (heap_footer_t*)((u32int)header + header->size - sizeof(heap_footer_t)); + if (header->magic != HEAP_MAGIC or footer->magic != HEAP_MAGIC) return; + + m_free += header->size; + + //Unify left + heap_footer_t *prev_footer = (heap_footer_t*)((u32int)header - sizeof(heap_footer_t)); + if (prev_footer->magic == HEAP_MAGIC && prev_footer->header->is_hole) { + header = prev_footer->header; + removeFromIndex(header); + + footer->header = header; + header->size = ((u32int)footer - (u32int)header + sizeof(heap_footer_t)); + } + + //Unify right + heap_header_t *next_header = (heap_header_t*)((u32int)footer + sizeof(heap_footer_t)); + if (next_header->magic == HEAP_MAGIC && next_header->is_hole) { + removeFromIndex(next_header); + footer = (heap_footer_t*)((u32int)footer + next_header->size); + + footer->header = header; + header->size = ((u32int)footer - (u32int)header + sizeof(heap_footer_t)); + } + + header->is_hole = true; + + insertIntoIndex(header); + + if ((u32int)footer == (m_end - sizeof(heap_footer_t)) and + header->size >= 0x2000 and (m_end - m_start > HEAP_MIN_SIZE)) { + contract(); + } +} diff --git a/Source/Kernel/MemoryManager/Heap.class.h b/Source/Kernel/MemoryManager/Heap.class.h new file mode 100644 index 0000000..a1feaa1 --- /dev/null +++ b/Source/Kernel/MemoryManager/Heap.class.h @@ -0,0 +1,61 @@ +#ifndef DEF_HEAP_CLASS_H +#define DEF_HEAP_CLASS_H + +#include + +//Heap minimum size : 2M +#define HEAP_MIN_SIZE 0x00200000 +//Heap magic number, for verifications +#define HEAP_MAGIC 0xBEEF1337 + +struct heap_header_t { + u32int magic; + bool is_hole; + u32int size; +}; + +struct heap_footer_t { + u32int magic; + heap_header_t *header; +}; + +struct heap_index_t { + heap_header_t **data; + u32int size; +}; + +class PageDirectory; + +class Heap { + private: + bool m_usable, m_user, m_rw; + u32int m_free, m_start, m_end; + heap_index_t m_index; + PageDirectory* m_pagedir; + + void insertIntoIndex(heap_header_t *e); + u32int findIndexEntry(heap_header_t *e); + void removeFromIndex(u32int idx); + void removeFromIndex(heap_header_t *e); + + void expand(u32int quantity); + void contract(); //Quantity is automatically calculated + + + public: + Heap(); + ~Heap(); + + bool usable() { return m_usable; } + + void create(u32int start, u32int size, u32int idxsize, PageDirectory* pagedir, bool user, bool rw); + + void* alloc(u32int sz, bool no_expand = false); + void free(void* ptr); + + u32int size() { return m_end - m_start; } + u32int free() { return m_free; } +}; + + +#endif diff --git a/Source/Kernel/MemoryManager/Mem.ns.cpp b/Source/Kernel/MemoryManager/Mem.ns.cpp index fa407d6..b2f2d59 100644 --- a/Source/Kernel/MemoryManager/Mem.ns.cpp +++ b/Source/Kernel/MemoryManager/Mem.ns.cpp @@ -1,17 +1,17 @@ #include #include +#include namespace Mem { -bool kheapUsable = false, pagingEnabled = false; -u32int placementAddress, kheapFree; +bool pagingEnabled = false; +u32int placementAddress; -heap_index_t heapIndex; -u32int heapStart, heapEnd; +Heap kheap; //Placement malloc, used while heap is not initialized void *kallocInternal(u32int sz, bool align) { - if (kheapUsable) return 0; + if (kheap.usable()) return 0; if (align && (placementAddress & 0xFFFFF000)) { placementAddress &= 0xFFFFF000; placementAddress += 0x1000; @@ -24,242 +24,38 @@ void *kallocInternal(u32int sz, bool align) { return (void*)temp; } -//*************************************************************************** -//*** HEAP INDEX FUNCTIONS *** -//*************************************************************************** -void insertIntoHeapIndex(heap_header_t *e) { - //If index is full, return - if ((heapIndex.size * sizeof(heap_header_t*) + (u32int)heapIndex.data) >= heapStart) return; - - u32int iterator = 0; - while (iterator < heapIndex.size && heapIndex.data[iterator]->size < e->size) { - if (heapIndex.data[iterator] == e) return; - iterator++; - } - if (iterator == heapIndex.size) { - heapIndex.data[heapIndex.size++] = e; - } else { - u32int pos = iterator; - iterator = heapIndex.size; - while (iterator > pos) { - heapIndex.data[iterator] = heapIndex.data[iterator - 1]; - iterator--; - } - heapIndex.size++; - heapIndex.data[pos] = e; - } -} - -u32int heapIndexFindEntry(heap_header_t *e) { - for (u32int i = 0; i < heapIndex.size; i++) { - if (heapIndex.data[i] == e) - return i; - } - return (u32int) - 1; -} - -void removeFromHeapIndex(u32int idx) { - heapIndex.size--; - while (idx < heapIndex.size) { - heapIndex.data[idx] = heapIndex.data[idx + 1]; - idx++; - } -} - -void removeFromHeapIndex(heap_header_t *e) { - u32int i = heapIndexFindEntry(e); - if (i != (u32int) - 1) { - removeFromHeapIndex(i); - } -} - //*************************************************************************** //*** MEMORY MANAGMENT FUNCTIONS *** //*************************************************************************** void createHeap() { u32int heapIndexSize = PhysMem::total() * 64 + 0x10000; - heapStart = (placementAddress & 0xFFFFF000) + 0x10000; //Set initial heap start - heapEnd = heapStart + HEAP_MIN_SIZE + heapIndexSize; //Set heap end + u32int heapStart = (placementAddress & 0xFFFFF000) + 0x10000; //Set initial heap start + u32int heapSize = HEAP_MIN_SIZE + heapIndexSize; //Calculate heap size - //Alocate frames for the heap - for (u32int i = placementAddress; i < heapEnd; i += 0x1000) { - kernelPageDirectory->allocFrame(i, true, false); + for (u32int i = (placementAddress & 0xFFFFF000); i < heapStart; i += 0x1000) { + kernelPageDirectory->allocFrame(i, false, false); } - heapIndex.data = (heap_header_t **)heapStart; //Set index start - heapIndex.size = 0; - heapStart += heapIndexSize; //Set some of available memory to be the index - - heap_header_t *hole = (heap_header_t*) heapStart; - hole->size = (heapEnd - heapStart); - hole->magic = HEAP_MAGIC; - hole->is_hole = true; - - heap_footer_t *hole_footer = (heap_footer_t*) (heapEnd - sizeof(heap_footer_t)); - hole_footer->header = hole; - hole_footer->magic = HEAP_MAGIC; - - insertIntoHeapIndex(hole); - - kheapUsable = true; - kheapFree = (heapEnd - heapStart); -} - -void expandHeap(u32int quantity) { - if (quantity & 0x00000FFF) - quantity = (quantity & 0xFFFFF000) + 0x1000; - - u32int newEnd = heapEnd + quantity; - - for (u32int i = heapEnd; i < newEnd; i++) { - kernelPageDirectory->allocFrame(i, true, false); - } - - heap_footer_t *last_footer = (heap_footer_t*) (heapEnd - sizeof(heap_footer_t)); - heap_header_t *last_header = last_footer->header; - if (last_header->is_hole) { //Last block of heap is a hole, update its size - removeFromHeapIndex(last_header); - last_header->size += quantity; - - last_footer = (heap_footer_t*) (newEnd - sizeof(heap_footer_t)); - - last_footer->magic = HEAP_MAGIC; - last_footer->header = last_header; - - insertIntoHeapIndex(last_header); - } else { //Last block is not a hole. Just add a new hole at the end - last_header = (heap_header_t*)heapEnd; - last_footer = (heap_footer_t*) (newEnd - sizeof(heap_footer_t)); - - last_header->is_hole = true; - last_header->magic = HEAP_MAGIC; - last_header->size = quantity; - - last_footer->magic = HEAP_MAGIC; - last_footer->header = last_header; - - insertIntoHeapIndex(last_header); - } - - heapEnd = newEnd; - kheapFree += quantity; -} - -void contractHeap() { //Automatically work out how much we can contract - heap_footer_t *last_footer = (heap_footer_t*) (heapEnd - sizeof(heap_footer_t)); - heap_header_t *last_header = last_footer->header; - if (last_header->is_hole == false) return; //We need a hole at end of heap - - u32int quantity = 0; - while ((heapEnd - heapStart) - quantity > HEAP_MIN_SIZE and - (last_header->size - quantity) > 0x1000) //Always keep at least 0x1000 free at end - quantity += 0x1000; - if (quantity == 0) return; - - u32int newEnd = heapEnd - quantity; - kheapFree -= quantity; - - removeFromHeapIndex(last_header); - last_header->size -= quantity; - last_footer = (heap_footer_t*)((u32int)last_footer - quantity); - last_footer->magic = HEAP_MAGIC; - last_footer->header = last_header; - insertIntoHeapIndex(last_header); - - for (u32int i = newEnd; i < heapEnd; i += 0x1000) { - kernelPageDirectory->freeFrame(i); - } - - heapEnd = newEnd; + kheap.create(heapStart, heapSize, heapIndexSize, kernelPageDirectory, false, false); } void *kalloc(u32int sz, bool align) { - if (!kheapUsable) return kallocInternal(sz, align); + if (!kheap.usable()) return kallocInternal(sz, align); if (align) return 0; - u32int newsize = sz + sizeof(heap_header_t) + sizeof(heap_footer_t); - u32int iterator = 0; - while (iterator < heapIndex.size) { - if (heapIndex.data[iterator]->size >= newsize) break; - iterator++; - } - if (iterator == heapIndex.size) { - expandHeap((sz & 0xFFFFF000) + 0x1000); - return kalloc(sz); //Recurse call - } - - heap_header_t *loc = heapIndex.data[iterator]; - heap_footer_t *footer = (heap_footer_t*)((u32int)loc + loc->size - sizeof(heap_footer_t)); - loc->is_hole = false; //Update current header - - removeFromHeapIndex(loc); - - - //Here we create a new hole after currently allocated block, but only if we have enough space. If we don't, we simply allocate a bigger block so that we don't loose space - if (loc->size > (newsize + sizeof(heap_header_t) + sizeof(heap_footer_t))) { - loc->size = newsize; //Update header for return block - - heap_footer_t *newfooter = (heap_footer_t*)((u32int)loc + newsize - sizeof(heap_footer_t)); //Write footer for return block - newfooter->header = loc; - newfooter->magic = HEAP_MAGIC; - - heap_header_t *nextloc = (heap_header_t*)((u32int)loc + newsize); //Write header for new hole - nextloc->is_hole = true; - nextloc->magic = HEAP_MAGIC; - nextloc->size = ((u32int)footer - (u32int)nextloc + sizeof(heap_footer_t)); - - footer->header = nextloc; //Write footer for new hole - footer->magic = HEAP_MAGIC; - - insertIntoHeapIndex(nextloc); - } - - kheapFree -= loc->size; - - return (void*)((u32int)loc + sizeof(heap_header_t)); + return kheap.alloc(sz); } void kfree(void *ptr) { - if (ptr == 0) return; - - heap_header_t *header = (heap_header_t*) ((u32int)ptr - sizeof(heap_header_t)); - heap_footer_t *footer = (heap_footer_t*)((u32int)header + header->size - sizeof(heap_footer_t)); - if (header->magic != HEAP_MAGIC or footer->magic != HEAP_MAGIC) return; - - kheapFree += header->size; - - //Unify left - heap_footer_t *prev_footer = (heap_footer_t*)((u32int)header - sizeof(heap_footer_t)); - if (prev_footer->magic == HEAP_MAGIC && prev_footer->header->is_hole) { - header = prev_footer->header; - removeFromHeapIndex(header); - - footer->header = header; - header->size = ((u32int)footer - (u32int)header + sizeof(heap_footer_t)); - } - - //Unify right - heap_header_t *next_header = (heap_header_t*)((u32int)footer + sizeof(heap_footer_t)); - if (next_header->magic == HEAP_MAGIC && next_header->is_hole) { - removeFromHeapIndex(next_header); - footer = (heap_footer_t*)((u32int)footer + next_header->size); - - footer->header = header; - header->size = ((u32int)footer - (u32int)header + sizeof(heap_footer_t)); - } - - header->is_hole = true; - - insertIntoHeapIndex(header); - - if ((u32int)footer == (heapEnd - sizeof(heap_footer_t)) and - header->size >= 0x2000 and (heapEnd - heapStart > HEAP_MIN_SIZE)) { - contractHeap(); - } + kheap.free(ptr); } u32int kheapSize() { - return (heapEnd - heapStart); + return kheap.size(); +} + +u32int kheapFree() { + return kheap.free(); } } diff --git a/Source/Kernel/MemoryManager/Mem.ns.h b/Source/Kernel/MemoryManager/Mem.ns.h index 8eb4b2e..15935c0 100644 --- a/Source/Kernel/MemoryManager/Mem.ns.h +++ b/Source/Kernel/MemoryManager/Mem.ns.h @@ -3,36 +3,15 @@ #ifndef DEF_MEM_NS_H #define DEF_MEM_NS_H -//Heap minimum size : 2M -#define HEAP_MIN_SIZE 0x00200000 -//Heap magic number, for verifications -#define HEAP_MAGIC 0xBEEF1337 - namespace Mem { extern bool pagingEnabled; - extern u32int placementAddress, kheapFree; - - struct heap_header_t { - u32int magic; - bool is_hole; - u32int size; - }; - - struct heap_footer_t { - u32int magic; - heap_header_t *header; - }; - - struct heap_index_t { - heap_header_t **data; - u32int size; - }; + extern u32int placementAddress; void createHeap(); void *kalloc(u32int sz, bool align = false); void kfree(void *ptr); - u32int kheapSize(); + u32int kheapSize(), kheapFree(); } #endif diff --git a/Source/Kernel/Shell/KernelShell-sys.class.cpp b/Source/Kernel/Shell/KernelShell-sys.class.cpp index 17ff19c..6243b0f 100644 --- a/Source/Kernel/Shell/KernelShell-sys.class.cpp +++ b/Source/Kernel/Shell/KernelShell-sys.class.cpp @@ -29,7 +29,7 @@ void KernelShell::free(Vector& args) { u32int frames = PhysMem::total(), freef = PhysMem::free(); *m_vt << " - Free frames : " << (s32int)freef << " (" << (s32int)(freef * 4 / 1024) << "Mo) of " << (s32int)frames << " (" << (s32int)(frames * 4 / 1024) << "Mo).\n"; - u32int kh = Mem::kheapSize(), freek = Mem::kheapFree; + u32int kh = Mem::kheapSize(), freek = Mem::kheapFree(); *m_vt << " - Kernel heap free : " << (s32int)(freek / 1024 / 1024) << "Mo (" << (s32int)(freek / 1024) << "Ko) of " << (s32int)(kh / 1024 / 1024) << "Mo (" << (s32int)(kh / 1024) << "Ko).\n"; } -- cgit v1.2.3