00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include <stdlib.h>
00036 #include <string.h>
00037 #include <strings.h>
00038 #if !defined(__SUNPRO_CC) || __SUNPRO_CC > 0x420
00039 #include <new>
00040 #endif
00041 #include "config.h"
00042
00043 #include "threadheap.h"
00044 #include "processheap.h"
00045 #include "persistentheap.h"
00046 #include "arch-specific.h"
00047
00048 #include "dlmalloc.h"
00049
00050
00051
00052
00053
00054
00055
00056 inline static persistentHeap * getPersistentAllocator (void) {
00057 static char * buf = (char *) hoardGetMemory (sizeof(persistentHeap));
00058 static persistentHeap * theAllocator = new (buf) persistentHeap;
00059 return theAllocator;
00060 }
00061
00062
00063
00064
00065
00066
00067
00068
00069 inline static processHeap * getAllocator (persistentHeap *persistentHeap) {
00070 static char * buf = (char *) hoardGetMemory (sizeof(processHeap));
00071 static processHeap * theAllocator = new (buf) processHeap(persistentHeap);
00072 return theAllocator;
00073 }
00074
00075 #define HOARD_MALLOC pmalloc
00076 #define HOARD_MALLOC_TXN pmallocTxn
00077 #define HOARD_FREE pfree
00078 #define HOARD_FREE_TXN pfreeTxn
00079 #define HOARD_REALLOC prealloc
00080 #define HOARD_CALLOC pcalloc
00081 #define HOARD_MEMALIGN pmemalign
00082 #define HOARD_VALLOC pvalloc
00083 #define HOARD_GET_USABLE_SIZE pmalloc_usable_size
00084
00085
00086
00087 extern "C" void * HOARD_MALLOC(size_t);
00088 extern "C" void * HOARD_MALLOC_TXN(size_t);
00089 extern "C" void HOARD_FREE(void *);
00090 extern "C" void HOARD_FREE_TXN(void *);
00091 extern "C" void * HOARD_REALLOC(void *, size_t);
00092 extern "C" void * HOARD_CALLOC(size_t, size_t);
00093 extern "C" void * HOARD_MEMALIGN(size_t, size_t);
00094 extern "C" void * HOARD_VALLOC(size_t);
00095 extern "C" size_t HOARD_GET_USABLE_SIZE(void *);
00096
00097 __attribute__((tm_wrapping(HOARD_MALLOC))) void *HOARD_MALLOC_TXN(size_t);
00098 __attribute__((tm_wrapping(HOARD_FREE))) void HOARD_FREE_TXN(void *);
00099
00100 static void * malloc_internal (size_t sz)
00101 {
00102 void *addr;
00103 static persistentHeap *persistentheap = getPersistentAllocator();
00104 static processHeap *pHeap = getAllocator(persistentheap);
00105 if (sz == 0) {
00106 sz = 1;
00107 }
00108 printf("pmalloc[START]: size = %d\n", sz);
00109 if (sz >= SUPERBLOCK_SIZE) {
00110
00111
00112
00113
00114
00115
00116 {
00117 addr = PDL_MALLOC(sz);
00118 }
00119 } else {
00120 addr = pHeap->getHeap(pHeap->getHeapIndex()).malloc (sz);
00121 }
00122 printf("pmalloc[DONE]: addr=%p, size = %d\n", addr, sz);
00123 return addr;
00124 }
00125
00126 extern "C" void * HOARD_MALLOC (size_t sz)
00127 {
00128 return malloc_internal(sz);
00129 std::cerr << "Called persistent memory allocator outside of transaction." << std::endl;
00130 abort();
00131 }
00132
00133 extern "C" void * HOARD_MALLOC_TXN (size_t sz)
00134 {
00135 return malloc_internal(sz);
00136 }
00137
00138 extern "C" void * HOARD_CALLOC (size_t nelem, size_t elsize)
00139 {
00140 static persistentHeap * persistentheap = getPersistentAllocator();
00141 static processHeap * pHeap = getAllocator(persistentheap);
00142 size_t sz = nelem * elsize;
00143 if (sz == 0) {
00144 sz = 1;
00145 }
00146 void * ptr = pHeap->getHeap(pHeap->getHeapIndex()).malloc (sz);
00147
00148 memset (ptr, 0, sz);
00149 return ptr;
00150 }
00151
00152 static void free_internal (void * ptr)
00153 {
00154 static persistentHeap * persistentheap = getPersistentAllocator();
00155
00156 printf("free: %p [%p - %p)\n",
00157 ptr,
00158 ((uintptr_t) persistentheap->getPersistentSegmentBase()),
00159 ((uintptr_t) persistentheap->getPersistentSegmentBase() + PERSISTENTHEAP_SIZE));
00160
00161
00162 if ((uintptr_t) ptr >= ((uintptr_t) persistentheap->getPersistentSegmentBase()) &&
00163 (uintptr_t) ptr < ((uintptr_t) persistentheap->getPersistentSegmentBase() + PERSISTENTHEAP_SIZE))
00164 {
00165 persistentheap->free (ptr);
00166 } else {
00167
00168 {
00169 PDL_FREE (ptr);
00170 }
00171 }
00172 }
00173
00174
00175 extern "C" void HOARD_FREE (void* ptr)
00176 {
00177 free_internal(ptr);
00178 std::cerr << "Called persistent memory allocator outside of transaction." << std::endl;
00179 abort();
00180 }
00181
00182
00183 extern "C" void HOARD_FREE_TXN (void * ptr)
00184 {
00185 free_internal(ptr);
00186 }
00187
00188
00189 extern "C" void * HOARD_MEMALIGN (size_t, size_t)
00190 {
00191
00192 assert(0);
00193 #if 0
00194 static persistentHeap * persistentheap = getPersistentAllocator();
00195 static processHeap * pHeap = getAllocator(persistentheap);
00196 void * addr = pHeap->getHeap(pHeap->getHeapIndex()).memalign (alignment, size);
00197 return addr;
00198 #endif
00199 return NULL;
00200 }
00201
00202
00203 extern "C" void * HOARD_VALLOC (size_t size)
00204 {
00205 return HOARD_MEMALIGN (hoardGetPageSize(), size);
00206 }
00207
00208
00209 extern "C" void * HOARD_REALLOC (void * ptr, size_t sz)
00210 {
00211 if (ptr == NULL) {
00212 return HOARD_MALLOC (sz);
00213 }
00214 if (sz == 0) {
00215 HOARD_FREE (ptr);
00216 return NULL;
00217 }
00218
00219
00220
00221
00222 size_t objSize = threadHeap::objectSize (ptr);
00223
00224 if (objSize >= sz) {
00225 return ptr;
00226 }
00227
00228
00229
00230 void * buf = HOARD_MALLOC (sz);
00231
00232
00233
00234
00235 size_t minSize = (objSize < sz) ? objSize : sz;
00236 memcpy (buf, ptr, minSize);
00237
00238
00239
00240 HOARD_FREE (ptr);
00241
00242
00243
00244 return buf;
00245 }
00246
00247 extern "C" size_t HOARD_GET_USABLE_SIZE (void * ptr)
00248 {
00249 return threadHeap::objectSize (ptr);
00250 }
00251
00252
00253 #if 0
00254 extern "C" void malloc_stats (void)
00255 {
00256 TheWrapper.TheAllocator()->stats();
00257 }
00258 #endif