/home/coin/SVN-release/CoinAll-1.1.0/CoinUtils/src/CoinAlloc.hpp

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

Generated on Sun Nov 14 14:06:32 2010 for Coin-All by  doxygen 1.4.7