usermode/library/malloc-hoard-old/src/wrapper.cpp

00001 
00002 //
00003 // The Hoard Multiprocessor Memory Allocator
00004 // www.hoard.org
00005 //
00006 // Author: Emery Berger, http://www.cs.utexas.edu/users/emery
00007 //
00008 // Copyright (c) 1998-2001, The University of Texas at Austin.
00009 //
00010 // This library is free software; you can redistribute it and/or modify
00011 // it under the terms of the GNU Library General Public License as
00012 // published by the Free Software Foundation, http://www.fsf.org.
00013 //
00014 // This library is distributed in the hope that it will be useful, but
00015 // WITHOUT ANY WARRANTY; without even the implied warranty of
00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017 // Library General Public License for more details.
00018 //
00020 
00021 /*
00022   wrapper.cpp
00023   ------------------------------------------------------------------------
00024   Implementations of malloc(), free(), etc. in terms of hoard.
00025   This lets us link in hoard in place of the stock malloc.
00026   ------------------------------------------------------------------------
00027   @(#) $Id: wrapper.cpp,v 1.40 2001/12/10 20:11:29 emery Exp $
00028   ------------------------------------------------------------------------
00029   Emery Berger                    | <http://www.cs.utexas.edu/users/emery>
00030   Department of Computer Sciences |             <http://www.cs.utexas.edu>
00031   University of Texas at Austin   |                <http://www.utexas.edu>
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 // Access exactly one instance of the global persistent heap
00052 // (which contains objects allocated in previous incarnations).
00053 // We create this object dynamically to avoid bloating the object code.
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 // Access exactly one instance of the process heap
00065 // (which contains the thread heaps).
00066 // We create this object dynamically to avoid bloating the object code.
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 //extern "C" __attribute__((tm_callable)) void * HOARD_MALLOC (size_t sz);
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                 /* Fall back to the standard persistent allocator. 
00111                  * Begin a new atomic block to force the compiler to fall through down the TM 
00112                  * instrumented path. Actually we are already in the transactional path so
00113                  * this atomic block should execute as a nested transaction.
00114                  */
00115                 //__tm_atomic 
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   // Zero out the malloc'd block.
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         /* Find out which heap this block has been allocated from. */
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                 //__tm_atomic 
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   //TODO
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   // If the existing object can hold the new size,
00220   // just return it.
00221 
00222   size_t objSize = threadHeap::objectSize (ptr);
00223 
00224   if (objSize >= sz) {
00225     return ptr;
00226   }
00227 
00228   // Allocate a new block of size sz.
00229 
00230   void * buf = HOARD_MALLOC (sz);
00231 
00232   // Copy the contents of the original object
00233   // up to the size of the new block.
00234 
00235   size_t minSize = (objSize < sz) ? objSize : sz;
00236   memcpy (buf, ptr, minSize);
00237 
00238   // Free the old block.
00239 
00240   HOARD_FREE (ptr);
00241 
00242   // Return a pointer to the new one.
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

Generated on Sat Apr 23 11:43:35 2011 for Mnemosyne by  doxygen 1.4.7