LIBINT 2.7.2
src/bin/libint/memory.h
1/*
2 * Copyright (C) 2004-2021 Edward F. Valeev
3 *
4 * This file is part of Libint.
5 *
6 * Libint is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * Libint is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with Libint. If not, see <http://www.gnu.org/licenses/>.
18 *
19 */
20
21#include <limits.h>
22#include <list>
23#include <smart_ptr.h>
24
25#ifndef _libint2_src_bin_libint_memory_h_
26#define _libint2_src_bin_libint_memory_h_
27
28namespace libint2 {
29
33 template <typename A, typename S>
35 {
36 public:
37 typedef A Address;
38 typedef S Size;
39
40 MemoryBlock(const Address& address, const Size& size, bool free,
41 const SafePtr<MemoryBlock>& left,
42 const SafePtr<MemoryBlock>& right) :
43 address_(address), size_(size), free_(free),
44 left_(left), right_(right)
45 {
46 }
47 MemoryBlock(const MemoryBlock& other) :
48 address_(other.address_), size_(other.size_), free_(other.free_),
49 left_(other.left_), right_(other.right_)
50 {
51 }
52
53 ~MemoryBlock() {}
54
56 const MemoryBlock& operator=(const MemoryBlock& other) {
57 address_ = other.address_;
58 size_ = other.size_;
59 free_ = other.free_;
60 left_ = other.left_;
61 right_ = other.right_;
62 return *this;
63 }
64
66 Address address() const { return address_; }
68 Size size() const { return size_; }
70 bool free() const { return free_; }
72 SafePtr<MemoryBlock> left() const { return left_; }
74 SafePtr<MemoryBlock> right() const { return right_; }
76 void left(const SafePtr<MemoryBlock>& l) { left_ = l; }
78 void right(const SafePtr<MemoryBlock>& r) { right_ = r; }
79
81 void set_address(const Address& address) { address_ = address; }
83 void set_size(const Size& size) { size_ = size; }
85 void set_free(bool free) { free_ = free; }
86
88 static bool size_less_than(const SafePtr<MemoryBlock>& i,
89 const SafePtr<MemoryBlock>& j) {
90 return i->size() < j->size();
91 }
95 static bool size_eq(SafePtr<MemoryBlock> i, Size sz) {
96 return i->size() == sz;
97 }
101 static bool size_geq(SafePtr<MemoryBlock> i, Size sz) {
102 return i->size() >= sz;
103 }
105 static bool address_less_than(const SafePtr<MemoryBlock>& i,
106 const SafePtr<MemoryBlock>& j) {
107 return i->address() < j->address();
108 }
112 static bool address_eq(SafePtr<MemoryBlock> i, Address a) {
113 return i->address() == a;
114 }
116 static bool is_free(const SafePtr<MemoryBlock>& i) {
117 return i->free();
118 }
119
121 const MemoryBlock& merge(const MemoryBlock& other) {
122 if (address() > other.address()) {
123 address_ = other.address_;
124 }
125 size_ += other.size();
126 return *this;
127 }
128
129 private:
130 Address address_;
131 Size size_;
132 bool free_;
133 typedef MemoryBlock<Address,Size> this_type;
134 SafePtr<this_type> left_;
135 SafePtr<MemoryBlock> right_;
136
137 MemoryBlock();
138 };
139
146 public:
148 typedef intptr_t Address;
149 typedef size_t Size;
151
152 static const Address InvalidAddress = -1;
153
154 protected:
155 typedef std::list< SafePtr<MemBlock> > memblkset;
156
157 private:
159 Size maxmem_;
161 memblkset blks_;
163 SafePtr<MemBlock> superblock_;
165 Size max_memory_used_;
166
167 SafePtr<MemBlock> merge_blocks(const SafePtr<MemBlock>& left, const SafePtr<MemBlock>& right);
168 SafePtr<MemBlock> merge_to_superblock(const SafePtr<MemBlock>& blk);
169 void update_max_memory();
170
171
172 public:
173 virtual ~MemoryManager();
174
176 virtual Address alloc(const Size& size) =0;
178 virtual void free(const Address& address);
180 Size max_memory_used() const { return max_memory_used_; }
181
183 void reset();
184
185 protected:
186 MemoryManager(const Size& maxmem);
187
189 Size maxmem() const { return maxmem_; }
191 memblkset& blocks() { return blks_;}
193 SafePtr<MemBlock> superblock() const { return superblock_; }
195 SafePtr<MemBlock> steal_from_block(const SafePtr<MemBlock>& blk, const Size& size);
197 SafePtr<MemBlock> find_block(const Address& a);
198
199 };
200
201
207 public:
208 WorstFitMemoryManager(bool search_exact = true, const Size& maxsize = ULONG_MAX);
209 virtual ~WorstFitMemoryManager();
210
212 Address alloc(const Size& size) override;
213
214 private:
216 bool search_exact_;
217 };
218
226 public:
227 BestFitMemoryManager(bool search_exact = true, const Size& tight_fit = 0, const Size& maxsize = ULONG_MAX);
228 virtual ~BestFitMemoryManager();
229
231 Address alloc(const Size& size) override;
232
233 private:
235 bool search_exact_;
237 Size tight_fit_;
238 };
239
245 public:
246 FirstFitMemoryManager(bool search_exact = true, const Size& maxsize = ULONG_MAX);
247 virtual ~FirstFitMemoryManager();
248
250 Address alloc(const Size& size) override;
251
252 private:
254 bool search_exact_;
255 };
256
262 public:
263 LastFitMemoryManager(bool search_exact = true, const Size& maxsize = ULONG_MAX);
264 virtual ~LastFitMemoryManager();
265
267 Address alloc(const Size& size) override;
268
269 private:
271 bool search_exact_;
272 };
273
278 public:
279 static const unsigned int ntypes = 8;
280 SafePtr<MemoryManager> memman(unsigned int type) const;
281 std::string label(unsigned int type) const;
282 };
283
288 typedef std::list< MemoryManager::MemBlock > MemBlockSet;
289 bool size_lessthan(const MemoryManager::MemBlock& A, const MemoryManager::MemBlock& B);
290 bool address_lessthan(const MemoryManager::MemBlock& A, const MemoryManager::MemBlock& B);
294 void merge(MemBlockSet& blocks);
295
296};
297
298#endif
BestFitMemoryManager allocates memory by trying to find a suitable free block, which is is larger tha...
Definition: src/bin/libint/memory.h:225
Address alloc(const Size &size) override
Implementation of MemoryManager::alloc()
Definition: memory.cc:276
FirstFitMemoryManager allocates memory by finding first suitable free block.
Definition: src/bin/libint/memory.h:244
Address alloc(const Size &size) override
Implementation of MemoryManager::alloc()
Definition: memory.cc:362
LastFitMemoryManager allocates memory by finding last suitable free block.
Definition: src/bin/libint/memory.h:261
Address alloc(const Size &size) override
Implementation of MemoryManager::alloc()
Definition: memory.cc:436
MemoryBlock<Address,Size> describes a block of raw memory addressed via Address and size described by...
Definition: src/bin/libint/memory.h:35
void set_size(const Size &size)
Sets the size.
Definition: src/bin/libint/memory.h:83
SafePtr< MemoryBlock > right() const
Returns the right adjacent block.
Definition: src/bin/libint/memory.h:74
SafePtr< MemoryBlock > left() const
Returns the left adjacent block.
Definition: src/bin/libint/memory.h:72
const MemoryBlock & merge(const MemoryBlock &other)
Merge A to this (does not check if merge can happen – can_merge(*this,*A) must be already satisfied)....
Definition: src/bin/libint/memory.h:121
static bool address_eq(SafePtr< MemoryBlock > i, Address a)
Returns true if the address of *i equals a.
Definition: src/bin/libint/memory.h:112
static bool size_less_than(const SafePtr< MemoryBlock > &i, const SafePtr< MemoryBlock > &j)
Returns true if the size of *i is less than the size of *j.
Definition: src/bin/libint/memory.h:88
static bool is_free(const SafePtr< MemoryBlock > &i)
Returns true if *i is free.
Definition: src/bin/libint/memory.h:116
static bool address_less_than(const SafePtr< MemoryBlock > &i, const SafePtr< MemoryBlock > &j)
Returns true if the address of *i is less than the address of *j.
Definition: src/bin/libint/memory.h:105
Size size() const
Returns size.
Definition: src/bin/libint/memory.h:68
void set_address(const Address &address)
Sets the address.
Definition: src/bin/libint/memory.h:81
bool free() const
Returns true if the block is free.
Definition: src/bin/libint/memory.h:70
void set_free(bool free)
Sets block's free status.
Definition: src/bin/libint/memory.h:85
const MemoryBlock & operator=(const MemoryBlock &other)
copy A to this
Definition: src/bin/libint/memory.h:56
static bool size_geq(SafePtr< MemoryBlock > i, Size sz)
Returns true if the size of *i greater or equal than sz.
Definition: src/bin/libint/memory.h:101
void right(const SafePtr< MemoryBlock > &r)
Sets the right adjacent block.
Definition: src/bin/libint/memory.h:78
Address address() const
Returns address.
Definition: src/bin/libint/memory.h:66
void left(const SafePtr< MemoryBlock > &l)
Sets the left adjacent block.
Definition: src/bin/libint/memory.h:76
static bool size_eq(SafePtr< MemoryBlock > i, Size sz)
Returns true if the size of *i equals sz.
Definition: src/bin/libint/memory.h:95
MemoryManagerFactory is a very dumb factory for MemoryManagers.
Definition: src/bin/libint/memory.h:277
Class MemoryManager handles allocation and deallocation of raw memory (stack) provided at runtime of ...
Definition: src/bin/libint/memory.h:145
memblkset & blocks()
Returns blocks.
Definition: src/bin/libint/memory.h:191
Size max_memory_used() const
Returns the max amount of memory used up to this moment.
Definition: src/bin/libint/memory.h:180
Size maxmem() const
Returns maxmem.
Definition: src/bin/libint/memory.h:189
SafePtr< MemBlock > find_block(const Address &a)
finds the block at Address a
Definition: memory.cc:80
virtual Address alloc(const Size &size)=0
Reserve a block and return its address.
intptr_t Address
Negative Address is used to denote an invalid address – hence signed integer.
Definition: src/bin/libint/memory.h:148
SafePtr< MemBlock > superblock() const
Returns the superblock.
Definition: src/bin/libint/memory.h:193
SafePtr< MemBlock > steal_from_block(const SafePtr< MemBlock > &blk, const Size &size)
steals size memory from block blk and returns the new block
Definition: memory.cc:50
void reset()
resets the state of MemoryManager; does not invalidate stats, however
Definition: memory.cc:181
virtual void free(const Address &address)
Release a block previously reserved using alloc.
Definition: memory.cc:92
WorstFitMemoryManager allocates memory by trying to find the largest-possible free block.
Definition: src/bin/libint/memory.h:206
Address alloc(const Size &size) override
Implementation of MemoryManager::alloc()
Definition: memory.cc:207
Defaults definitions for various parameters assumed by Libint.
Definition: algebra.cc:24
void merge(MemBlockSet &blocks)
Merge blocks, if possible.
Definition: memory.cc:590
bool can_merge(const MemoryManager::MemBlock &A, const MemoryManager::MemBlock &B)
True if can merge blocks.
Definition: memory.cc:580
MemoryManager::MemBlock MemBlock
Very useful nonmember functions to operate on MemBlocks and their containers.
Definition: src/bin/libint/memory.h:287