Eneboo - Documentación para desarrolladores
|
00001 /* -*- C++ -*- */ 00002 00003 /* 00004 00005 Heap Layers: An Extensible Memory Allocation Infrastructure 00006 00007 Copyright (C) 2000-2005 by Emery Berger 00008 http://www.cs.umass.edu/~emery 00009 emery@cs.umass.edu 00010 00011 This program is free software; you can redistribute it and/or modify 00012 it under the terms of the GNU General Public License as published by 00013 the Free Software Foundation; either version 2 of the License, or 00014 (at your option) any later version. 00015 00016 This program is distributed in the hope that it will be useful, 00017 but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 GNU General Public License for more details. 00020 00021 You should have received a copy of the GNU General Public License 00022 along with this program; if not, write to the Free Software 00023 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00024 00025 */ 00026 00027 #ifndef _XALLOCHEAP_H_ 00028 #define _XALLOCHEAP_H_ 00029 00030 namespace HL { 00031 00032 template <int ArenaSize, class SuperHeap> 00033 class XallocHeap : public SuperHeap { 00034 00035 public: 00036 00037 inline XallocHeap (void) { 00038 start_of_array = (char *) SuperHeap::malloc (ArenaSize); 00039 end_of_array = start_of_array + align(sizeof(Nuggie)); 00040 size_lval(end_of_array) = 0; 00041 last_block = NULL; 00042 } 00043 00044 inline ~XallocHeap (void) { 00045 SuperHeap::free (start_of_array); 00046 } 00047 00048 inline void * malloc (size_t size) { 00049 char * old_end_of_array = end_of_array; 00050 end_of_array += align(size + sizeof(Nuggie)); 00051 if (old_end_of_array + size >= start_of_array + ArenaSize) { 00052 // We're out of memory. 00053 return NULL; 00054 } 00055 size_lval(end_of_array) = end_of_array - old_end_of_array; 00056 clear_use(end_of_array); /* this is not necessary, cause it will be zero */ 00057 set_use(old_end_of_array); 00058 last_block = old_end_of_array; 00059 return old_end_of_array; 00060 } 00061 00062 inline void free (void * ptr) { 00063 char * p = (char *) ptr; 00064 char * q; 00065 /* At this point we could check that the in_use bit for this block 00066 is set, and also check that the size is right */ 00067 clear_use(p); /* mark this block as unused */ 00068 if (p == last_block) { 00069 while (1) { 00070 q = prev_block(p); 00071 if (q == p) { 00072 last_block = NULL; 00073 end_of_array = p; 00074 break; /* only happens when we get to the beginning */ 00075 } 00076 if (in_use(q)) { 00077 last_block = q; 00078 end_of_array = p; 00079 break; 00080 } 00081 p = q; 00082 } 00083 } 00084 } 00085 00086 private: 00087 00088 static inline size_t& size_lval (char * x) { 00089 return (((Nuggie *)(((char *)x) - sizeof(Nuggie)))->size); 00090 } 00091 00092 static inline char * prev_block (char * x) { 00093 return (((char *) x) - (size_lval(x) & (~1))); 00094 } 00095 00096 static inline int in_use (char * x) { 00097 return (size_lval(x) & (1)); 00098 } 00099 00100 static inline void set_use (char * x) { 00101 (size_lval(x) |= (1)); 00102 } 00103 00104 static inline void clear_use (char * x) { 00105 (size_lval(x) &= (~1)); 00106 } 00107 00108 class Nuggie { 00109 public: 00110 size_t size; 00111 }; 00112 00113 inline static size_t align (int sz) { 00114 return (sz + (sizeof(double) - 1)) & ~(sizeof(double) - 1); 00115 } 00116 00117 char * end_of_array; 00118 char * start_of_array; 00119 char * last_block; 00120 }; 00121 00122 }; 00123 00124 00125 #endif