• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  * available
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:
64     impl(nullptr)
65 {
66 }
67 
68 MemoryPool&
instance()69 MemoryPool::instance()
70 {
71    static thread_local MemoryPool me;
72    return me;
73 }
74 
75 void
free()76 MemoryPool::free()
77 {
78    delete impl;
79    impl = nullptr;
80 }
81 
82 void
initialize()83 MemoryPool::initialize()
84 {
85    if (!impl)
86       impl = new MemoryPoolImpl();
87 }
88 
89 void *
allocate(size_t size)90 MemoryPool::allocate(size_t size)
91 {
92    assert(impl);
93    return impl->pool->allocate(size);
94 }
95 
96 void *
allocate(size_t size,size_t align)97 MemoryPool::allocate(size_t size, size_t align)
98 {
99    assert(impl);
100    return impl->pool->allocate(size, align);
101 }
102 
103 void
release_all()104 MemoryPool::release_all()
105 {
106    instance().free();
107 }
108 
109 void
init_pool()110 init_pool()
111 {
112    MemoryPool::instance().initialize();
113 }
114 
115 void
release_pool()116 release_pool()
117 {
118    MemoryPool::release_all();
119 }
120 
121 void *
operator new(size_t size)122 Allocate::operator new(size_t size)
123 {
124    return MemoryPool::instance().allocate(size);
125 }
126 
127 void
operator delete(void * p,size_t size)128 Allocate::operator delete(void *p, size_t size)
129 {
130    // MemoryPool::instance().deallocate(p, size);
131 }
132 
MemoryPoolImpl()133 MemoryPoolImpl::MemoryPoolImpl() { pool = new MemoryBacking(); }
134 
~MemoryPoolImpl()135 MemoryPoolImpl::~MemoryPoolImpl() { delete pool; }
136 
137 #ifndef HAVE_MEMORY_RESOURCE
~MemoryBacking()138 MemoryBacking::~MemoryBacking()
139 {
140    for (auto p : m_data)
141       free(p);
142 }
143 
144 void *
allocate(size_t size)145 MemoryBacking::allocate(size_t size)
146 {
147    void *retval = malloc(size);
148    m_data.push_back(retval);
149    return retval;
150 }
151 
152 void *
allocate(size_t size,size_t align)153 MemoryBacking::allocate(size_t size, size_t align)
154 {
155    void *retval = aligned_alloc(align, size);
156    m_data.push_back(retval);
157    return retval;
158 }
159 
160 #endif
161 
162 } // namespace r600
163