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 _KINGSLEYHEAP_H_ 00028 #define _KINGSLEYHEAP_H_ 00029 00030 #include "segheap.h" 00031 00044 namespace Kingsley { 00045 00046 size_t class2Size (const int i); 00047 00048 #if defined(__sparc) && defined(__GNUC__) 00049 inline int popc (int v) { 00050 int r; 00051 asm volatile ("popc %1, %0" 00052 : "=r" (r) 00053 : "r" (v)); 00054 return r; 00055 } 00056 #endif 00057 00063 const int cl[16] = { 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4 }; 00064 00065 inline int size2Class (const size_t sz) { 00066 #if defined(__sparc) && defined(__GNUC__) 00067 // Adapted from _Hacker's Delight_, by Henry Warren (p.80) 00068 size_t x = sz; 00069 x = x | (x >> 1); 00070 x = x | (x >> 2); 00071 x = x | (x >> 4); 00072 x = x | (x >> 8); 00073 x = x | (x >> 16); 00074 return popc(x) - 3; 00075 #else 00076 if (sz < 128 ) { 00077 assert (class2Size(cl[sz >> 3]) >= sz); 00078 return cl[(sz - 1) >> 3]; 00079 } else { 00080 // 00081 // We know that the object is more than 128 bytes long, 00082 // so we can avoid iterating 5 times. 00083 // 00084 int c = 5; 00085 size_t sz1 = ((sz - 1) >> 5); 00086 while (sz1 > 7) { 00087 sz1 >>= 1; 00088 c++; 00089 } 00090 assert (class2Size(c) >= sz); 00091 return c; 00092 } 00093 #endif 00094 00095 } 00096 00097 inline size_t class2Size (const int i) { 00098 return (size_t) (1 << (i+3)); 00099 } 00100 00101 enum { NUMBINS = 29 }; 00102 00103 }; 00104 00113 namespace HL { 00114 00115 template <class PerClassHeap, class BigHeap> 00116 class KingsleyHeap : 00117 public StrictSegHeap<Kingsley::NUMBINS, 00118 Kingsley::size2Class, 00119 Kingsley::class2Size, 00120 PerClassHeap, 00121 BigHeap> {}; 00122 00123 }; 00124 00125 #endif