00001
00002
00009 #ifndef _ALIGNEDMMAP_H_
00010 #define _ALIGNEDMMAP_H_
00011
00012 #include "sassert.h"
00013 #include "myhashmap.h"
00014 #include "freelistheap.h"
00015 #include "mmapwrapper.h"
00016 #include "bumpalloc.h"
00017 #include "exactlyone.h"
00018 #include "mmapalloc.h"
00019
00020 using namespace std;
00021 using namespace HL;
00022
00023 namespace Hoard {
00024
00032 template <size_t Alignment_>
00033 class AlignedMmapInstance {
00034 public:
00035
00036 enum { Alignment = Alignment_ };
00037
00038 inline void * malloc (size_t sz) {
00039
00040
00041 sz = (sz + HL::MmapWrapper::Size - 1) & ~(HL::MmapWrapper::Size - 1);
00042
00043
00044 if ((size_t) HL::MmapWrapper::Alignment % (size_t) Alignment == 0) {
00045 void * ptr = HL::MmapWrapper::map (sz);
00046 MyMap.set (ptr, sz);
00047 return ptr;
00048 }
00049
00050
00051
00052
00053 char * ptr = reinterpret_cast<char *>(HL::MmapWrapper::map (sz));
00054
00055 if (ptr == align(ptr)) {
00056
00057 MyMap.set (ptr, sz);
00058 return ptr;
00059 } else {
00060
00061 HL::MmapWrapper::unmap ((void *) ptr, sz);
00062 }
00063
00064
00065
00066
00067
00068 ptr = reinterpret_cast<char *>(HL::MmapWrapper::map (sz + Alignment_));
00069
00070 if (ptr == NULL) {
00071 return NULL;
00072 }
00073
00074 char * newptr = align (ptr);
00075
00076
00077
00078 size_t prolog = (size_t) newptr - (size_t) ptr;
00079
00080 if (prolog > 0) {
00081
00082 HL::MmapWrapper::unmap (ptr, prolog);
00083 }
00084
00085 size_t epilog = Alignment_ - prolog;
00086 HL::MmapWrapper::unmap ((char *) newptr + sz, epilog);
00087
00088
00089
00090 MyMap.set (newptr, sz);
00091 return newptr;
00092 }
00093
00094 inline void free (void * ptr) {
00095
00096
00097
00098
00099 size_t requestedSize = MyMap.get (ptr);
00100
00101 if (requestedSize == 0) {
00102 return;
00103 }
00104
00105 HL::MmapWrapper::unmap (ptr, requestedSize);
00106
00107
00108 MyMap.erase (ptr);
00109 }
00110
00111 inline size_t getSize (void * ptr) {
00112 return MyMap.get (ptr);
00113 }
00114
00115
00116 private:
00117
00119 inline static char * align (char * buf) {
00120 return (char *)(((size_t) buf + (Alignment_-1)) & ~(Alignment_-1));
00121 }
00122
00123
00124
00125
00127 typedef void * keyType;
00128
00130 typedef size_t valType;
00131
00132
00133
00134 class SourceHeap : public HL::FreelistHeap<BumpAlloc<65536, MmapAlloc> > { };
00135
00137 typedef MyHashMap<keyType, valType, SourceHeap> mapType;
00138
00140 mapType MyMap;
00141
00142 };
00143
00144
00151 template <size_t Alignment_,
00152 class LockType>
00153 class AlignedMmap :
00154 public ExactlyOne<LockedHeap<LockType, AlignedMmapInstance<Alignment_> > >
00155 {
00156 public:
00157
00158 enum { Alignment = Alignment_ };
00159
00160 inline void * malloc (size_t sz) {
00161 return (*this)().malloc (sz);
00162 }
00163 inline void free (void * ptr) {
00164 return (*this)().free (ptr);
00165 }
00166 inline size_t getSize (void * ptr) const {
00167 return (*this)().getSize (ptr);
00168 }
00169
00170 };
00171
00172 }
00173
00174 #endif