CoinAlloc.hpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006 #ifndef CoinAlloc_hpp
00007 #define CoinAlloc_hpp
00008
00009 #include "CoinUtilsConfig.h"
00010 #include <cstdlib>
00011
00012 #if !defined(COINUTILS_MEMPOOL_MAXPOOLED)
00013 # define COINUTILS_MEMPOOL_MAXPOOLED -1
00014 #endif
00015
00016 #if (COINUTILS_MEMPOOL_MAXPOOLED >= 0)
00017
00018 #ifndef COINUTILS_MEMPOOL_ALIGNMENT
00019 #define COINUTILS_MEMPOOL_ALIGNMENT 16
00020 #endif
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #if (COINUTILS_MEMPOOL_ALIGNMENT == 16)
00034 static const std::size_t CoinAllocPtrShift = 4;
00035 static const std::size_t CoinAllocRoundMask = ~((std::size_t)15);
00036 #elif (COINUTILS_MEMPOOL_ALIGNMENT == 8)
00037 static const std::size_t CoinAllocPtrShift = 3;
00038 static const std::size_t CoinAllocRoundMask = ~((std::size_t)7);
00039 #else
00040 #error "COINUTILS_MEMPOOL_ALIGNMENT must be defined as 8 or 16 (or this code needs to be changed :-)"
00041 #endif
00042
00043
00044
00045 #ifndef COIN_MEMPOOL_SAVE_BLOCKHEADS
00046 # define COIN_MEMPOOL_SAVE_BLOCKHEADS 0
00047 #endif
00048
00049
00050
00051 class CoinMempool
00052 {
00053 private:
00054 #if (COIN_MEMPOOL_SAVE_BLOCKHEADS == 1)
00055 char** block_heads;
00056 std::size_t block_num;
00057 std::size_t max_block_num;
00058 #endif
00059 #if defined(COINUTILS_PTHREADS) && (COINUTILS_PTHREAD == 1)
00060 pthread_mutex_t mutex_;
00061 #endif
00062 int last_block_size_;
00063 char* first_free_;
00064 const std::size_t entry_size_;
00065
00066 private:
00067 CoinMempool(const CoinMempool&);
00068 CoinMempool& operator=(const CoinMempool&);
00069
00070 private:
00071 char* allocate_new_block();
00072 inline void lock_mutex() {
00073 #if defined(COINUTILS_PTHREADS) && (COINUTILS_PTHREAD == 1)
00074 pthread_mutex_lock(&mutex_);
00075 #endif
00076 }
00077 inline void unlock_mutex() {
00078 #if defined(COINUTILS_PTHREADS) && (COINUTILS_PTHREAD == 1)
00079 pthread_mutex_unlock(&mutex_);
00080 #endif
00081 }
00082
00083 public:
00084 CoinMempool(std::size_t size = 0);
00085 ~CoinMempool();
00086
00087 char* alloc();
00088 inline void dealloc(char *p)
00089 {
00090 char** pp = (char**)p;
00091 lock_mutex();
00092 *pp = first_free_;
00093 first_free_ = p;
00094 unlock_mutex();
00095 }
00096 };
00097
00098
00099
00112 class CoinAlloc
00113 {
00114 private:
00115 CoinMempool* pool_;
00116 int maxpooled_;
00117 public:
00118 CoinAlloc();
00119 ~CoinAlloc() {}
00120
00121 inline void* alloc(const std::size_t n)
00122 {
00123 if (maxpooled_ <= 0) {
00124 return std::malloc(n);
00125 }
00126 char *p = NULL;
00127 const std::size_t to_alloc =
00128 ((n+COINUTILS_MEMPOOL_ALIGNMENT-1) & CoinAllocRoundMask) +
00129 COINUTILS_MEMPOOL_ALIGNMENT;
00130 CoinMempool* pool = NULL;
00131 if (maxpooled_ > 0 && to_alloc >= (size_t)maxpooled_) {
00132 p = static_cast<char*>(std::malloc(to_alloc));
00133 if (p == NULL) throw std::bad_alloc();
00134 } else {
00135 pool = pool_ + (to_alloc >> CoinAllocPtrShift);
00136 p = pool->alloc();
00137 }
00138 *((CoinMempool**)p) = pool;
00139 return static_cast<void*>(p+COINUTILS_MEMPOOL_ALIGNMENT);
00140 }
00141
00142 inline void dealloc(void* p)
00143 {
00144 if (maxpooled_ <= 0) {
00145 std::free(p);
00146 return;
00147 }
00148 if (p) {
00149 char* base = static_cast<char*>(p)-COINUTILS_MEMPOOL_ALIGNMENT;
00150 CoinMempool* pool = *((CoinMempool**)base);
00151 if (!pool) {
00152 std::free(base);
00153 } else {
00154 pool->dealloc(base);
00155 }
00156 }
00157 }
00158 };
00159
00160 extern CoinAlloc CoinAllocator;
00161
00162
00163
00164 #if defined(COINUTILS_MEMPOOL_OVERRIDE_NEW) && (COINUTILS_MEMPOOL_OVERRIDE_NEW == 1)
00165 void* operator new(std::size_t size) throw (std::bad_alloc);
00166 void* operator new[](std::size_t) throw (std::bad_alloc);
00167 void operator delete(void*) throw();
00168 void operator delete[](void*) throw();
00169 void* operator new(std::size_t, const std::nothrow_t&) throw();
00170 void* operator new[](std::size_t, const std::nothrow_t&) throw();
00171 void operator delete(void*, const std::nothrow_t&) throw();
00172 void operator delete[](void*, const std::nothrow_t&) throw();
00173 #endif
00174
00175 #endif
00176 #endif