xref: /aosp_15_r20/external/mesa3d/src/gallium/drivers/r600/sfn/sfn_memorypool.cpp (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /* -*- mesa-c++  -*-
2  * Copyright 2022 Collabora LTD
3  * Author: Gert Wollny <[email protected]>
4  * SPDX-License-Identifier: MIT
5  */
6 
7 #include "sfn_memorypool.h"
8 
9 #include <cassert>
10 #include <iostream>
11 
12 #ifdef HAVE_MEMORY_RESOURCE
13 #include <memory_resource>
14 #else
15 #include <list>
16 #include <stdlib.h>
17 #endif
18 
19 namespace r600 {
20 
21 #ifndef HAVE_MEMORY_RESOURCE
22 /* Fallback memory resource if the C++17 memory resource is not
23  * available
24  */
25 struct MemoryBacking {
26    ~MemoryBacking();
27    void *allocate(size_t size);
28    void *allocate(size_t size, size_t align);
29    std::list<void *> m_data;
30 };
31 #endif
32 
33 struct MemoryPoolImpl {
34 public:
35    MemoryPoolImpl();
36    ~MemoryPoolImpl();
37 #ifdef HAVE_MEMORY_RESOURCE
38    using MemoryBacking = ::std::pmr::monotonic_buffer_resource;
39 #endif
40    MemoryBacking *pool;
41 };
42 
MemoryPool()43 MemoryPool::MemoryPool() noexcept:
44     impl(nullptr)
45 {
46 }
47 
48 MemoryPool&
instance()49 MemoryPool::instance()
50 {
51    static thread_local MemoryPool me;
52    return me;
53 }
54 
55 void
free()56 MemoryPool::free()
57 {
58    delete impl;
59    impl = nullptr;
60 }
61 
62 void
initialize()63 MemoryPool::initialize()
64 {
65    if (!impl)
66       impl = new MemoryPoolImpl();
67 }
68 
69 void *
allocate(size_t size)70 MemoryPool::allocate(size_t size)
71 {
72    assert(impl);
73    return impl->pool->allocate(size);
74 }
75 
76 void *
allocate(size_t size,size_t align)77 MemoryPool::allocate(size_t size, size_t align)
78 {
79    assert(impl);
80    return impl->pool->allocate(size, align);
81 }
82 
83 void
release_all()84 MemoryPool::release_all()
85 {
86    instance().free();
87 }
88 
89 void
init_pool()90 init_pool()
91 {
92    MemoryPool::instance().initialize();
93 }
94 
95 void
release_pool()96 release_pool()
97 {
98    MemoryPool::release_all();
99 }
100 
101 void *
operator new(size_t size)102 Allocate::operator new(size_t size)
103 {
104    return MemoryPool::instance().allocate(size);
105 }
106 
107 void
operator delete(void * p,size_t size)108 Allocate::operator delete(void *p, size_t size)
109 {
110    // MemoryPool::instance().deallocate(p, size);
111 }
112 
MemoryPoolImpl()113 MemoryPoolImpl::MemoryPoolImpl() { pool = new MemoryBacking(); }
114 
~MemoryPoolImpl()115 MemoryPoolImpl::~MemoryPoolImpl() { delete pool; }
116 
117 #ifndef HAVE_MEMORY_RESOURCE
~MemoryBacking()118 MemoryBacking::~MemoryBacking()
119 {
120    for (auto p : m_data)
121       free(p);
122 }
123 
124 void *
allocate(size_t size)125 MemoryBacking::allocate(size_t size)
126 {
127    void *retval = malloc(size);
128    m_data.push_back(retval);
129    return retval;
130 }
131 
132 void *
allocate(size_t size,size_t align)133 MemoryBacking::allocate(size_t size, size_t align)
134 {
135    void *retval = aligned_alloc(align, size);
136    m_data.push_back(retval);
137    return retval;
138 }
139 
140 #endif
141 
142 } // namespace r600
143