Eneboo - Documentación para desarrolladores
|
00001 #ifndef _SCALABLELEAHEAP_H_ 00002 #define _SCALABLELEAHEAP_H_ 00003 00004 #include "heaplayers.h" 00005 00006 namespace ScalableHeapNS { 00007 00008 template <int NumHeaps, class SuperHeap> 00009 class GlobalHeapWrapper : public SuperHeap { 00010 public: 00011 inline void * malloc (size_t sz) { 00012 void * ptr = SuperHeap::malloc (sz); 00013 if (ptr != NULL) { 00014 assert (!isFree(ptr)); 00015 } 00016 return ptr; 00017 } 00018 inline void free (void * ptr) { 00019 // Set this object's heap to an unassigned heap (NumHeaps), 00020 // then free it. 00021 setHeap (ptr, NumHeaps); // This should be an unassigned heap number. 00022 assert (getHeap(ptr) == NumHeaps); 00023 setPrevHeap(getNext(ptr), NumHeaps); 00024 assert (getPrevHeap(getNext(ptr)) == NumHeaps); 00025 SuperHeap::free (ptr); 00026 } 00027 private: 00028 inline int remove (void *); 00029 }; 00030 00031 00032 template <int Threshold, class Heap1, class Heap2> 00033 class TryHeap : public Heap2 { 00034 public: 00035 TryHeap (void) 00036 : reserved (0) 00037 {} 00038 00039 inline void * malloc (size_t sz) { 00040 void * ptr = heap1.malloc (sz); 00041 if (ptr == NULL) { 00042 #if 1 00043 // Get a big chunk. 00044 size_t chunkSize = (Threshold / 2) > sz ? (Threshold / 2) : sz; 00045 ptr = Heap2::malloc (chunkSize); 00046 if (ptr == NULL) { 00047 return NULL; 00048 } 00049 // Split it. 00050 void * splitPiece = CoalesceHeap<Heap2>::split (ptr, sz); 00051 assert (splitPiece != ptr); 00052 assert (!isFree(ptr)); 00053 // Put the split piece on heap 1. 00054 if (splitPiece != NULL) { 00055 reserved += getSize(splitPiece); 00056 heap1.free (splitPiece); 00057 } 00058 #else 00059 ptr = Heap2::malloc (sz); 00060 #endif 00061 } else { 00062 reserved -= getSize(ptr); 00063 } 00064 // assert (getHeap(ptr) == tid); 00065 return ptr; 00066 } 00067 inline void free (void * ptr) { 00068 reserved += getSize(ptr); 00069 heap1.free (ptr); 00070 if (reserved > Threshold) { 00071 // We've crossed the threshold. 00072 // Free objects from heap 1 and give them to heap 2. 00073 // Start big. 00074 size_t sz = Threshold / 2; 00075 while ((sz > sizeof(double)) && (reserved > Threshold / 2)) { 00076 void * p = NULL; 00077 while ((p == NULL) && (sz >= sizeof(double))) { 00078 p = heap1.malloc (sz); 00079 if (p == NULL) { 00080 sz >>= 1; 00081 } 00082 } 00083 if (p != NULL) { 00084 reserved -= getSize(p); 00085 Heap2::free (p); 00086 } 00087 } 00088 } 00089 } 00090 00091 00092 private: 00093 inline int remove (void * ptr); 00094 #if 0 00095 { 00096 assert (0); 00097 abort(); 00098 } 00099 #endif 00100 00101 Heap1 heap1; 00102 int reserved; 00103 }; 00104 00105 00106 template <int NumHeaps, int MmapThreshold, class BaseNullHeap, class BaseHeap> 00107 class SmallHeap : public 00108 ScalableHeapNS::TryHeap<MmapThreshold, 00109 MarkThreadHeap<NumHeaps, BaseNullHeap>, 00110 MarkThreadHeap<NumHeaps, GlobalHeapWrapper<NumHeaps, BaseHeap> > > {}; 00111 00112 template <int NumHeaps, int MmapThreshold, class BaseNullHeap, class BaseHeap> 00113 class MTHeap : 00114 public PHOThreadHeap<NumHeaps, 00115 LockedHeap<SmallHeap<NumHeaps, MmapThreshold, BaseNullHeap, BaseHeap> > > {}; 00116 00117 }; 00118 00119 00120 template <int NumHeaps, class BaseNullHeap, class BaseHeap, class Mmap> 00121 class ScalableHeap : 00122 public SelectMmapHeap<128 * 1024, 00123 ScalableHeapNS::MTHeap<NumHeaps, 128 * 1024, BaseNullHeap, BaseHeap>, 00124 LockedHeap<Mmap> > {}; 00125 #endif