spot 2.11.6.dev
mspool.hh
1// -*- coding: utf-8 -*-
2// Copyright (C) 2011, 2013, 2015-2016, 2018, 2022 Laboratoire de
3// Recherche et Developpement 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 <unordered_map>
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{
33
36 {
37 static const size_t alignment_ = 2 * sizeof(size_t) - 1;
38 public:
41 : free_start_(nullptr), free_end_(nullptr), chunklist_(nullptr)
42 {
43 }
44
47 {
48 while (chunklist_)
49 {
50 chunk_* prev = chunklist_->prev;
51 free(chunklist_);
52 chunklist_ = prev;
53 }
54 }
55
56 size_t fixsize(size_t size) const
57 {
58 if (size < sizeof(block_))
59 size = sizeof(block_);
60
61 return (size + alignment_ - 1) & ~(alignment_ - 1);
62 }
63
65 void*
66 allocate(size_t size)
67 {
68 size = fixsize(size);
69
70 block_*& f = freelist_[size];
71 // If we have free blocks available, return the first one.
72 if (f)
73 {
74 block_* first = f;
75#ifdef USES_MEMCHECK_H
76 VALGRIND_MALLOCLIKE_BLOCK(f, size, 0, false);
77 // field f->next is initialized: prevents valgrind from complaining
78 // about jumps depending on uninitialized memory
79 VALGRIND_MAKE_MEM_DEFINED(f, sizeof(block_*));
80#endif
81 f = f->next;
82 return first;
83 }
84
85 // Else, create a block out of the last chunk of allocated
86 // memory.
87
88 // If all the last chunk has been used, allocate one more.
89 if (free_start_ + size > free_end_)
90 {
91 const size_t requested = (size > 128 ? size : 128) * 8192 - 64;
92 chunk_* c = reinterpret_cast<chunk_*>(malloc(requested));
93 if (!c)
94 throw std::bad_alloc();
95 c->prev = chunklist_;
96 chunklist_ = c;
97
98 free_start_ = c->data_ + size;
99 free_end_ = c->data_ + requested;
100 }
101
102 void* res = free_start_;
103 free_start_ += size;
104#ifdef USES_MEMCHECK_H
105 VALGRIND_MALLOCLIKE_BLOCK(res, size, 0, false);
106#endif
107 return res;
108 }
109
119 void
120 deallocate (const void* ptr, size_t size)
121 {
122 SPOT_ASSERT(ptr);
123 size = fixsize(size);
124 block_* b = reinterpret_cast<block_*>(const_cast<void*>(ptr));
125 block_*& f = freelist_[size];
126 b->next = f;
127 f = b;
128#ifdef USES_MEMCHECK_H
129 VALGRIND_FREELIKE_BLOCK(ptr, 0);
130#endif
131 }
132
133 private:
134 struct block_ { block_* next; };
135 std::unordered_map<size_t, block_*> freelist_;
136 char* free_start_;
137 char* free_end_;
138 // chunk = several agglomerated blocks
139 union chunk_ { chunk_* prev; char data_[1]; }* chunklist_;
140 };
141}
A multiple-size memory pool implementation.
Definition: mspool.hh:36
~multiple_size_pool()
Free any memory allocated by this pool.
Definition: mspool.hh:46
void * allocate(size_t size)
Allocate size bytes of memory.
Definition: mspool.hh:66
void deallocate(const void *ptr, size_t size)
Recycle size bytes of memory.
Definition: mspool.hh:120
multiple_size_pool()
Create a pool.
Definition: mspool.hh:40
Definition: automata.hh:27

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