xref: /aosp_15_r20/external/ComputeLibrary/src/runtime/PoolManager.cpp (revision c217d954acce2dbc11938adb493fc0abd69584f3)
1*c217d954SCole Faust /*
2*c217d954SCole Faust  * Copyright (c) 2017-2020 Arm Limited.
3*c217d954SCole Faust  *
4*c217d954SCole Faust  * SPDX-License-Identifier: MIT
5*c217d954SCole Faust  *
6*c217d954SCole Faust  * Permission is hereby granted, free of charge, to any person obtaining a copy
7*c217d954SCole Faust  * of this software and associated documentation files (the "Software"), to
8*c217d954SCole Faust  * deal in the Software without restriction, including without limitation the
9*c217d954SCole Faust  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10*c217d954SCole Faust  * sell copies of the Software, and to permit persons to whom the Software is
11*c217d954SCole Faust  * furnished to do so, subject to the following conditions:
12*c217d954SCole Faust  *
13*c217d954SCole Faust  * The above copyright notice and this permission notice shall be included in all
14*c217d954SCole Faust  * copies or substantial portions of the Software.
15*c217d954SCole Faust  *
16*c217d954SCole Faust  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17*c217d954SCole Faust  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18*c217d954SCole Faust  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19*c217d954SCole Faust  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20*c217d954SCole Faust  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21*c217d954SCole Faust  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22*c217d954SCole Faust  * SOFTWARE.
23*c217d954SCole Faust  */
24*c217d954SCole Faust #include "arm_compute/runtime/PoolManager.h"
25*c217d954SCole Faust 
26*c217d954SCole Faust #include "arm_compute/core/Error.h"
27*c217d954SCole Faust #include "arm_compute/runtime/IMemoryPool.h"
28*c217d954SCole Faust 
29*c217d954SCole Faust #include <algorithm>
30*c217d954SCole Faust #include <list>
31*c217d954SCole Faust 
32*c217d954SCole Faust using namespace arm_compute;
33*c217d954SCole Faust 
PoolManager()34*c217d954SCole Faust PoolManager::PoolManager()
35*c217d954SCole Faust     : _free_pools(), _occupied_pools(), _sem(), _mtx()
36*c217d954SCole Faust {
37*c217d954SCole Faust }
38*c217d954SCole Faust 
lock_pool()39*c217d954SCole Faust IMemoryPool *PoolManager::lock_pool()
40*c217d954SCole Faust {
41*c217d954SCole Faust     ARM_COMPUTE_ERROR_ON_MSG(_free_pools.empty() && _occupied_pools.empty(), "Haven't setup any pools!");
42*c217d954SCole Faust 
43*c217d954SCole Faust     _sem->wait();
44*c217d954SCole Faust     arm_compute::lock_guard<arm_compute::Mutex> lock(_mtx);
45*c217d954SCole Faust     ARM_COMPUTE_ERROR_ON_MSG(_free_pools.empty(), "Empty pool must exist as semaphore has been signalled");
46*c217d954SCole Faust     _occupied_pools.splice(std::begin(_occupied_pools), _free_pools, std::begin(_free_pools));
47*c217d954SCole Faust     return _occupied_pools.front().get();
48*c217d954SCole Faust }
49*c217d954SCole Faust 
unlock_pool(IMemoryPool * pool)50*c217d954SCole Faust void PoolManager::unlock_pool(IMemoryPool *pool)
51*c217d954SCole Faust {
52*c217d954SCole Faust     ARM_COMPUTE_ERROR_ON_MSG(_free_pools.empty() && _occupied_pools.empty(), "Haven't setup any pools!");
53*c217d954SCole Faust 
54*c217d954SCole Faust     arm_compute::lock_guard<arm_compute::Mutex> lock(_mtx);
55*c217d954SCole Faust     auto it = std::find_if(std::begin(_occupied_pools), std::end(_occupied_pools), [pool](const std::unique_ptr<IMemoryPool> &pool_it)
56*c217d954SCole Faust     {
57*c217d954SCole Faust         return pool_it.get() == pool;
58*c217d954SCole Faust     });
59*c217d954SCole Faust     ARM_COMPUTE_ERROR_ON_MSG(it == std::end(_occupied_pools), "Pool to be unlocked couldn't be found!");
60*c217d954SCole Faust     _free_pools.splice(std::begin(_free_pools), _occupied_pools, it);
61*c217d954SCole Faust     _sem->signal();
62*c217d954SCole Faust }
63*c217d954SCole Faust 
register_pool(std::unique_ptr<IMemoryPool> pool)64*c217d954SCole Faust void PoolManager::register_pool(std::unique_ptr<IMemoryPool> pool)
65*c217d954SCole Faust {
66*c217d954SCole Faust     arm_compute::lock_guard<arm_compute::Mutex> lock(_mtx);
67*c217d954SCole Faust     ARM_COMPUTE_ERROR_ON_MSG(!_occupied_pools.empty(), "All pools should be free in order to register a new one!");
68*c217d954SCole Faust 
69*c217d954SCole Faust     // Set pool
70*c217d954SCole Faust     _free_pools.push_front(std::move(pool));
71*c217d954SCole Faust 
72*c217d954SCole Faust     // Update semaphore
73*c217d954SCole Faust     _sem = std::make_unique<arm_compute::Semaphore>(_free_pools.size());
74*c217d954SCole Faust }
75*c217d954SCole Faust 
release_pool()76*c217d954SCole Faust std::unique_ptr<IMemoryPool> PoolManager::release_pool()
77*c217d954SCole Faust {
78*c217d954SCole Faust     arm_compute::lock_guard<arm_compute::Mutex> lock(_mtx);
79*c217d954SCole Faust     ARM_COMPUTE_ERROR_ON_MSG(!_occupied_pools.empty(), "All pools should be free in order to release one!");
80*c217d954SCole Faust 
81*c217d954SCole Faust     if(!_free_pools.empty())
82*c217d954SCole Faust     {
83*c217d954SCole Faust         std::unique_ptr<IMemoryPool> pool = std::move(_free_pools.front());
84*c217d954SCole Faust         ARM_COMPUTE_ERROR_ON(_free_pools.front() != nullptr);
85*c217d954SCole Faust         _free_pools.pop_front();
86*c217d954SCole Faust 
87*c217d954SCole Faust         // Update semaphore
88*c217d954SCole Faust         _sem = std::make_unique<arm_compute::Semaphore>(_free_pools.size());
89*c217d954SCole Faust 
90*c217d954SCole Faust         return pool;
91*c217d954SCole Faust     }
92*c217d954SCole Faust 
93*c217d954SCole Faust     return nullptr;
94*c217d954SCole Faust }
95*c217d954SCole Faust 
clear_pools()96*c217d954SCole Faust void PoolManager::clear_pools()
97*c217d954SCole Faust {
98*c217d954SCole Faust     arm_compute::lock_guard<arm_compute::Mutex> lock(_mtx);
99*c217d954SCole Faust     ARM_COMPUTE_ERROR_ON_MSG(!_occupied_pools.empty(), "All pools should be free in order to clear the PoolManager!");
100*c217d954SCole Faust     _free_pools.clear();
101*c217d954SCole Faust 
102*c217d954SCole Faust     // Update semaphore
103*c217d954SCole Faust     _sem = nullptr;
104*c217d954SCole Faust }
105*c217d954SCole Faust 
num_pools() const106*c217d954SCole Faust size_t PoolManager::num_pools() const
107*c217d954SCole Faust {
108*c217d954SCole Faust     arm_compute::lock_guard<arm_compute::Mutex> lock(_mtx);
109*c217d954SCole Faust 
110*c217d954SCole Faust     return _free_pools.size() + _occupied_pools.size();
111*c217d954SCole Faust }
112