gem5 [DEVELOP-FOR-25.0]
Loading...
Searching...
No Matches
free_list.hh
Go to the documentation of this file.
1/*
2 * Copyright (c) 2024 The Board of Trustees of the Leland Stanford
3 * Junior University
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met: redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer;
10 * redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution;
13 * neither the name of the copyright holders nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#ifndef __BASE_FREE_LIST_HH__
31#define __BASE_FREE_LIST_HH__
32
33#include <algorithm>
34#include <cassert>
35#include <limits>
36#include <list>
37
38#include "base/logging.hh"
39
40namespace gem5
41{
42
43template <typename T>
45{
46 public:
47 struct Range
48 {
51
53 : base(base), size(size)
54 {
55 }
56
57 bool
58 contains(T x) const
59 {
60 return base <= x && x < base + size;
61 }
62
63 bool
64 precedes(T x) const
65 {
66 return base + size <= x;
67 }
68
69 bool
70 precedes(const Range &o) const
71 {
72 return precedes(o.base);
73 }
74
75 bool
76 overlaps(const Range &o) const
77 {
78 return !precedes(o) && !o.precedes(*this);
79 }
80 };
81
82 FreeList() = default;
83
85 {
87 }
88
89 private:
92 T _size = 0;
93
94 public:
95
97 void
99 {
100 _size += size;
101
102 // Finds first range whose base is greater than
103 // or equal to the insertion base.
104 auto it = std::lower_bound(
105 _ranges.begin(), _ranges.end(), base,
106 [] (const Range& range, T base) -> bool {
107 return range.base < base;
108 });
109
110 // Assert that this isn't a double free.
111 panic_if(it != _ranges.end() && it->overlaps(Range(base, size)),
112 "free list: double free!\n");
113 panic_if(it != _ranges.begin() &&
114 std::prev(it)->overlaps(Range(base, size)),
115 "free list: double free!\n");
116
117 // Merge left.
118 if (it != _ranges.begin()) {
119 auto prev = std::prev(it);
120 assert(prev->base + prev->size <= base);
121 if (prev->base + prev->size == base) {
122 base = prev->base;
123 size += prev->size;
124 _ranges.erase(prev);
125 }
126 }
127
128 // Merge right.
129 if (it != _ranges.end()) {
130 assert(base + size <= it->base);
131 if (base + size == it->base) {
132 size += it->size;
133 it = _ranges.erase(it);
134 }
135 }
136
137 // Insert new range.
138 _ranges.emplace(it, base, size);
139 }
140
145 std::optional<T>
147 {
148 assert(size > 0);
149
150 // Find the best-fit free range, i.e.,
151 // the smallest range whose size is greater than
152 // equal to the requested allocation size.
153 auto best_it = _ranges.end();
154 T best_size = std::numeric_limits<T>::max();
155 for (auto it = _ranges.begin(); it != _ranges.end(); ++it) {
156 if (size <= it->size && it->size <= best_size) {
157 best_it = it;
158 best_size = it->size;
159 }
160 }
161
162 // Allocation failed.
163 if (best_it == _ranges.end())
164 return std::nullopt;
165
166 // Allocation succeeded.
167 _size -= size;
168 assert(best_it != _ranges.end());
169 const T base = best_it->base;
170 best_it->base += size;
171 best_it->size -= size;
172 if (best_it->size == 0)
173 _ranges.erase(best_it);
174 return base;
175 }
176
178 T
179 size() const
180 {
181 return _size;
182 }
183
185 const RangeList&
186 ranges() const
187 {
188 return _ranges;
189 }
190};
191
192}
193
194#endif
const RangeList & ranges() const
Return a list of free ranges.
Definition free_list.hh:186
std::list< Range > RangeList
Definition free_list.hh:90
void insert(T base, T size)
Mark the range [base, base + size) as free.
Definition free_list.hh:98
FreeList(T base, T size)
Definition free_list.hh:84
RangeList _ranges
Definition free_list.hh:91
FreeList()=default
std::optional< T > allocate(T size)
Allocate a region of size.
Definition free_list.hh:146
T size() const
Return the number of free items.
Definition free_list.hh:179
STL list class.
Definition stl.hh:51
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
Definition logging.hh:246
Bitfield< 3 > x
Definition pagetable.hh:76
Copyright (c) 2024 Arm Limited All rights reserved.
Definition binary32.hh:36
bool contains(T x) const
Definition free_list.hh:58
Range(T base, T size)
Definition free_list.hh:52
bool overlaps(const Range &o) const
Definition free_list.hh:76
bool precedes(const Range &o) const
Definition free_list.hh:70
bool precedes(T x) const
Definition free_list.hh:64
std::list< TranslationGen::Range > RangeList

Generated on Mon May 26 2025 09:19:08 for gem5 by doxygen 1.13.2