- Main Page
- Namespaces
- Classes
- Files
- Directories

- Search for |

- File List
- File Members

# CoinAlloc.hpp

Go to the documentation of this file.

    00001 /* $Id: CoinAlloc.hpp 1448 2011-06-19 15:34:41Z stefan $ */
    00002 // Copyright (C) 2007, International Business Machines
    00003 // Corporation and others.  All Rights Reserved.
    00004 // This code is licensed under the terms of the Eclipse Public License (EPL).
    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 /* Note:
    00023    This memory pool implementation assumes that sizeof(size_t) and
    00024    sizeof(void*) are both <= COINUTILS_MEMPOOL_ALIGNMENT.
    00025    Choosing an alignment of 4 will cause segfault on 64-bit platforms and may
    00026    lead to bad performance on 32-bit platforms. So 8 is a mnimum recommended
    00027    alignment. Probably 16 does not waste too much space either and may be even
    00028    better for performance. One must play with it.
    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 /*(COINUTILS_MEMPOOL_MAXPOOLED >= 0)*/
    00176 #endif