blob: c49b8ead7703ed690e1c2c2ffe701f0c5fa18b31 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
|
// SPDX-License-Identifier: GPL-2.0-or-later
#include "pool.h"
#include <cstdint>
#include <cassert>
namespace Inkscape {
namespace Util {
// Round up x to the next multiple of m.
static std::byte *roundup(std::byte *x, std::size_t m)
{
auto y = reinterpret_cast<uintptr_t>(x);
y = ((y - 1) / m + 1) * m;
return reinterpret_cast<std::byte*>(y);
}
std::byte *Pool::allocate(std::size_t size, std::size_t alignment)
{
auto a = roundup(cur, alignment);
auto b = a + size;
if (b <= end) {
cur = b;
return a;
}
cursize = std::max(nextsize, size + alignment - 1);
buffers.emplace_back(std::make_unique<std::byte[]>(cursize));
// buffers.emplace_back(std::make_unique_for_overwrite<std::byte[]>(cursize)); // Todo: C++20.
resetblock();
nextsize = cursize * 3 / 2;
a = roundup(cur, alignment);
b = a + size;
assert(b <= end);
cur = b;
return a;
};
void Pool::free_all() noexcept
{
if (buffers.empty()) return;
if (buffers.size() > 1) {
buffers.front() = std::move(buffers.back());
buffers.resize(1);
}
resetblock();
}
void Pool::movefrom(Pool &other) noexcept
{
buffers = std::move(other.buffers);
cur = other.cur;
end = other.end;
cursize = other.cursize;
nextsize = other.nextsize;
other.buffers.clear();
other.cur = nullptr;
other.end = nullptr;
other.cursize = 0;
other.nextsize = 2;
}
void Pool::resetblock() noexcept
{
assert(!buffers.empty());
cur = buffers.back().get();
end = cur + cursize;
}
} // namespace Util
} // namespace Inkscape
|