• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

/build/buildd/coinutils-2.6.4/CoinUtils/src/CoinAlloc.hpp

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

Generated on Fri Oct 15 2010 18:21:02 by  doxygen 1.7.1