📄 memorymanager.cpp
字号:
/*! \file MemoryManger.cpp \brief MemoryMangement allocate and free Copyright (c) 2003 Higepon All rights reserved. License=MIT/X Licnese \author HigePon \version $Revision: 1.6 $ \date create:2003/09/28 update:$Date: 2004/10/17 14:54:32 $*/#include <monapi/MemoryManager.h>#include <monapi/string.h>#include <monapi/syscall.h>#define SIZE_OF_HEADER sizeof(MemoryEntry)namespace MonAPI {MemoryManager::MemoryManager() {}void MemoryManager::initialize(dword start, dword end) { /* create large free block */ freeList_ = (MemoryEntry*)start; freeList_->next = (MemoryEntry*)NULL; freeList_->size = end - start - SIZE_OF_HEADER; /* memory not used yet */ usedList_ = (MemoryEntry*)NULL; /* start end */ start_ = start; end_ = end;}MemoryManager::~MemoryManager() {}bool MemoryManager::hasNoEntry(MemoryEntry* list) const { return (list == (MemoryEntry*)NULL);}void MemoryManager::addToNext(MemoryEntry* current, MemoryEntry* next) { MemoryEntry* nextnext = current->next; current->next = next; next->next = nextnext;}void MemoryManager::addToList(MemoryEntry** list, MemoryEntry* entry) { MemoryEntry* target = *list; if (hasNoEntry(target)) { *list = entry; entry->next = (MemoryEntry*)NULL; return; } if (entry < target) { entry->next = target; *list = entry; return; } for (; ; target = target->next) { bool isBetween = target < entry && entry < target->next; bool isEndOfList = target->next == (MemoryEntry*)NULL; if (isBetween || isEndOfList) { addToNext(target, entry); break; } } return;}void MemoryManager::concatFreeList() { for (MemoryEntry* current = freeList_; current != (MemoryEntry*)NULL; current = current->next) { while (true) { if (!tryConcat(current)) break; } }}bool MemoryManager::tryConcat(MemoryEntry* entry) { /* has no next entry */ if (entry->next == (MemoryEntry*)NULL) return false; MemoryEntry* expectedNext = (MemoryEntry*)((dword)entry + getRealSize(entry->size)); /* can not concat */ if (expectedNext != entry->next) return false; /* concat */ dword nextSize = getRealSize(entry->next->size); entry->next = entry->next->next; entry->size += nextSize; return true;}dword MemoryManager::getRealSize(dword size) { return (size + SIZE_OF_HEADER);}void* MemoryManager::allocate(dword size) { if (size == 0) return (dword)NULL; /* align16 */ size = (size + 16 - 1) & 0xFFFFFFF0; MemoryEntry* current; dword realSize = getRealSize(size); for (current = freeList_; ; current = current->next) { if (current->size >= realSize) break; if (current->next == (MemoryEntry*)NULL) { return (dword)NULL; } } if (current->size == realSize) { deleteFromList(&freeList_, current); addToList(&usedList_, current); memset(current->startAddress, 0, size); return (current->startAddress); } else if (current->size >= realSize) { MemoryEntry* freeBlock = (MemoryEntry*)((dword)current + realSize); freeBlock->size = getRealSize(current->size) - realSize - SIZE_OF_HEADER; current->size = size; deleteFromList(&freeList_, current); addToList(&usedList_, current); addToList(&freeList_, freeBlock); memset(current->startAddress, 0, size); return (current->startAddress); } else { return (dword)NULL; }}void MemoryManager::free(void* address) { dword target = (dword)address; if (target < 1) return; MemoryEntry* entry = (MemoryEntry*)(target - SIZE_OF_HEADER); dword size = entry->size; deleteFromList(&usedList_, entry); addToList(&freeList_, entry); concatFreeList(); syscall_free_pages((dword)address, size);}void MemoryManager::deleteFromList(MemoryEntry** list, MemoryEntry* entry) { /* delete block is top of the list */ if (*list == entry && (*list)->next == (MemoryEntry*)NULL) { *list = (MemoryEntry*)NULL; return; } else if (*list == entry && (*list)->next != (MemoryEntry*)NULL) { MemoryEntry* next = (*list)->next; *list = next; return; } /* iterate list and find block to delete */ for (MemoryEntry* current = *list; current != (MemoryEntry*)NULL; current = current->next) { /* block to delete found */ if (current->next == entry) { current->next = current->next->next; break; } } return;}dword MemoryManager::getFreeMemorySize() const { dword result = 0; for (MemoryEntry* current = freeList_; current != (MemoryEntry*)NULL; current = current->next) { result += (current->size); } return result;}dword MemoryManager::getUsedMemorySize() const { dword result = 0; for (MemoryEntry* current = usedList_; current != (MemoryEntry*)NULL; current = current->next) { result += (current->size); } return result;}void MemoryManager::debugPrint() const {// printf("Rage[%x-%x]\n", start_, end_);// printf("FreeMemorySize=%x\n", getFreeMemorySize());// for (MemoryEntry* current = freeList_; current != (MemoryEntry*)NULL; current = current->next) {// printf("F[%x][%x]\n", current, current->size);// }// printf("UsedMemorySize=%x\n", getUsedMemorySize());// for (MemoryEntry* current = usedList_; current != (MemoryEntry*)NULL; current = current->next) {// printf("U[%x][%x]\n", current, current->size);// }}dword MemoryManager::getPhysicalMemorySize() { /* assume there is at least 1MB memory */ dword totalMemorySize = 1024 * 1024; /* 1MB unit loop */ for (dword i = 1024 * 1024; i < 0xFFFFFFFF; i += 1024 * 1024) { dword* p = (dword*)i; dword value = *p; *p = 0x12345678; if (*p != 0x12345678) break; *p = value; totalMemorySize += 1024 * 1024; } return totalMemorySize;}MemoryManager2::MemoryManager2() {}void MemoryManager2::initialize(dword start, dword end) { freeList_ = (MemoryHeader*)start; freeList_->next = freeList_; freeList_->size = (end - start + 1) / sizeof(MemoryHeader);}MemoryManager2::~MemoryManager2() {}void* MemoryManager2::allocate(dword size) { if (size == 0) return (dword)NULL; dword nunits = (size + sizeof(MemoryHeader) - 1) / sizeof(MemoryHeader) + 1; MemoryHeader *prevp = freeList_; MemoryHeader *p; for (p = prevp->next; ;prevp = p, p = p->next) { if (p->size >= nunits) break; if (p == freeList_) return 0; } if (p->size == nunits) { prevp->next = p->next; } else { p->size -= nunits; p += p->size; p->size = nunits; } freeList_ = prevp; return (void *)(p + 1);}void MemoryManager2::free(void* address) { MemoryHeader *bp = (MemoryHeader *)address - 1; MemoryHeader *p; for (p = freeList_; !(p < bp && bp < p->next); p = p->next) { if (p >= p->next && (bp > p || bp < p->next)) break; } if (bp + bp->size == p->next) { bp->size += p->next->size; bp->next = p->next->next; } else { bp->next = p->next; } if (p + p->size == bp) { p->size += bp->size; p->next = bp->next; } else { p->next = bp; } freeList_ = p;}dword MemoryManager2::getPhysicalMemorySize() { /* assume there is at least 1MB memory */ dword totalMemorySize = 1024 * 1024; /* 1MB unit loop */ for (dword i = 1024 * 1024; i < 0xFFFFFFFF; i += 1024 * 1024) { dword* p = (dword*)i; dword value = *p; *p = 0x12345678; if (*p != 0x12345678) break; *p = value; totalMemorySize += 1024 * 1024; } return totalMemorySize;}dword MemoryManager2::getFreeMemorySize() const { dword result = 0; for (MemoryHeader* current = freeList_; current->next != freeList_; current = current->next) { result += (current->size); } return result * sizeof(MemoryHeader);}dword MemoryManager2::getUsedMemorySize() const { return (end_ - start_ + 1) / sizeof(MemoryHeader) - getFreeMemorySize();}}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -