Eneboo - Documentación para desarrolladores
|
00001 // -*- C++ -*- 00002 00003 /* 00004 00005 Heap Layers: An Extensible Memory Allocation Infrastructure 00006 00007 Copyright (C) 2000-2003 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 _REDIRECTFREE_H_ 00028 #define _REDIRECTFREE_H_ 00029 00030 #include "fred.h" 00031 #include "guard.h" 00032 00033 namespace Hoard { 00034 00041 template <class Heap, 00042 typename SuperblockType_> 00043 class RedirectFree { 00044 public: 00045 00046 enum { Alignment = (int) Heap::Alignment }; 00047 00048 typedef SuperblockType_ SuperblockType; 00049 00050 inline void * malloc (size_t sz) { 00051 return _theHeap.malloc (sz); 00052 } 00053 00054 size_t getSize (void * ptr) { 00055 return Heap::getSize (ptr); 00056 } 00057 00058 SuperblockType * getSuperblock (void * ptr) { 00059 return Heap::getSuperblock (ptr); 00060 } 00061 00063 static inline void free (void * ptr) { 00064 // Get the superblock header. 00065 SuperblockType * s = reinterpret_cast<SuperblockType *>(Heap::getSuperblock (ptr)); 00066 00067 assert (s->isValidSuperblock()); 00068 00069 // Find out who the owner is. 00070 00071 typedef BaseHoardManager<SuperblockType> * baseHeapType; 00072 baseHeapType owner; 00073 00074 s->lock(); 00075 00076 // By acquiring the lock on the superblock (above), 00077 // we prevent it from moving up to a higher heap. 00078 // This eventually pins it down in one heap, 00079 // so this loop is guaranteed to terminate. 00080 // (It should generally take no more than two iterations.) 00081 00082 for (;;) { 00083 owner = reinterpret_cast<baseHeapType>(s->getOwner()); 00084 assert (owner != NULL); 00085 assert (owner->isValid()); 00086 // Lock the owner. If ownership changed between these two lines, 00087 // we'll detect it and try again. 00088 owner->lock(); 00089 if (owner == reinterpret_cast<baseHeapType>(s->getOwner())) { 00090 owner->free (ptr); 00091 owner->unlock(); 00092 s->unlock(); 00093 return; 00094 } 00095 owner->unlock(); 00096 00097 // Sleep a little. 00098 HL::Fred::yield(); 00099 } 00100 } 00101 00102 private: 00103 00104 Heap _theHeap; 00105 00106 }; 00107 00108 } 00109 00110 #endif