spot  2.11.6
fixpool.hh
1 // -*- coding: utf-8 -*-
2 // Copyright (C) 2011, 2015-2018, 2020, 2022 Laboratoire de Recherche et
3 // Développement de l'Epita (LRDE)
4 //
5 // This file is part of Spot, a model checking library.
6 //
7 // Spot is free software; you can redistribute it and/or modify it
8 // under the terms of the GNU General Public License as published by
9 // the Free Software Foundation; either version 3 of the License, or
10 // (at your option) any later version.
11 //
12 // Spot is distributed in the hope that it will be useful, but WITHOUT
13 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 // License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program. If not, see <http://www.gnu.org/licenses/>.
19 
20 #pragma once
21 
22 #include <spot/misc/common.hh>
23 #include <spot/misc/clz.hh>
24 
25 #if SPOT_DEBUG && __has_include(<valgrind/memcheck.h>)
26 #undef USES_MEMCHECK_H
27 #define USES_MEMCHECK_H 1
28 #include <valgrind/memcheck.h>
29 #endif
30 
31 namespace spot
32 {
42  enum class pool_type { Safe , Unsafe };
43 
45  template<pool_type Kind>
46  class SPOT_API fixed_size_pool
47  {
48  public:
50  fixed_size_pool(size_t size)
51  : size_(
52  [](size_t size)
53  {
54  // to properly store chunks and freelist, we need size to be at
55  // least the size of a block_
56  if (size < sizeof(block_))
57  size = sizeof(block_);
58  // powers of 2 are a good alignment
59  if (!(size & (size-1)))
60  return size;
61  // small numbers are best aligned to the next power of 2
62  else if (size < alignof(std::max_align_t))
63  return size_t{1} << (CHAR_BIT*sizeof(size_t) - clz(size));
64  else
65  {
66  size_t mask = alignof(std::max_align_t)-1;
67  return (size + mask) & ~mask;
68  }
69  }(size)),
70  freelist_(nullptr),
71  chunklist_(nullptr)
72  {
73  new_chunk_();
74  }
75 
78  {
79  while (chunklist_)
80  {
81  chunk_* prev = chunklist_->prev;
82  ::operator delete(chunklist_);
83  chunklist_ = prev;
84  }
85  }
86 
88  void*
90  {
91  block_* f = freelist_;
92  // If we have free blocks available, return the first one.
93  if (f)
94  {
95 #ifdef USES_MEMCHECK_H
96  if (Kind == pool_type::Safe)
97  {
98  VALGRIND_MALLOCLIKE_BLOCK(f, size_, 0, false);
99  // field f->next is initialized: prevents valgrind from
100  // complaining about jumps depending on uninitialized memory
101  VALGRIND_MAKE_MEM_DEFINED(f, sizeof(block_*));
102  }
103 #endif
104  freelist_ = f->next;
105  return f;
106  }
107 
108  // Else, create a block out of the last chunk of allocated
109  // memory.
110 
111  // If all the last chunk has been used, allocate one more.
112  if (free_start_ + size_ > free_end_)
113  new_chunk_();
114 
115  void* res = free_start_;
116  free_start_ += size_;
117 #ifdef USES_MEMCHECK_H
118  if (Kind == pool_type::Safe)
119  {
120  VALGRIND_MALLOCLIKE_BLOCK(res, size_, 0, false);
121  }
122 #endif
123  return res;
124  }
125 
132  void
133  deallocate(void* ptr)
134  {
135  SPOT_ASSERT(ptr);
136  block_* b = reinterpret_cast<block_*>(ptr);
137  b->next = freelist_;
138  freelist_ = b;
139 #ifdef USES_MEMCHECK_H
140  if (Kind == pool_type::Safe)
141  {
142  VALGRIND_FREELIKE_BLOCK(ptr, 0);
143  }
144 #endif
145  }
146 
147  private:
148  void new_chunk_()
149  {
150  const size_t requested = (size_ > 128 ? size_ : 128) * 8192 - 64;
151  chunk_* c = reinterpret_cast<chunk_*>(::operator new(requested));
152  c->prev = chunklist_;
153  chunklist_ = c;
154 
155  free_start_ = c->data_ + size_;
156  free_end_ = c->data_ + requested;
157  }
158 
159 
160  const size_t size_;
161  struct block_ { block_* next; }* freelist_;
162  char* free_start_;
163  char* free_end_;
164  // chunk = several agglomerated blocks
165  union chunk_ { chunk_* prev; char data_[1]; }* chunklist_;
166  };
167 }
A fixed-size memory pool implementation.
Definition: fixpool.hh:47
void * allocate()
Allocate size bytes of memory.
Definition: fixpool.hh:89
void deallocate(void *ptr)
Recycle size bytes of memory.
Definition: fixpool.hh:133
~fixed_size_pool()
Free any memory allocated by this pool.
Definition: fixpool.hh:77
fixed_size_pool(size_t size)
Create a pool allocating objects of size bytes.
Definition: fixpool.hh:50
Definition: automata.hh:27
pool_type
Definition: fixpool.hh:42

Please direct any question, comment, or bug report to the Spot mailing list at spot@lrde.epita.fr.
Generated on Fri Feb 27 2015 10:00:07 for spot by doxygen 1.9.1