Cgl  0.60.3
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CoinAlloc.hpp
Go to the documentation of this file.
1 /* $Id: CoinAlloc.hpp 2083 2019-01-06 19:38:09Z unxusr $ */
2 // Copyright (C) 2007, International Business Machines
3 // Corporation and others. All Rights Reserved.
4 // This code is licensed under the terms of the Eclipse Public License (EPL).
5 
6 #ifndef CoinAlloc_hpp
7 #define CoinAlloc_hpp
8 
9 #include "CoinUtilsConfig.h"
10 #include <cstdlib>
11 
12 #if !defined(COINUTILS_MEMPOOL_MAXPOOLED)
13 #define COINUTILS_MEMPOOL_MAXPOOLED -1
14 #endif
15 
16 #if (COINUTILS_MEMPOOL_MAXPOOLED >= 0)
17 
18 #ifndef COINUTILS_MEMPOOL_ALIGNMENT
19 #define COINUTILS_MEMPOOL_ALIGNMENT 16
20 #endif
21 
22 /* Note:
23  This memory pool implementation assumes that sizeof(size_t) and
24  sizeof(void*) are both <= COINUTILS_MEMPOOL_ALIGNMENT.
25  Choosing an alignment of 4 will cause segfault on 64-bit platforms and may
26  lead to bad performance on 32-bit platforms. So 8 is a mnimum recommended
27  alignment. Probably 16 does not waste too much space either and may be even
28  better for performance. One must play with it.
29 */
30 
31 //#############################################################################
32 
33 #if (COINUTILS_MEMPOOL_ALIGNMENT == 16)
34 static const std::size_t CoinAllocPtrShift = 4;
35 static const std::size_t CoinAllocRoundMask = ~((std::size_t)15);
36 #elif (COINUTILS_MEMPOOL_ALIGNMENT == 8)
37 static const std::size_t CoinAllocPtrShift = 3;
38 static const std::size_t CoinAllocRoundMask = ~((std::size_t)7);
39 #else
40 #error "COINUTILS_MEMPOOL_ALIGNMENT must be defined as 8 or 16 (or this code needs to be changed :-)"
41 #endif
42 
43 //#############################################################################
44 
45 #ifndef COIN_MEMPOOL_SAVE_BLOCKHEADS
46 #define COIN_MEMPOOL_SAVE_BLOCKHEADS 0
47 #endif
48 
49 //#############################################################################
50 
51 class CoinMempool {
52 private:
53 #if (COIN_MEMPOOL_SAVE_BLOCKHEADS == 1)
54  char **block_heads;
55  std::size_t block_num;
56  std::size_t max_block_num;
57 #endif
58 #if defined(COINUTILS_PTHREADS) && (COINUTILS_PTHREAD == 1)
59  pthread_mutex_t mutex_;
60 #endif
61  int last_block_size_;
62  char *first_free_;
63  const std::size_t entry_size_;
64 
65 private:
66  CoinMempool(const CoinMempool &);
67  CoinMempool &operator=(const CoinMempool &);
68 
69 private:
70  char *allocate_new_block();
71  inline void lock_mutex()
72  {
73 #if defined(COINUTILS_PTHREADS) && (COINUTILS_PTHREAD == 1)
74  pthread_mutex_lock(&mutex_);
75 #endif
76  }
77  inline void unlock_mutex()
78  {
79 #if defined(COINUTILS_PTHREADS) && (COINUTILS_PTHREAD == 1)
80  pthread_mutex_unlock(&mutex_);
81 #endif
82  }
83 
84 public:
85  CoinMempool(std::size_t size = 0);
86  ~CoinMempool();
87 
88  char *alloc();
89  inline void dealloc(char *p)
90  {
91  char **pp = (char **)p;
92  lock_mutex();
93  *pp = first_free_;
94  first_free_ = p;
95  unlock_mutex();
96  }
97 };
98 
99 //#############################################################################
100 
113 class CoinAlloc {
114 private:
115  CoinMempool *pool_;
116  int maxpooled_;
117 
118 public:
119  CoinAlloc();
120  ~CoinAlloc() {}
121 
122  inline void *alloc(const std::size_t n)
123  {
124  if (maxpooled_ <= 0) {
125  return std::malloc(n);
126  }
127  char *p = NULL;
128  const std::size_t to_alloc = ((n + COINUTILS_MEMPOOL_ALIGNMENT - 1) & CoinAllocRoundMask) + COINUTILS_MEMPOOL_ALIGNMENT;
129  CoinMempool *pool = NULL;
130  if (maxpooled_ > 0 && to_alloc >= (size_t)maxpooled_) {
131  p = static_cast< char * >(std::malloc(to_alloc));
132  if (p == NULL)
133  throw std::bad_alloc();
134  } else {
135  pool = pool_ + (to_alloc >> CoinAllocPtrShift);
136  p = pool->alloc();
137  }
138  *((CoinMempool **)p) = pool;
139  return static_cast< void * >(p + COINUTILS_MEMPOOL_ALIGNMENT);
140  }
141 
142  inline void dealloc(void *p)
143  {
144  if (maxpooled_ <= 0) {
145  std::free(p);
146  return;
147  }
148  if (p) {
149  char *base = static_cast< char * >(p) - COINUTILS_MEMPOOL_ALIGNMENT;
150  CoinMempool *pool = *((CoinMempool **)base);
151  if (!pool) {
152  std::free(base);
153  } else {
154  pool->dealloc(base);
155  }
156  }
157  }
158 };
159 
160 extern CoinAlloc CoinAllocator;
161 
162 //#############################################################################
163 
164 #if defined(COINUTILS_MEMPOOL_OVERRIDE_NEW) && (COINUTILS_MEMPOOL_OVERRIDE_NEW == 1)
165 void *operator new(std::size_t size) throw(std::bad_alloc);
166 void *operator new[](std::size_t) throw(std::bad_alloc);
167 void operator delete(void *)throw();
168 void operator delete[](void *) throw();
169 void *operator new(std::size_t, const std::nothrow_t &) throw();
170 void *operator new[](std::size_t, const std::nothrow_t &) throw();
171 void operator delete(void *, const std::nothrow_t &)throw();
172 void operator delete[](void *, const std::nothrow_t &) throw();
173 #endif
174 
175 #endif /*(COINUTILS_MEMPOOL_MAXPOOLED >= 0)*/
176 #endif
177 
178 /* vi: softtabstop=2 shiftwidth=2 expandtab tabstop=2
179 */