1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
|
/*
MemManager.h Memory Manager
This module provides memory management functions.
Copyright (C) 2004, Wong Chi Kwong.
This program is FREEALIGN 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 2
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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __MEM_MANAGER_H__
#define __MEM_MANAGER_H__
#include "TypeNLimit.h"
#include <stdlib.h>
#include <stdio.h>
#define MAX_ALIGN 64 // All memory except pool memory are aligned to MAX_ALIGN; pool memory is aligned to finer boundary for small memory size
#define MIN_ALIGN 1
#define RECORD_GRAND_TOTAL
// Memory type:
//
// unit memory: allocation managed by malloc() individually;
// to be used for large and less frequently accessed items
// allocation can be freed individually at any time
// pool memory: pre-allocated memory pool for items with varying sizes
// allocation cannot be freed by individually
// to be used for small and frequently accessed items
// temp memory: temporary use granted from pool memory
// allocation is allocated and freed like the items in a stack
// pool memory allocation is disabled while temporary memory is in use
// bulk memory: pre-allocated memory pool for items with the same size
// to be used for massively numbered items
// memory address of dispatched items can be calculated by dispatch index
#ifdef DEBUG
#define Mem(mmBulk, index) MMBulkAddress(mmBulk, index)
#else
#define Mem(mmBulk, index) (void*)&(mmBulk->directory[index >> mmBulk->itemPerAllocationInPowerOf2][(index & mmBulk->indexMask) * mmBulk->itemSize])
#endif
typedef struct MMPool {
unsigned int poolSize; // Size of memory pool; the beginning of the pool holds the MMPool structure
unsigned int poolByteDispatched; // Includes any spillover and memory skipped for align
unsigned int poolByteSpillover; // Exclude spillover pointers
unsigned int currentTempByteDispatched; // Includes any spillover
unsigned int currentTempByteSpillover; // Exclude spillover pointers
unsigned int maxTotalByteDispatched; // The max of pool memory + temp memory dispatched
void *firstSpillOverAddress; // if pool is freed, = address of mmPool
} MMPool;
typedef struct MMBulk {
unsigned int itemSize;
unsigned int itemPerAllocationInPowerOf2;
unsigned int boundaryCushionSize; // boundary cushion is a piece of memory allocated so that the memory around items can be safely referenced
unsigned int indexMask;
unsigned int currentDirectoryEntry;
unsigned int nextUnusedItem;
unsigned int directorySize;
unsigned char **directory; // if bulk is freed, = NULL
} MMBulk;
typedef struct MMMaster {
unsigned int currentUnitByteAllocated;
unsigned int maxUnitByteAllocated;
unsigned int maxNumberOfPools;
MMPool **mmPool;
unsigned int maxNumberOfBulks;
MMBulk **mmBulk;
unsigned int maxTotalByteAllocated;
unsigned int maxTotalByteDispatched;
int traceUnitByteAllocation;
FILE *unitByteTraceFile;
} MMMaster;
void *MMMalloc(const unsigned int memSize);
void MMFree(void *address);
void MMMasterInitialize(const unsigned int maxNumberOfPools, const unsigned int maxNumberOfBulks,
const int traceUnitByteAllocation, FILE *unitByteTraceFile);
void MMMasterFreeAll();
unsigned int MMMasterCurrentTotalByteAllocated();
unsigned int MMMasterCurrentTotalByteDispatched();
unsigned int MMMasterMaxTotalByteAllocated();
unsigned int MMMasterMaxTotalByteDispatched();
void MMMasterSetMaxTotalByteAllocated();
void MMMasterSetMaxTotalByteDispatched();
void MMMasterPrintReport(FILE *output, const unsigned int withUnitDetails, const unsigned int withPoolDetails, const unsigned int withBulkDetails);
void *MMUnitAllocate(const unsigned int memSize);
void *MMUnitReallocate(void *address, const unsigned int newMemSize, const unsigned int oldMemSize);
void MMUnitFree(void *address, const unsigned int memSize);
unsigned int MMUnitCurrentByteAllocated();
unsigned int MMUnitMaxByteAllocated();
void MMUnitPrintReport(FILE *output);
MMPool *MMPoolCreate(const unsigned int poolSize);
unsigned int MMPoolIsActive(const MMPool *mmPool);
void MMPoolSetInactive(MMPool *mmPool);
unsigned int MMPoolCurrentTotalByteAllocated(const MMPool *mmPool);
unsigned int MMPoolCurrentTotalByteDispatched(const MMPool *mmPool);
unsigned int MMPoolMaxTotalByteDispatched(const MMPool *mmPool);
unsigned int MMPoolByteAvailable(const MMPool *mmPool);
MMPool *MMPoolFree(MMPool *mmPool);
void MMPoolReset(MMPool *mmPool);
void MMPoolDestory(MMPool *mmPool);
void *MMPoolDispatch(MMPool *mmPool, const unsigned int memSize);
unsigned int MMPoolDispatchOffset(MMPool *mmPool, const unsigned int memSize);
void MMPoolReturn(MMPool *mmPool, void *address, const unsigned int memSize); // Dummy function
void MMPoolPrintReport(MMPool *mmPool, FILE *output);
void *MMTempDispatch(MMPool *mmPool, const unsigned int memsize);
void MMTempReturn(MMPool *mmPool, void *address, const unsigned int memSize);
void MMTempPrintReport(MMPool *mmPool, FILE *output);
MMBulk *MMBulkCreate(MMPool *mmPool, const unsigned int itemSize, const unsigned int itemPerAllocationInPowerOf2,
unsigned int const boundaryCushionSize, unsigned int const directorySize);
unsigned int MMBulkIsActive(const MMBulk *mmBulk);
void MMBulkSetInactive(MMBulk *mmBulk);
unsigned int MMBulkByteAllocated(const MMBulk *mmBulk);
unsigned int MMBulkByteDispatched(const MMBulk *mmBulk);
unsigned int MMBulkUnitDispatched(const MMBulk *mmBulk);
void MMBulkFree(MMBulk *mmBulk);
void MMBulkDestory(MMBulk *mmBulk);
unsigned int MMBulkDispatch(MMBulk *mmBulk);
void *MMBulkAddress(const MMBulk *mmBulk, const unsigned int index);
MMPool *MMBulkFindPoolUsed(const MMBulk *mmBulk);
void MMBulkPrintReport(MMBulk *mmBulk, FILE *output);
void MMBulkSave(MMBulk *mmBulk, FILE *output);
MMBulk *MMBulkLoad(MMPool *mmPool, FILE *input);
#endif
|