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
00020
00021 setHeap (ptr, NumHeaps);
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
00044 size_t chunkSize = (Threshold / 2) > sz ? (Threshold / 2) : sz;
00045 ptr = Heap2::malloc (chunkSize);
00046 if (ptr == NULL) {
00047 return NULL;
00048 }
00049
00050 void * splitPiece = CoalesceHeap<Heap2>::split (ptr, sz);
00051 assert (splitPiece != ptr);
00052 assert (!isFree(ptr));
00053
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
00065 return ptr;
00066 }
00067 inline void free (void * ptr) {
00068 reserved += getSize(ptr);
00069 heap1.free (ptr);
00070 if (reserved > Threshold) {
00071
00072
00073
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