spot 2.11.2.dev
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
31namespace 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 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
void * allocate()
Allocate size bytes of memory.
Definition: fixpool.hh:89
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.4