Eneboo - Documentación para desarrolladores
src/hoard/src/heaplayers/mmapheap.h
Ir a la documentación de este archivo.
00001 /* -*- C++ -*- */
00002 
00003 /*
00004 
00005   Heap Layers: An Extensible Memory Allocation Infrastructure
00006   
00007   Copyright (C) 2000-2004 by Emery Berger
00008   http://www.cs.umass.edu/~emery
00009   emery@cs.umass.edu
00010   
00011   This program is free software; you can redistribute it and/or modify
00012   it under the terms of the GNU General Public License as published by
00013   the Free Software Foundation; either version 2 of the License, or
00014   (at your option) any later version.
00015   
00016   This program is distributed in the hope that it will be useful,
00017   but WITHOUT ANY WARRANTY; without even the implied warranty of
00018   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019   GNU General Public License for more details.
00020   
00021   You should have received a copy of the GNU General Public License
00022   along with this program; if not, write to the Free Software
00023   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00024 
00025 */
00026 
00027 #ifndef _MMAPHEAP_H_
00028 #define _MMAPHEAP_H_
00029 
00030 #if defined(_WIN32)
00031 #include <windows.h>
00032 #else
00033 // UNIX
00034 #include <sys/types.h>
00035 #include <sys/stat.h>
00036 #include <fcntl.h>
00037 #include <unistd.h>
00038 #include <sys/mman.h>
00039 #include <map>
00040 #endif
00041 
00042 #include "sassert.h"
00043 #include "myhashmap.h"
00044 #include "stlallocator.h"
00045 #include "freelistheap.h"
00046 #include "zoneheap.h"
00047 #include "lockedheap.h"
00048 #include "spinlock.h"
00049 #include "hldefines.h"
00050 
00051 #if HL_EXECUTABLE_HEAP
00052 #define HL_MMAP_PROTECTION_MASK (PROT_READ | PROT_WRITE | PROT_EXEC)
00053 #else
00054 #define HL_MMAP_PROTECTION_MASK (PROT_READ | PROT_WRITE)
00055 #endif
00056 
00057 #if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
00058 #define MAP_ANONYMOUS MAP_ANON
00059 #endif
00060 
00061 
00062 #include <new>
00063 
00064 #ifdef __MINGW32__
00065 #define _WIN32
00066 #include <windows.h>
00067 #endif
00068 
00075 namespace HL {
00076 
00077   class PrivateMmapHeap {
00078   public:
00079 
00081     enum { ZeroMemory = 1 };
00082 
00083 #if defined(_WIN32) 
00084 
00085     // Microsoft Windows aligns all memory to a 64K boundary.
00086     enum { Alignment = 64 * 1024 };
00087 
00088     inline void * malloc (size_t sz) {
00089       //    printf ("mmapheap: Size request = %d\n", sz);
00090 #if HL_EXECUTABLE_HEAP
00091       char * ptr = (char *) VirtualAlloc (NULL, sz, MEM_RESERVE | MEM_COMMIT | MEM_TOP_DOWN, PAGE_EXECUTE_READWRITE);
00092 #else
00093       char * ptr = (char *) VirtualAlloc (NULL, sz, MEM_RESERVE | MEM_COMMIT | MEM_TOP_DOWN, PAGE_READWRITE);
00094 #endif
00095       return (void *) ptr;
00096     }
00097   
00098     inline void free (void * ptr, size_t) {
00099       VirtualFree (ptr, 0, MEM_RELEASE);
00100     }
00101 
00102     inline void free (void * ptr) {
00103       VirtualFree (ptr, 0, MEM_RELEASE);
00104     }
00105   
00106     inline static size_t getSize (void * ptr) {
00107       MEMORY_BASIC_INFORMATION mbi;
00108       VirtualQuery (ptr, &mbi, sizeof(mbi));
00109       return (size_t) mbi.RegionSize;
00110     }
00111 
00112 #else
00113 
00114     virtual ~PrivateMmapHeap (void) {}
00115 
00116 #if defined(__SVR4)
00117 
00118     // Solaris aligns all memory to a 64K boundary.
00119     enum { Alignment = 64 * 1024 };
00120 #else
00121     // Linux and most other operating systems align memory to a 4K boundary.
00122     enum { Alignment = 4 * 1024 };
00123 #endif
00124 
00125     inline void * malloc (size_t sz) {
00126 #if defined(MAP_ALIGN) && defined(MAP_ANON)
00127       // Request memory aligned to the Alignment value above.
00128       void * ptr = mmap ((char *) Alignment, sz, HL_MMAP_PROTECTION_MASK, MAP_PRIVATE | MAP_ALIGN | MAP_ANON, -1, 0);
00129 #elif !defined(MAP_ANONYMOUS)
00130       static int fd = ::open ("/dev/zero", O_RDWR);
00131       void * ptr = mmap (NULL, sz, HL_MMAP_PROTECTION_MASK, MAP_PRIVATE, fd, 0);
00132 #else
00133       void * ptr = mmap (NULL, sz, HL_MMAP_PROTECTION_MASK, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
00134 #endif
00135       if (ptr == MAP_FAILED) {
00136         ptr = NULL;
00137       }
00138       return ptr;
00139     }
00140     
00141 #if 1
00142     inline void free (void * ptr) {
00143       abort();
00144       munmap (reinterpret_cast<char *>(ptr), getSize(ptr));
00145     }
00146 
00147     inline size_t getSize (void * ptr) {
00148       ptr = ptr;
00149       abort();
00150       return Alignment; // Obviously broken. Such is life.
00151     }
00152 #endif
00153 
00154     void free (void * ptr, size_t sz)
00155     {
00156       if ((long) sz < 0) {
00157         abort();
00158       }
00159 
00160       munmap (reinterpret_cast<char *>(ptr), sz);
00161     }
00162 
00163 #endif
00164 
00165   };
00166 
00167 
00168   class MmapHeap : public PrivateMmapHeap {
00169 #if !defined(_WIN32)
00170 
00171   private:
00172 
00173     class MyHeap : public LockedHeap<SpinLockType, FreelistHeap<ZoneHeap<PrivateMmapHeap, 16384 - 16> > > {}; // FIX ME: 16 = size of ZoneHeap header.
00174 
00175     typedef MyHashMap<void *, size_t, MyHeap> mapType;
00176 
00177   protected:
00178     mapType MyMap;
00179 
00180     SpinLockType MyMapLock;
00181 
00182   public:
00183     inline void * malloc (size_t sz) {
00184       void * ptr = PrivateMmapHeap::malloc (sz);
00185       MyMapLock.lock();
00186       MyMap.set (ptr, sz);
00187       MyMapLock.unlock();
00188       assert (reinterpret_cast<size_t>(ptr) % Alignment == 0);
00189       return const_cast<void *>(ptr);
00190     }
00191 
00192     inline size_t getSize (void * ptr) {
00193       MyMapLock.lock();
00194       size_t sz = MyMap.get (ptr);
00195       MyMapLock.unlock();
00196       return sz;
00197     }
00198 
00199     // WORKAROUND: apparent gcc bug.
00200     void free (void * ptr, size_t sz) {
00201       PrivateMmapHeap::free (ptr, sz);
00202     }
00203 
00204     inline void free (void * ptr) {
00205       assert (reinterpret_cast<size_t>(ptr) % Alignment == 0);
00206       MyMapLock.lock();
00207       size_t sz = MyMap.get (ptr);
00208       PrivateMmapHeap::free (ptr, sz);
00209       MyMap.erase (ptr);
00210       MyMapLock.unlock();
00211     }
00212 #endif
00213   };
00214 
00215 }
00216 
00217 #endif
 Todo Clases Namespaces Archivos Funciones Variables 'typedefs' Enumeraciones Valores de enumeraciones Propiedades Amigas 'defines'