Arcane  4.2.3.0
Developer documentation
Loading...
Searching...
No Matches
LazyMemoryPool.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2026 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* LazyMemoryPool.cc (C) 2000-2026 */
9/* */
10/* Zero buffers shared by the connectivities that are still lazy. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/mesh/internal/LazyMemoryPool.h"
15
17
18#include <utility>
19
20/*---------------------------------------------------------------------------*/
21/*---------------------------------------------------------------------------*/
22
23namespace Arcane::mesh
24{
25
26/*---------------------------------------------------------------------------*/
27/*---------------------------------------------------------------------------*/
28
29LazyMemoryPool::Buffer::
30Buffer()
31: m_zeros(MemoryUtils::getDefaultDataAllocator())
32{
33}
34
35/*---------------------------------------------------------------------------*/
36/*---------------------------------------------------------------------------*/
37
38ConstArrayView<Int32> LazyMemoryPool::
39grow(Buffer*& buffer, Int32 n)
40{
41 std::lock_guard<std::mutex> lk(m_mutex);
42 if (buffer && n <= buffer->m_zeros.size())
43 return buffer->m_zeros.constView();
44 Buffer* new_buffer = _smallestBuffer(n, false);
45 if (!new_buffer) {
46 Int32 size = 1024;
47 while (size < n)
48 size *= 2;
49 new_buffer = _addBuffer(size, false);
50 }
51 return _moveTo(buffer, new_buffer);
52}
53
54/*---------------------------------------------------------------------------*/
55/*---------------------------------------------------------------------------*/
56
57ConstArrayView<Int32> LazyMemoryPool::
58trim(Buffer*& buffer, Int32 n)
59{
60 std::lock_guard<std::mutex> lk(m_mutex);
61 // Another connectivity, possibly of another mesh, may already have allocated
62 // a buffer that fits: sharing it keeps one buffer for all of them.
63 Buffer* new_buffer = _smallestBuffer(n, true);
64 if (!new_buffer)
65 new_buffer = _addBuffer(n, true);
66 return _moveTo(buffer, new_buffer);
67}
68
69/*---------------------------------------------------------------------------*/
70/*---------------------------------------------------------------------------*/
71
72void LazyMemoryPool::
73release(Buffer*& buffer)
74{
75 std::lock_guard<std::mutex> lk(m_mutex);
76 _release(buffer);
77}
78
79/*---------------------------------------------------------------------------*/
80/*---------------------------------------------------------------------------*/
81
82LazyMemoryPool::Buffer* LazyMemoryPool::
83_smallestBuffer(Int32 n, bool only_exact)
84{
85 Buffer* best = nullptr;
86 for (const auto& b : m_buffers) {
87 if (only_exact && !b->m_is_exact)
88 continue;
89 if (b->m_zeros.size() < n)
90 continue;
91 if (!best || b->m_zeros.size() < best->m_zeros.size())
92 best = b.get();
93 }
94 return best;
95}
96
97/*---------------------------------------------------------------------------*/
98/*---------------------------------------------------------------------------*/
99
100LazyMemoryPool::Buffer* LazyMemoryPool::
101_addBuffer(Int32 size, bool is_exact)
102{
103 auto b = std::make_unique<Buffer>();
104 b->m_zeros.resize(size);
105 b->m_zeros.fill(0);
106 b->m_is_exact = is_exact;
107 Buffer* p = b.get();
108 m_buffers.push_back(std::move(b));
109 return p;
110}
111
112/*---------------------------------------------------------------------------*/
113/*---------------------------------------------------------------------------*/
121ConstArrayView<Int32> LazyMemoryPool::
122_moveTo(Buffer*& buffer, Buffer* new_buffer)
123{
124 if (buffer != new_buffer) {
125 ++new_buffer->m_nb_reader;
126 _release(buffer);
127 buffer = new_buffer;
128 }
129 return new_buffer->m_zeros.constView();
130}
131
132/*---------------------------------------------------------------------------*/
133/*---------------------------------------------------------------------------*/
134
135void LazyMemoryPool::
136_release(Buffer*& buffer)
137{
138 if (!buffer)
139 return;
140 --buffer->m_nb_reader;
141 if (buffer->m_nb_reader == 0) {
142 for (auto& b : m_buffers) {
143 if (b.get() == buffer) {
144 std::swap(b, m_buffers.back());
145 m_buffers.pop_back();
146 break;
147 }
148 }
149 }
150 buffer = nullptr;
151}
152
153/*---------------------------------------------------------------------------*/
154/*---------------------------------------------------------------------------*/
155
156} // namespace Arcane::mesh
157
158/*---------------------------------------------------------------------------*/
159/*---------------------------------------------------------------------------*/
Memory and allocator management functions.
ConstArrayView< T > constView() const
Constant view of this array.
Constant view of an array of type T.
ConstArrayView< Int32 > _moveTo(Buffer *&buffer, Buffer *new_buffer)
Moves the reader of buffer to new_buffer.
IMemoryAllocator * getDefaultDataAllocator()
Default allocator for data.
std::int32_t Int32
Signed integer type of 32 bits.
One zero buffer and the number of connectivities reading it.