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 "genalloc.h"
00049
00050 #include <itm.h>
00051 #include "mtm/include/txlock.h"
00052
00053 m_txmutex_t generic_pmalloc_txmutex = PTHREAD_MUTEX_INITIALIZER;
00054
00055
00056
00057
00058
00059
00060
00061 inline static persistentHeap * getPersistentAllocator (void) {
00062 static char * buf = (char *) hoardGetMemory (sizeof(persistentHeap));
00063 static persistentHeap * theAllocator = new (buf) persistentHeap;
00064 return theAllocator;
00065 }
00066
00067
00068
00069
00070
00071
00072
00073
00074 inline static processHeap * getAllocator (persistentHeap *persistentHeap) {
00075 static char * buf = (char *) hoardGetMemory (sizeof(processHeap));
00076 static processHeap * theAllocator = new (buf) processHeap(persistentHeap);
00077 return theAllocator;
00078 }
00079
00080 #define HOARD_MALLOC pmalloc
00081 #define HOARD_MALLOC_TXN pmallocTxn
00082 #define HOARD_FREE pfree
00083 #define HOARD_FREE_TXN pfreeTxn
00084 #define HOARD_REALLOC prealloc
00085 #define HOARD_REALLOC_TXN preallocTxn
00086 #define HOARD_CALLOC pcalloc
00087 #define HOARD_MEMALIGN pmemalign
00088 #define HOARD_VALLOC pvalloc
00089 #define HOARD_GET_USABLE_SIZE pmalloc_usable_size
00090
00091
00092
00093 extern "C" void * HOARD_MALLOC(size_t);
00094 extern "C" void * HOARD_MALLOC_TXN(size_t);
00095 extern "C" void HOARD_FREE(void *);
00096 extern "C" void HOARD_FREE_TXN(void *);
00097 extern "C" void * HOARD_REALLOC(void *, size_t);
00098 extern "C" void * HOARD_REALLOC_TXN(void *, size_t);
00099 extern "C" void * HOARD_CALLOC(size_t, size_t);
00100 extern "C" void * HOARD_MEMALIGN(size_t, size_t);
00101 extern "C" void * HOARD_VALLOC(size_t);
00102 extern "C" size_t HOARD_GET_USABLE_SIZE(void *);
00103
00104 __attribute__((tm_wrapping(HOARD_MALLOC))) void *HOARD_MALLOC_TXN(size_t);
00105 __attribute__((tm_wrapping(HOARD_FREE))) void HOARD_FREE_TXN(void *);
00106 __attribute__((tm_wrapping(HOARD_REALLOC))) void *HOARD_REALLOC_TXN(void *, size_t);
00107
00108
00109 static void * pmalloc_internal (size_t sz)
00110 {
00111 void *addr;
00112 static persistentHeap *persistentheap = getPersistentAllocator();
00113 static processHeap *pHeap = getAllocator(persistentheap);
00114
00115 if (sz == 0) {
00116 sz = 1;
00117 }
00118
00119
00120 if (sz >= SUPERBLOCK_SIZE/2) {
00121
00122
00123
00124
00125
00126
00127 __tm_atomic
00128 {
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139 addr = GENERIC_PMALLOC(sz);
00140 }
00141 } else {
00142
00143 addr = pHeap->getHeap(pHeap->getHeapIndex()).malloc (sz);
00144 }
00145
00146 return addr;
00147 }
00148
00149 extern "C" void * HOARD_MALLOC (size_t sz)
00150 {
00151
00152
00153 return pmalloc_internal(sz);
00154 }
00155
00156 extern "C" void * HOARD_MALLOC_TXN (size_t sz)
00157 {
00158 return pmalloc_internal(sz);
00159 }
00160
00161 extern "C" void * HOARD_CALLOC (size_t nelem, size_t elsize)
00162 {
00163 static persistentHeap * persistentheap = getPersistentAllocator();
00164 static processHeap * pHeap = getAllocator(persistentheap);
00165 size_t sz = nelem * elsize;
00166
00167 if (sz == 0) {
00168 sz = 1;
00169 }
00170 void * ptr = pHeap->getHeap(pHeap->getHeapIndex()).malloc (sz);
00171
00172 memset (ptr, 0, sz);
00173 return ptr;
00174 }
00175
00176 static void free_internal (void * ptr)
00177 {
00178 static persistentHeap * persistentheap = getPersistentAllocator();
00179
00180
00181
00182
00183
00184
00185
00186 if ((uintptr_t) ptr >= ((uintptr_t) persistentheap->getPersistentSegmentBase()) &&
00187 (uintptr_t) ptr < ((uintptr_t) persistentheap->getPersistentSegmentBase() + PERSISTENTHEAP_SIZE))
00188 {
00189 persistentheap->free (ptr);
00190 } else {
00191 __tm_atomic
00192 {
00193 GENERIC_PFREE (ptr);
00194 }
00195 }
00196 }
00197
00198
00199 extern "C" void HOARD_FREE (void* ptr)
00200 {
00201 free_internal(ptr);
00202
00203
00204 }
00205
00206
00207 extern "C" void HOARD_FREE_TXN (void * ptr)
00208 {
00209 free_internal(ptr);
00210 }
00211
00212
00213 extern "C" void * HOARD_MEMALIGN (size_t, size_t)
00214 {
00215
00216 assert(0);
00217 #if 0
00218 static persistentHeap * persistentheap = getPersistentAllocator();
00219 static processHeap * pHeap = getAllocator(persistentheap);
00220 void * addr = pHeap->getHeap(pHeap->getHeapIndex()).memalign (alignment, size);
00221 return addr;
00222 #endif
00223 return NULL;
00224 }
00225
00226
00227 extern "C" void * HOARD_VALLOC (size_t size)
00228 {
00229 return HOARD_MEMALIGN (hoardGetPageSize(), size);
00230 }
00231
00232
00233 static void * prealloc_internal (void * ptr, size_t sz)
00234 {
00235 _ITM_transaction *tx;
00236 static persistentHeap * persistentheap = getPersistentAllocator();
00237
00238 if (ptr == NULL) {
00239 return pmalloc_internal (sz);
00240 }
00241 if (sz == 0) {
00242 free_internal (ptr);
00243 return NULL;
00244 }
00245
00246 size_t objSize;
00247
00248
00249
00250 if ((uintptr_t) ptr >= ((uintptr_t) persistentheap->getPersistentSegmentBase()) &&
00251 (uintptr_t) ptr < ((uintptr_t) persistentheap->getPersistentSegmentBase() + PERSISTENTHEAP_SIZE))
00252 {
00253
00254
00255
00256 objSize = persistentHeap::objectSize (ptr);
00257
00258 if (objSize >= sz) {
00259 return ptr;
00260 }
00261 } else {
00262 objSize = GENERIC_OBJSIZE(ptr);
00263 }
00264
00265
00266 void * buf = pmalloc_internal (sz);
00267
00268
00269
00270
00271 size_t minSize = (objSize < sz) ? objSize : sz;
00272 tx = _ITM_getTransaction();
00273 _ITM_memcpyRtWt (tx, buf, ptr, minSize);
00274
00275
00276 free_internal (ptr);
00277
00278
00279 return buf;
00280 }
00281
00282
00283 extern "C" void * HOARD_REALLOC (void * ptr, size_t sz)
00284 {
00285 return prealloc_internal(ptr, sz);
00286 }
00287
00288
00289 extern "C" void * HOARD_REALLOC_TXN (void * ptr, size_t sz)
00290 {
00291 return prealloc_internal(ptr, sz);
00292 }
00293
00294
00295 extern "C" size_t HOARD_GET_USABLE_SIZE (void * ptr)
00296 {
00297 return threadHeap::objectSize (ptr);
00298 }
00299
00300
00301 #if 0
00302 extern "C" void malloc_stats (void)
00303 {
00304 TheWrapper.TheAllocator()->stats();
00305 }
00306 #endif
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316 __attribute__((tm_wrapping(malloc))) void *malloc_txn(size_t sz)
00317 {
00318 return malloc(sz);
00319 }
00320
00321 __attribute__((tm_wrapping(realloc))) void *realloc_txn(void *ptr, size_t sz)
00322 {
00323 return realloc(ptr, sz);
00324 }
00325
00326 __attribute__((tm_wrapping(free))) void free_txn(void *ptr)
00327 {
00328 free(ptr);
00329 }