1 /* -*- mesa-c++ -*-
2 *
3 * Copyright (c) 2022 Collabora LTD
4 *
5 * Author: Gert Wollny <gert.wollny@collabora.com>
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * on the rights to use, copy, modify, merge, publish, distribute, sub
11 * license, and/or sell copies of the Software, and to permit persons to whom
12 * the Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the next
15 * paragraph) shall be included in all copies or substantial portions of the
16 * Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
22 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24 * USE OR OTHER DEALINGS IN THE SOFTWARE.
25 */
26
27 #include "sfn_memorypool.h"
28
29 #include <cassert>
30 #include <iostream>
31
32 #ifdef HAVE_MEMORY_RESOURCE
33 #include <memory_resource>
34 #else
35 #include <list>
36 #include <stdlib.h>
37 #endif
38
39 namespace r600 {
40
41 #ifndef HAVE_MEMORY_RESOURCE
42 /* Fallback memory resource if the C++17 memory resource is not
43 * avaliable
44 */
45 struct MemoryBacking {
46 ~MemoryBacking();
47 void *allocate(size_t size);
48 void *allocate(size_t size, size_t align);
49 std::list<void *> m_data;
50 };
51 #endif
52
53 struct MemoryPoolImpl {
54 public:
55 MemoryPoolImpl();
56 ~MemoryPoolImpl();
57 #ifdef HAVE_MEMORY_RESOURCE
58 using MemoryBacking = ::std::pmr::monotonic_buffer_resource;
59 #endif
60 MemoryBacking *pool;
61 };
62
MemoryPool()63 MemoryPool::MemoryPool() noexcept : impl(nullptr)
64 {
65 }
66
instance()67 MemoryPool& MemoryPool::instance()
68 {
69 static thread_local MemoryPool me;
70 me.initialize();
71 return me;
72 }
73
free()74 void MemoryPool::free()
75 {
76 delete impl;
77 impl = nullptr;
78 }
79
initialize()80 void MemoryPool::initialize()
81 {
82 if (!impl)
83 impl = new MemoryPoolImpl();
84 }
85
allocate(size_t size)86 void *MemoryPool::allocate(size_t size)
87 {
88 return impl->pool->allocate(size);
89 }
90
allocate(size_t size,size_t align)91 void *MemoryPool::allocate(size_t size, size_t align)
92 {
93 return impl->pool->allocate(size, align);
94 }
95
release_all()96 void MemoryPool::release_all()
97 {
98 instance().free();
99 }
100
init_pool()101 void init_pool()
102 {
103 MemoryPool::instance();
104 }
105
release_pool()106 void release_pool()
107 {
108 MemoryPool::release_all();
109 }
110
operator new(size_t size)111 void *Allocate::operator new(size_t size)
112 {
113 return MemoryPool::instance().allocate(size);
114 }
115
operator delete(void * p,size_t size)116 void Allocate::operator delete (void *p, size_t size)
117 {
118 // MemoryPool::instance().deallocate(p, size);
119 }
120
MemoryPoolImpl()121 MemoryPoolImpl::MemoryPoolImpl()
122 {
123 pool = new MemoryBacking();
124 }
125
~MemoryPoolImpl()126 MemoryPoolImpl::~MemoryPoolImpl()
127 {
128 delete pool;
129 }
130
131 #ifndef HAVE_MEMORY_RESOURCE
~MemoryBacking()132 MemoryBacking::~MemoryBacking()
133 {
134 for (auto p : m_data)
135 free(p);
136 }
137
allocate(size_t size)138 void *MemoryBacking::allocate(size_t size)
139 {
140 void *retval = malloc(size);
141 m_data.push_back(retval);
142 return retval;
143 }
144
allocate(size_t size,size_t align)145 void *MemoryBacking::allocate(size_t size, size_t align)
146 {
147 void *retval = aligned_alloc(align, size);
148 m_data.push_back(retval);
149 return retval;
150 }
151
152 #endif
153
154 }
155