blob: 592d374817a4777e13d3a90c362a613133f9cb4e [file] [log] [blame]
Narumol Prangnawarat7be47ef2019-09-27 18:00:11 +01001//
2// Copyright © 2019 Arm Ltd. All rights reserved.
3// SPDX-License-Identifier: MIT
4//
5
6#include "BufferManager.hpp"
7#include "PacketBuffer.hpp"
Narumol Prangnawarat7be47ef2019-09-27 18:00:11 +01008
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00009namespace arm
Narumol Prangnawarat7be47ef2019-09-27 18:00:11 +010010{
11
Cathal Corbett5aa9fd72022-02-25 15:33:28 +000012namespace pipe
Narumol Prangnawarat7be47ef2019-09-27 18:00:11 +010013{
14
15BufferManager::BufferManager(unsigned int numberOfBuffers, unsigned int maxPacketSize)
Finn Williams09ad6f92019-12-19 17:05:18 +000016 : m_MaxBufferSize(maxPacketSize),
Jim Flynn0204f092020-06-22 20:41:43 +010017 m_NumberOfBuffers(numberOfBuffers),
18 m_MaxNumberOfBuffers(numberOfBuffers * 3),
19 m_CurrentNumberOfBuffers(numberOfBuffers)
Narumol Prangnawarat7be47ef2019-09-27 18:00:11 +010020{
Finn Williams09ad6f92019-12-19 17:05:18 +000021 Initialize();
Narumol Prangnawarat7be47ef2019-09-27 18:00:11 +010022}
23
Matteo Martincigh2ffcc412019-11-05 11:47:40 +000024IPacketBufferPtr BufferManager::Reserve(unsigned int requestedSize, unsigned int& reservedSize)
Narumol Prangnawarat7be47ef2019-09-27 18:00:11 +010025{
Narumol Prangnawarat0ec068f2019-09-30 16:20:20 +010026 reservedSize = 0;
Jim Flynne195a042022-04-12 17:19:28 +010027#if !defined(ARMNN_DISABLE_THREADS)
Narumol Prangnawarat7be47ef2019-09-27 18:00:11 +010028 std::unique_lock<std::mutex> availableListLock(m_AvailableMutex, std::defer_lock);
Jim Flynne195a042022-04-12 17:19:28 +010029#endif
Narumol Prangnawarat7be47ef2019-09-27 18:00:11 +010030 if (requestedSize > m_MaxBufferSize)
31 {
Narumol Prangnawarat0ec068f2019-09-30 16:20:20 +010032 return nullptr;
Narumol Prangnawarat7be47ef2019-09-27 18:00:11 +010033 }
Jim Flynne195a042022-04-12 17:19:28 +010034#if !defined(ARMNN_DISABLE_THREADS)
Narumol Prangnawarat7be47ef2019-09-27 18:00:11 +010035 availableListLock.lock();
Jim Flynne195a042022-04-12 17:19:28 +010036#endif
Narumol Prangnawarat7be47ef2019-09-27 18:00:11 +010037 if (m_AvailableList.empty())
38 {
Jim Flynn0204f092020-06-22 20:41:43 +010039 if (m_CurrentNumberOfBuffers < m_MaxNumberOfBuffers)
40 {
41 // create a temporary overflow/surge buffer and hand it back
42 m_CurrentNumberOfBuffers++;
Jim Flynne195a042022-04-12 17:19:28 +010043#if !defined(ARMNN_DISABLE_THREADS)
Jim Flynn0204f092020-06-22 20:41:43 +010044 availableListLock.unlock();
Jim Flynne195a042022-04-12 17:19:28 +010045#endif
Jim Flynn0204f092020-06-22 20:41:43 +010046 IPacketBufferPtr buffer = std::make_unique<PacketBuffer>(m_MaxBufferSize);
47 reservedSize = requestedSize;
48 return buffer;
49 }
50 else
51 {
52 // we have totally busted the limit. call a halt to new memory allocations.
Jim Flynne195a042022-04-12 17:19:28 +010053#if !defined(ARMNN_DISABLE_THREADS)
Jim Flynn0204f092020-06-22 20:41:43 +010054 availableListLock.unlock();
Jim Flynne195a042022-04-12 17:19:28 +010055#endif
Jim Flynn0204f092020-06-22 20:41:43 +010056 return nullptr;
57 }
Narumol Prangnawarat7be47ef2019-09-27 18:00:11 +010058 }
Matteo Martincigh2ffcc412019-11-05 11:47:40 +000059 IPacketBufferPtr buffer = std::move(m_AvailableList.back());
Narumol Prangnawarat7be47ef2019-09-27 18:00:11 +010060 m_AvailableList.pop_back();
Jim Flynne195a042022-04-12 17:19:28 +010061#if !defined(ARMNN_DISABLE_THREADS)
Narumol Prangnawarat7be47ef2019-09-27 18:00:11 +010062 availableListLock.unlock();
Jim Flynne195a042022-04-12 17:19:28 +010063#endif
Narumol Prangnawarat7be47ef2019-09-27 18:00:11 +010064 reservedSize = requestedSize;
65 return buffer;
66}
67
Sadik Armagan3896b472020-02-10 12:24:15 +000068void BufferManager::Commit(IPacketBufferPtr& packetBuffer, unsigned int size, bool notifyConsumer)
Narumol Prangnawarat7be47ef2019-09-27 18:00:11 +010069{
Jim Flynne195a042022-04-12 17:19:28 +010070#if !defined(ARMNN_DISABLE_THREADS)
Narumol Prangnawarat7be47ef2019-09-27 18:00:11 +010071 std::unique_lock<std::mutex> readableListLock(m_ReadableMutex, std::defer_lock);
Jim Flynne195a042022-04-12 17:19:28 +010072#endif
Narumol Prangnawarat7be47ef2019-09-27 18:00:11 +010073 packetBuffer->Commit(size);
Jim Flynne195a042022-04-12 17:19:28 +010074#if !defined(ARMNN_DISABLE_THREADS)
Narumol Prangnawarat7be47ef2019-09-27 18:00:11 +010075 readableListLock.lock();
Jim Flynne195a042022-04-12 17:19:28 +010076#endif
Finn Williamsb6a402f2020-03-24 13:46:22 +000077 m_ReadableList.push(std::move(packetBuffer));
Jim Flynne195a042022-04-12 17:19:28 +010078#if !defined(ARMNN_DISABLE_THREADS)
Narumol Prangnawarat7be47ef2019-09-27 18:00:11 +010079 readableListLock.unlock();
Jim Flynne195a042022-04-12 17:19:28 +010080#endif
Sadik Armagan3896b472020-02-10 12:24:15 +000081 if (notifyConsumer)
82 {
83 FlushReadList();
84 }
Finn Williams09ad6f92019-12-19 17:05:18 +000085}
86
87void BufferManager::Initialize()
88{
89 m_AvailableList.reserve(m_NumberOfBuffers);
Jim Flynn0204f092020-06-22 20:41:43 +010090 m_CurrentNumberOfBuffers = m_NumberOfBuffers;
Finn Williams09ad6f92019-12-19 17:05:18 +000091 for (unsigned int i = 0; i < m_NumberOfBuffers; ++i)
92 {
93 IPacketBufferPtr buffer = std::make_unique<PacketBuffer>(m_MaxBufferSize);
94 m_AvailableList.emplace_back(std::move(buffer));
95 }
Narumol Prangnawarat7be47ef2019-09-27 18:00:11 +010096}
97
Matteo Martincigh2ffcc412019-11-05 11:47:40 +000098void BufferManager::Release(IPacketBufferPtr& packetBuffer)
Narumol Prangnawarat7be47ef2019-09-27 18:00:11 +010099{
Jim Flynne195a042022-04-12 17:19:28 +0100100#if !defined(ARMNN_DISABLE_THREADS)
Narumol Prangnawarat7be47ef2019-09-27 18:00:11 +0100101 std::unique_lock<std::mutex> availableListLock(m_AvailableMutex, std::defer_lock);
Jim Flynne195a042022-04-12 17:19:28 +0100102#endif
Narumol Prangnawarat7be47ef2019-09-27 18:00:11 +0100103 packetBuffer->Release();
Jim Flynne195a042022-04-12 17:19:28 +0100104#if !defined(ARMNN_DISABLE_THREADS)
Narumol Prangnawarat7be47ef2019-09-27 18:00:11 +0100105 availableListLock.lock();
Jim Flynne195a042022-04-12 17:19:28 +0100106#endif
Jim Flynn0204f092020-06-22 20:41:43 +0100107 if (m_AvailableList.size() <= m_NumberOfBuffers)
108 {
109 m_AvailableList.push_back(std::move(packetBuffer));
110 }
111 else
112 {
113 // we have been handed a temporary overflow/surge buffer get rid of it
114 packetBuffer->Destroy();
115 if (m_CurrentNumberOfBuffers > m_NumberOfBuffers)
116 {
117 --m_CurrentNumberOfBuffers;
118 }
119 }
Jim Flynne195a042022-04-12 17:19:28 +0100120#if !defined(ARMNN_DISABLE_THREADS)
Narumol Prangnawarat7be47ef2019-09-27 18:00:11 +0100121 availableListLock.unlock();
Jim Flynne195a042022-04-12 17:19:28 +0100122#endif
Narumol Prangnawarat7be47ef2019-09-27 18:00:11 +0100123}
124
Finn Williams09ad6f92019-12-19 17:05:18 +0000125void BufferManager::Reset()
126{
127 //This method should only be called once all threads have been joined
Jim Flynne195a042022-04-12 17:19:28 +0100128#if !defined(ARMNN_DISABLE_THREADS)
Finn Williams09ad6f92019-12-19 17:05:18 +0000129 std::lock_guard<std::mutex> readableListLock(m_ReadableMutex);
130 std::lock_guard<std::mutex> availableListLock(m_AvailableMutex);
Jim Flynne195a042022-04-12 17:19:28 +0100131#endif
Finn Williams09ad6f92019-12-19 17:05:18 +0000132
133 m_AvailableList.clear();
Finn Williamsb6a402f2020-03-24 13:46:22 +0000134 std::queue<IPacketBufferPtr>().swap(m_ReadableList);
Finn Williams09ad6f92019-12-19 17:05:18 +0000135
136 Initialize();
137}
138
Matteo Martincigh2ffcc412019-11-05 11:47:40 +0000139IPacketBufferPtr BufferManager::GetReadableBuffer()
Narumol Prangnawarat7be47ef2019-09-27 18:00:11 +0100140{
Jim Flynne195a042022-04-12 17:19:28 +0100141#if !defined(ARMNN_DISABLE_THREADS)
Narumol Prangnawarat7be47ef2019-09-27 18:00:11 +0100142 std::unique_lock<std::mutex> readableListLock(m_ReadableMutex);
Jim Flynne195a042022-04-12 17:19:28 +0100143#endif
Narumol Prangnawarat7be47ef2019-09-27 18:00:11 +0100144 if (!m_ReadableList.empty())
145 {
Finn Williamsb6a402f2020-03-24 13:46:22 +0000146 IPacketBufferPtr buffer = std::move(m_ReadableList.front());
147 m_ReadableList.pop();
Jim Flynne195a042022-04-12 17:19:28 +0100148#if !defined(ARMNN_DISABLE_THREADS)
Narumol Prangnawarat7be47ef2019-09-27 18:00:11 +0100149 readableListLock.unlock();
Jim Flynne195a042022-04-12 17:19:28 +0100150#endif
Narumol Prangnawarat7be47ef2019-09-27 18:00:11 +0100151 return buffer;
152 }
153 return nullptr;
154}
155
Matteo Martincigh2ffcc412019-11-05 11:47:40 +0000156void BufferManager::MarkRead(IPacketBufferPtr& packetBuffer)
Narumol Prangnawarat7be47ef2019-09-27 18:00:11 +0100157{
Jim Flynne195a042022-04-12 17:19:28 +0100158#if !defined(ARMNN_DISABLE_THREADS)
Narumol Prangnawarat7be47ef2019-09-27 18:00:11 +0100159 std::unique_lock<std::mutex> availableListLock(m_AvailableMutex, std::defer_lock);
Jim Flynne195a042022-04-12 17:19:28 +0100160#endif
Narumol Prangnawarat7be47ef2019-09-27 18:00:11 +0100161 packetBuffer->MarkRead();
Jim Flynne195a042022-04-12 17:19:28 +0100162#if !defined(ARMNN_DISABLE_THREADS)
Narumol Prangnawarat7be47ef2019-09-27 18:00:11 +0100163 availableListLock.lock();
Jim Flynne195a042022-04-12 17:19:28 +0100164#endif
Jim Flynn0204f092020-06-22 20:41:43 +0100165 if (m_AvailableList.size() <= m_NumberOfBuffers)
166 {
167 m_AvailableList.push_back(std::move(packetBuffer));
168 }
169 else
170 {
171 // we have been handed a temporary overflow/surge buffer get rid of it
172 packetBuffer->Destroy();
173 if (m_CurrentNumberOfBuffers > m_NumberOfBuffers)
174 {
175 --m_CurrentNumberOfBuffers;
176 }
177 }
Jim Flynne195a042022-04-12 17:19:28 +0100178#if !defined(ARMNN_DISABLE_THREADS)
Narumol Prangnawarat7be47ef2019-09-27 18:00:11 +0100179 availableListLock.unlock();
Jim Flynne195a042022-04-12 17:19:28 +0100180#endif
Narumol Prangnawarat7be47ef2019-09-27 18:00:11 +0100181}
182
Sadik Armagan3896b472020-02-10 12:24:15 +0000183void BufferManager::SetConsumer(IConsumer* consumer)
184{
185 m_Consumer = consumer;
186}
187
188void BufferManager::FlushReadList()
189{
190 // notify consumer that packet is ready to read
191 if (m_Consumer != nullptr)
192 {
193 m_Consumer->SetReadyToRead();
194 }
195}
196
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000197} // namespace pipe
Narumol Prangnawarat7be47ef2019-09-27 18:00:11 +0100198
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000199} // namespace arm