xref: /aosp_15_r20/external/armnn/profiling/client/src/BufferManager.cpp (revision 89c4ff92f2867872bb9e2354d150bf0c8c502810)
1*89c4ff92SAndroid Build Coastguard Worker //
2*89c4ff92SAndroid Build Coastguard Worker // Copyright © 2019 Arm Ltd. All rights reserved.
3*89c4ff92SAndroid Build Coastguard Worker // SPDX-License-Identifier: MIT
4*89c4ff92SAndroid Build Coastguard Worker //
5*89c4ff92SAndroid Build Coastguard Worker 
6*89c4ff92SAndroid Build Coastguard Worker #include "BufferManager.hpp"
7*89c4ff92SAndroid Build Coastguard Worker #include "PacketBuffer.hpp"
8*89c4ff92SAndroid Build Coastguard Worker 
9*89c4ff92SAndroid Build Coastguard Worker namespace arm
10*89c4ff92SAndroid Build Coastguard Worker {
11*89c4ff92SAndroid Build Coastguard Worker 
12*89c4ff92SAndroid Build Coastguard Worker namespace pipe
13*89c4ff92SAndroid Build Coastguard Worker {
14*89c4ff92SAndroid Build Coastguard Worker 
BufferManager(unsigned int numberOfBuffers,unsigned int maxPacketSize)15*89c4ff92SAndroid Build Coastguard Worker BufferManager::BufferManager(unsigned int numberOfBuffers, unsigned int maxPacketSize)
16*89c4ff92SAndroid Build Coastguard Worker     : m_MaxBufferSize(maxPacketSize),
17*89c4ff92SAndroid Build Coastguard Worker       m_NumberOfBuffers(numberOfBuffers),
18*89c4ff92SAndroid Build Coastguard Worker       m_MaxNumberOfBuffers(numberOfBuffers * 3),
19*89c4ff92SAndroid Build Coastguard Worker       m_CurrentNumberOfBuffers(numberOfBuffers)
20*89c4ff92SAndroid Build Coastguard Worker {
21*89c4ff92SAndroid Build Coastguard Worker     Initialize();
22*89c4ff92SAndroid Build Coastguard Worker }
23*89c4ff92SAndroid Build Coastguard Worker 
Reserve(unsigned int requestedSize,unsigned int & reservedSize)24*89c4ff92SAndroid Build Coastguard Worker IPacketBufferPtr BufferManager::Reserve(unsigned int requestedSize, unsigned int& reservedSize)
25*89c4ff92SAndroid Build Coastguard Worker {
26*89c4ff92SAndroid Build Coastguard Worker     reservedSize = 0;
27*89c4ff92SAndroid Build Coastguard Worker #if !defined(ARMNN_DISABLE_THREADS)
28*89c4ff92SAndroid Build Coastguard Worker     std::unique_lock<std::mutex> availableListLock(m_AvailableMutex, std::defer_lock);
29*89c4ff92SAndroid Build Coastguard Worker #endif
30*89c4ff92SAndroid Build Coastguard Worker     if (requestedSize > m_MaxBufferSize)
31*89c4ff92SAndroid Build Coastguard Worker     {
32*89c4ff92SAndroid Build Coastguard Worker         return nullptr;
33*89c4ff92SAndroid Build Coastguard Worker     }
34*89c4ff92SAndroid Build Coastguard Worker #if !defined(ARMNN_DISABLE_THREADS)
35*89c4ff92SAndroid Build Coastguard Worker     availableListLock.lock();
36*89c4ff92SAndroid Build Coastguard Worker #endif
37*89c4ff92SAndroid Build Coastguard Worker     if (m_AvailableList.empty())
38*89c4ff92SAndroid Build Coastguard Worker     {
39*89c4ff92SAndroid Build Coastguard Worker         if (m_CurrentNumberOfBuffers < m_MaxNumberOfBuffers)
40*89c4ff92SAndroid Build Coastguard Worker         {
41*89c4ff92SAndroid Build Coastguard Worker             // create a temporary overflow/surge buffer and hand it back
42*89c4ff92SAndroid Build Coastguard Worker             m_CurrentNumberOfBuffers++;
43*89c4ff92SAndroid Build Coastguard Worker #if !defined(ARMNN_DISABLE_THREADS)
44*89c4ff92SAndroid Build Coastguard Worker             availableListLock.unlock();
45*89c4ff92SAndroid Build Coastguard Worker #endif
46*89c4ff92SAndroid Build Coastguard Worker             IPacketBufferPtr buffer = std::make_unique<PacketBuffer>(m_MaxBufferSize);
47*89c4ff92SAndroid Build Coastguard Worker             reservedSize = requestedSize;
48*89c4ff92SAndroid Build Coastguard Worker             return buffer;
49*89c4ff92SAndroid Build Coastguard Worker         }
50*89c4ff92SAndroid Build Coastguard Worker         else
51*89c4ff92SAndroid Build Coastguard Worker         {
52*89c4ff92SAndroid Build Coastguard Worker             // we have totally busted the limit. call a halt to new memory allocations.
53*89c4ff92SAndroid Build Coastguard Worker #if !defined(ARMNN_DISABLE_THREADS)
54*89c4ff92SAndroid Build Coastguard Worker             availableListLock.unlock();
55*89c4ff92SAndroid Build Coastguard Worker #endif
56*89c4ff92SAndroid Build Coastguard Worker             return nullptr;
57*89c4ff92SAndroid Build Coastguard Worker         }
58*89c4ff92SAndroid Build Coastguard Worker     }
59*89c4ff92SAndroid Build Coastguard Worker     IPacketBufferPtr buffer = std::move(m_AvailableList.back());
60*89c4ff92SAndroid Build Coastguard Worker     m_AvailableList.pop_back();
61*89c4ff92SAndroid Build Coastguard Worker #if !defined(ARMNN_DISABLE_THREADS)
62*89c4ff92SAndroid Build Coastguard Worker     availableListLock.unlock();
63*89c4ff92SAndroid Build Coastguard Worker #endif
64*89c4ff92SAndroid Build Coastguard Worker     reservedSize = requestedSize;
65*89c4ff92SAndroid Build Coastguard Worker     return buffer;
66*89c4ff92SAndroid Build Coastguard Worker }
67*89c4ff92SAndroid Build Coastguard Worker 
Commit(IPacketBufferPtr & packetBuffer,unsigned int size,bool notifyConsumer)68*89c4ff92SAndroid Build Coastguard Worker void BufferManager::Commit(IPacketBufferPtr& packetBuffer, unsigned int size, bool notifyConsumer)
69*89c4ff92SAndroid Build Coastguard Worker {
70*89c4ff92SAndroid Build Coastguard Worker #if !defined(ARMNN_DISABLE_THREADS)
71*89c4ff92SAndroid Build Coastguard Worker     std::unique_lock<std::mutex> readableListLock(m_ReadableMutex, std::defer_lock);
72*89c4ff92SAndroid Build Coastguard Worker #endif
73*89c4ff92SAndroid Build Coastguard Worker     packetBuffer->Commit(size);
74*89c4ff92SAndroid Build Coastguard Worker #if !defined(ARMNN_DISABLE_THREADS)
75*89c4ff92SAndroid Build Coastguard Worker     readableListLock.lock();
76*89c4ff92SAndroid Build Coastguard Worker #endif
77*89c4ff92SAndroid Build Coastguard Worker     m_ReadableList.push(std::move(packetBuffer));
78*89c4ff92SAndroid Build Coastguard Worker #if !defined(ARMNN_DISABLE_THREADS)
79*89c4ff92SAndroid Build Coastguard Worker     readableListLock.unlock();
80*89c4ff92SAndroid Build Coastguard Worker #endif
81*89c4ff92SAndroid Build Coastguard Worker     if (notifyConsumer)
82*89c4ff92SAndroid Build Coastguard Worker     {
83*89c4ff92SAndroid Build Coastguard Worker         FlushReadList();
84*89c4ff92SAndroid Build Coastguard Worker     }
85*89c4ff92SAndroid Build Coastguard Worker }
86*89c4ff92SAndroid Build Coastguard Worker 
Initialize()87*89c4ff92SAndroid Build Coastguard Worker void BufferManager::Initialize()
88*89c4ff92SAndroid Build Coastguard Worker {
89*89c4ff92SAndroid Build Coastguard Worker     m_AvailableList.reserve(m_NumberOfBuffers);
90*89c4ff92SAndroid Build Coastguard Worker     m_CurrentNumberOfBuffers = m_NumberOfBuffers;
91*89c4ff92SAndroid Build Coastguard Worker     for (unsigned int i = 0; i < m_NumberOfBuffers; ++i)
92*89c4ff92SAndroid Build Coastguard Worker     {
93*89c4ff92SAndroid Build Coastguard Worker         IPacketBufferPtr buffer = std::make_unique<PacketBuffer>(m_MaxBufferSize);
94*89c4ff92SAndroid Build Coastguard Worker         m_AvailableList.emplace_back(std::move(buffer));
95*89c4ff92SAndroid Build Coastguard Worker     }
96*89c4ff92SAndroid Build Coastguard Worker }
97*89c4ff92SAndroid Build Coastguard Worker 
Release(IPacketBufferPtr & packetBuffer)98*89c4ff92SAndroid Build Coastguard Worker void BufferManager::Release(IPacketBufferPtr& packetBuffer)
99*89c4ff92SAndroid Build Coastguard Worker {
100*89c4ff92SAndroid Build Coastguard Worker #if !defined(ARMNN_DISABLE_THREADS)
101*89c4ff92SAndroid Build Coastguard Worker     std::unique_lock<std::mutex> availableListLock(m_AvailableMutex, std::defer_lock);
102*89c4ff92SAndroid Build Coastguard Worker #endif
103*89c4ff92SAndroid Build Coastguard Worker     packetBuffer->Release();
104*89c4ff92SAndroid Build Coastguard Worker #if !defined(ARMNN_DISABLE_THREADS)
105*89c4ff92SAndroid Build Coastguard Worker     availableListLock.lock();
106*89c4ff92SAndroid Build Coastguard Worker #endif
107*89c4ff92SAndroid Build Coastguard Worker     if (m_AvailableList.size() <= m_NumberOfBuffers)
108*89c4ff92SAndroid Build Coastguard Worker     {
109*89c4ff92SAndroid Build Coastguard Worker         m_AvailableList.push_back(std::move(packetBuffer));
110*89c4ff92SAndroid Build Coastguard Worker     }
111*89c4ff92SAndroid Build Coastguard Worker     else
112*89c4ff92SAndroid Build Coastguard Worker     {
113*89c4ff92SAndroid Build Coastguard Worker         // we have been handed a temporary overflow/surge buffer get rid of it
114*89c4ff92SAndroid Build Coastguard Worker         packetBuffer->Destroy();
115*89c4ff92SAndroid Build Coastguard Worker         if (m_CurrentNumberOfBuffers > m_NumberOfBuffers)
116*89c4ff92SAndroid Build Coastguard Worker         {
117*89c4ff92SAndroid Build Coastguard Worker             --m_CurrentNumberOfBuffers;
118*89c4ff92SAndroid Build Coastguard Worker         }
119*89c4ff92SAndroid Build Coastguard Worker     }
120*89c4ff92SAndroid Build Coastguard Worker #if !defined(ARMNN_DISABLE_THREADS)
121*89c4ff92SAndroid Build Coastguard Worker     availableListLock.unlock();
122*89c4ff92SAndroid Build Coastguard Worker #endif
123*89c4ff92SAndroid Build Coastguard Worker }
124*89c4ff92SAndroid Build Coastguard Worker 
Reset()125*89c4ff92SAndroid Build Coastguard Worker void BufferManager::Reset()
126*89c4ff92SAndroid Build Coastguard Worker {
127*89c4ff92SAndroid Build Coastguard Worker     //This method should only be called once all threads have been joined
128*89c4ff92SAndroid Build Coastguard Worker #if !defined(ARMNN_DISABLE_THREADS)
129*89c4ff92SAndroid Build Coastguard Worker     std::lock_guard<std::mutex> readableListLock(m_ReadableMutex);
130*89c4ff92SAndroid Build Coastguard Worker     std::lock_guard<std::mutex> availableListLock(m_AvailableMutex);
131*89c4ff92SAndroid Build Coastguard Worker #endif
132*89c4ff92SAndroid Build Coastguard Worker 
133*89c4ff92SAndroid Build Coastguard Worker     m_AvailableList.clear();
134*89c4ff92SAndroid Build Coastguard Worker     std::queue<IPacketBufferPtr>().swap(m_ReadableList);
135*89c4ff92SAndroid Build Coastguard Worker 
136*89c4ff92SAndroid Build Coastguard Worker     Initialize();
137*89c4ff92SAndroid Build Coastguard Worker }
138*89c4ff92SAndroid Build Coastguard Worker 
GetReadableBuffer()139*89c4ff92SAndroid Build Coastguard Worker IPacketBufferPtr BufferManager::GetReadableBuffer()
140*89c4ff92SAndroid Build Coastguard Worker {
141*89c4ff92SAndroid Build Coastguard Worker #if !defined(ARMNN_DISABLE_THREADS)
142*89c4ff92SAndroid Build Coastguard Worker     std::unique_lock<std::mutex> readableListLock(m_ReadableMutex);
143*89c4ff92SAndroid Build Coastguard Worker #endif
144*89c4ff92SAndroid Build Coastguard Worker     if (!m_ReadableList.empty())
145*89c4ff92SAndroid Build Coastguard Worker     {
146*89c4ff92SAndroid Build Coastguard Worker         IPacketBufferPtr buffer = std::move(m_ReadableList.front());
147*89c4ff92SAndroid Build Coastguard Worker         m_ReadableList.pop();
148*89c4ff92SAndroid Build Coastguard Worker #if !defined(ARMNN_DISABLE_THREADS)
149*89c4ff92SAndroid Build Coastguard Worker         readableListLock.unlock();
150*89c4ff92SAndroid Build Coastguard Worker #endif
151*89c4ff92SAndroid Build Coastguard Worker         return buffer;
152*89c4ff92SAndroid Build Coastguard Worker     }
153*89c4ff92SAndroid Build Coastguard Worker     return nullptr;
154*89c4ff92SAndroid Build Coastguard Worker }
155*89c4ff92SAndroid Build Coastguard Worker 
MarkRead(IPacketBufferPtr & packetBuffer)156*89c4ff92SAndroid Build Coastguard Worker void BufferManager::MarkRead(IPacketBufferPtr& packetBuffer)
157*89c4ff92SAndroid Build Coastguard Worker {
158*89c4ff92SAndroid Build Coastguard Worker #if !defined(ARMNN_DISABLE_THREADS)
159*89c4ff92SAndroid Build Coastguard Worker     std::unique_lock<std::mutex> availableListLock(m_AvailableMutex, std::defer_lock);
160*89c4ff92SAndroid Build Coastguard Worker #endif
161*89c4ff92SAndroid Build Coastguard Worker     packetBuffer->MarkRead();
162*89c4ff92SAndroid Build Coastguard Worker #if !defined(ARMNN_DISABLE_THREADS)
163*89c4ff92SAndroid Build Coastguard Worker     availableListLock.lock();
164*89c4ff92SAndroid Build Coastguard Worker #endif
165*89c4ff92SAndroid Build Coastguard Worker     if (m_AvailableList.size() <= m_NumberOfBuffers)
166*89c4ff92SAndroid Build Coastguard Worker     {
167*89c4ff92SAndroid Build Coastguard Worker         m_AvailableList.push_back(std::move(packetBuffer));
168*89c4ff92SAndroid Build Coastguard Worker     }
169*89c4ff92SAndroid Build Coastguard Worker     else
170*89c4ff92SAndroid Build Coastguard Worker     {
171*89c4ff92SAndroid Build Coastguard Worker         // we have been handed a temporary overflow/surge buffer get rid of it
172*89c4ff92SAndroid Build Coastguard Worker         packetBuffer->Destroy();
173*89c4ff92SAndroid Build Coastguard Worker         if (m_CurrentNumberOfBuffers > m_NumberOfBuffers)
174*89c4ff92SAndroid Build Coastguard Worker         {
175*89c4ff92SAndroid Build Coastguard Worker             --m_CurrentNumberOfBuffers;
176*89c4ff92SAndroid Build Coastguard Worker         }
177*89c4ff92SAndroid Build Coastguard Worker     }
178*89c4ff92SAndroid Build Coastguard Worker #if !defined(ARMNN_DISABLE_THREADS)
179*89c4ff92SAndroid Build Coastguard Worker     availableListLock.unlock();
180*89c4ff92SAndroid Build Coastguard Worker #endif
181*89c4ff92SAndroid Build Coastguard Worker }
182*89c4ff92SAndroid Build Coastguard Worker 
SetConsumer(IConsumer * consumer)183*89c4ff92SAndroid Build Coastguard Worker void BufferManager::SetConsumer(IConsumer* consumer)
184*89c4ff92SAndroid Build Coastguard Worker {
185*89c4ff92SAndroid Build Coastguard Worker     m_Consumer = consumer;
186*89c4ff92SAndroid Build Coastguard Worker }
187*89c4ff92SAndroid Build Coastguard Worker 
FlushReadList()188*89c4ff92SAndroid Build Coastguard Worker void BufferManager::FlushReadList()
189*89c4ff92SAndroid Build Coastguard Worker {
190*89c4ff92SAndroid Build Coastguard Worker     // notify consumer that packet is ready to read
191*89c4ff92SAndroid Build Coastguard Worker     if (m_Consumer != nullptr)
192*89c4ff92SAndroid Build Coastguard Worker     {
193*89c4ff92SAndroid Build Coastguard Worker         m_Consumer->SetReadyToRead();
194*89c4ff92SAndroid Build Coastguard Worker     }
195*89c4ff92SAndroid Build Coastguard Worker }
196*89c4ff92SAndroid Build Coastguard Worker 
197*89c4ff92SAndroid Build Coastguard Worker } // namespace pipe
198*89c4ff92SAndroid Build Coastguard Worker 
199*89c4ff92SAndroid Build Coastguard Worker } // namespace arm
200