Eneboo - Documentación para desarrolladores
|
00001 /* -*- C++ -*- */ 00002 00003 #ifndef _LAZYSLOTHEAP_H_ 00004 #define _LAZYSLOTHEAP_H_ 00005 00006 /* 00007 This heap manages memory in units of Chunks. 00008 malloc returns a slot within a chunk, 00009 while free returns slots back to a chunk. 00010 00011 We completely exhaust the first chunk before we ever get another one. 00012 Once a chunk (except for our current one) is COMPLETELY empty, it is returned to the superheap. 00013 */ 00014 00015 #include <assert.h> 00016 #include <new.h> 00017 00018 #include "chunk.h" 00019 00020 00021 template <int chunkSize, int slotSize, class Super> 00022 class LazySlotHeap : public Super { 00023 public: 00024 00025 LazySlotHeap (void) 00026 : myChunk (new (Super::malloc (chunkSize)) Chunk<chunkSize, slotSize>()) 00027 {} 00028 00029 ~LazySlotHeap (void) 00030 { 00031 // Give up our chunk. 00032 Super::free (myChunk); 00033 } 00034 00035 inline void * malloc (size_t sz) { 00036 assert (sz <= slotSize); 00037 void * ptr = myChunk->getSlot(); 00038 if (ptr == NULL) { 00039 myChunk = new (Super::malloc (chunkSize)) Chunk<chunkSize, slotSize>(); 00040 ptr = myChunk->getSlot(); 00041 assert (ptr != NULL); 00042 } 00043 return ptr; 00044 } 00045 00046 inline void free (void * ptr) { 00048 Chunk<chunkSize, slotSize> * ch = Chunk<chunkSize, slotSize>::getChunk (ptr); 00049 ch->putSlot (ptr); 00050 // check if it's completely empty. If so, free it. 00051 if (ch != myChunk) { 00052 // Once the chunk is completely empty, free it. 00053 if (ch->getNumSlotsAvailable() == ch->getNumSlots()) { 00054 Super::free (ch); 00055 } 00056 } 00057 00058 #if 0 00059 // If this chunk isn't the one we're currently holding, 00060 // free it. NB: It is NOT guaranteed to be empty! 00061 if (ch != myChunk) { 00062 Super::free (ch); 00063 } 00064 #endif 00065 #if 0 00066 template <int chunkSize, int slotSize, class Super> 00067 class StrictSlotHeap : public LazySlotHeap { 00068 public: 00069 inline void free (void * ptr) { 00071 Chunk<chunkSize, slotSize> * ch = Chunk<chunkSize, slotSize>::getChunk (ptr); 00072 ch->putSlot (ptr); 00073 // check if it's completely empty. If so, free it. 00074 if (ch != myChunk) { 00075 // Once the chunk is completely empty, free it. 00076 if (ch->getNumSlotsAvailable() == ch->getNumSlots()) { 00077 Super::free (ch); 00078 } 00079 } 00080 } 00081 00082 }; 00083 #endif 00084 00085 } 00086 00087 inline static size_t size (void * ptr) 00088 { 00089 return slotSize; 00090 } 00091 00092 00093 protected: 00094 00095 Chunk<chunkSize, slotSize> * myChunk; 00096 00097 }; 00098 00099 00100 00101 #endif