1 /* 2 * Copyright 2009-2011 Fabrice Colin 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 */ 18 19 #ifndef _MEMORY_H 20 #define _MEMORY_H 21 22 #include "config.h" 23 #include <execinfo.h> 24 #include <string> 25 #include <iostream> 26 #ifdef HAVE_UMEM_H 27 #include <umem.h> 28 29 struct umem_allocator_tag 30 { 31 }; 32 33 /// Based on an example gven at http://www.ddj.com/cpp/184403759 34 template <typename T> 35 class umem_allocator 36 { 37 public: 38 typedef T value_type; 39 typedef value_type* pointer; 40 typedef const value_type* const_pointer; 41 typedef value_type& reference; 42 typedef const value_type& const_reference; 43 typedef typename std::size_t size_type; 44 typedef typename std::ptrdiff_t difference_type; 45 46 template <typename U> 47 struct rebind 48 { 49 typedef umem_allocator<U> other; 50 }; 51 umem_allocator()52 umem_allocator() 53 { 54 } 55 template <typename U> umem_allocator(const umem_allocator<U> &)56 umem_allocator(const umem_allocator<U> &) 57 { 58 } ~umem_allocator()59 ~umem_allocator() 60 { 61 } 62 address(reference x)63 static pointer address(reference x) 64 { 65 return &x; 66 } 67 address(const_reference x)68 static const_pointer address(const_reference x) 69 { 70 return x; 71 } 72 max_size()73 static size_type max_size() 74 { 75 return (std::numeric_limits<size_type>::max)(); 76 } 77 construct(pointer p,const value_type & t)78 static void construct(pointer p, const value_type &t) 79 { 80 new(p) T(t); 81 } 82 destroy(pointer p)83 static void destroy(pointer p) 84 { 85 p->~T(); 86 // Avoid unused variable warning 87 (void)p; 88 } 89 90 bool operator==(const umem_allocator &) const 91 { 92 return true; 93 } 94 95 bool operator!=(const umem_allocator &) const 96 { 97 return false; 98 } 99 allocate(size_type n)100 static pointer allocate(size_type n) 101 { 102 #ifdef DEBUG 103 std::cout << "umem_allocator::allocate: allocating " << n << std::endl; 104 #endif 105 void *ret = umem_alloc(n * sizeof(T), UMEM_DEFAULT); 106 if (ret == NULL) 107 { 108 throw std::bad_alloc(); 109 } 110 return static_cast<pointer>(ret); 111 } 112 allocate(const size_type n,const void * const)113 static pointer allocate(const size_type n, const void *const) 114 { 115 return allocate(n); 116 } 117 deallocate(pointer p,size_type n)118 static void deallocate(pointer p, size_type n) 119 { 120 if ((p == NULL) || 121 (n == 0)) 122 { 123 return; 124 } 125 126 #ifdef DEBUG 127 std::cout << "umem_allocator::deallocate: freeing " << n << std::endl; 128 #endif 129 umem_free(static_cast<void*>(p), n * sizeof(T)); 130 } 131 132 }; 133 134 /// Specialization for void. 135 template<> 136 class umem_allocator<void> 137 { 138 typedef void value_type; 139 typedef void* pointer; 140 typedef const void* const_pointer; 141 142 template <class U> 143 struct rebind 144 { 145 typedef umem_allocator<U> other; 146 }; 147 148 }; 149 #else 150 #ifdef HAVE_EXT_MALLOC_ALLOCATOR_H 151 #include <ext/malloc_allocator.h> 152 #endif 153 #endif 154 #ifdef HAVE_BOOST_POOL_POOLFWD_HPP 155 // This header should be available if poolfwd.hpp is 156 #include <boost/pool/pool_alloc.hpp> 157 #endif 158 159 #include "Visibility.h" 160 161 #ifdef HAVE_BOOST_POOL_POOLFWD_HPP 162 #ifdef HAVE_UMEM_H 163 // Memory pool with umem 164 typedef boost::pool_allocator<char, 165 umem_allocator> filter_allocator; 166 #else 167 // Memory pool with malloc (glibc's or any other implementation) 168 typedef boost::pool_allocator<char, 169 boost::default_user_allocator_malloc_free, 170 boost::details::pool::default_mutex, 131072> filter_allocator; 171 #endif 172 typedef std::basic_string<char, std::char_traits<char>, filter_allocator > dstring; 173 #else 174 #ifdef HAVE_UMEM_H 175 // No memory pool, plain umem 176 typedef umem_allocator<char> filter_allocator; 177 typedef std::basic_string<char, std::char_traits<char>, filter_allocator > dstring; 178 #else 179 #ifdef HAVE_EXT_MALLOC_ALLOCATOR_H 180 // No memory pool, plain malloc (glibc's or any other implementation) 181 typedef __gnu_cxx::malloc_allocator<char> filter_allocator; 182 typedef std::basic_string<char, std::char_traits<char>, filter_allocator > dstring; 183 #else 184 // No memory pool, default STL allocator 185 typedef std::allocator<char> filter_allocator; 186 typedef std::string dstring; 187 #endif 188 #endif 189 #endif 190 191 /// Memory usage related utilities. 192 class PINOT_EXPORT Memory 193 { 194 public: 195 /// Allocates a buffer. 196 static char *allocateBuffer(off_t length); 197 198 /// Frees a buffer. 199 static void freeBuffer(char *pBuffer, off_t length); 200 201 /// Returns the number of bytes in use. 202 static int getUsage(void); 203 204 /// Hints to the OS it can reclaim unused memory. 205 static void reclaim(void); 206 207 protected: 208 Memory(); 209 210 }; 211 212 #endif // _MEMORY_H 213