- Main Page
- Modules
- Namespaces
- Classes
- Files
- Related Pages

- File List
- File Members

# /home/coin/SVN-release/Vol-1.2.0/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