blob: f5ab7292599f736e5d8e09f7cbb774b05c8b542f [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
9namespace armnn
10{
11
12namespace profiling
13{
14
15BufferManager::BufferManager(unsigned int numberOfBuffers, unsigned int maxPacketSize)
Finn Williams09ad6f92019-12-19 17:05:18 +000016 : m_MaxBufferSize(maxPacketSize),
17 m_NumberOfBuffers(numberOfBuffers)
Narumol Prangnawarat7be47ef2019-09-27 18:00:11 +010018{
Finn Williams09ad6f92019-12-19 17:05:18 +000019 Initialize();
Narumol Prangnawarat7be47ef2019-09-27 18:00:11 +010020}
21
Matteo Martincigh2ffcc412019-11-05 11:47:40 +000022IPacketBufferPtr BufferManager::Reserve(unsigned int requestedSize, unsigned int& reservedSize)
Narumol Prangnawarat7be47ef2019-09-27 18:00:11 +010023{
Narumol Prangnawarat0ec068f2019-09-30 16:20:20 +010024 reservedSize = 0;
Narumol Prangnawarat7be47ef2019-09-27 18:00:11 +010025 std::unique_lock<std::mutex> availableListLock(m_AvailableMutex, std::defer_lock);
26 if (requestedSize > m_MaxBufferSize)
27 {
Narumol Prangnawarat0ec068f2019-09-30 16:20:20 +010028 return nullptr;
Narumol Prangnawarat7be47ef2019-09-27 18:00:11 +010029 }
30 availableListLock.lock();
31 if (m_AvailableList.empty())
32 {
Narumol Prangnawarat0ec068f2019-09-30 16:20:20 +010033 availableListLock.unlock();
34 return nullptr;
Narumol Prangnawarat7be47ef2019-09-27 18:00:11 +010035 }
Matteo Martincigh2ffcc412019-11-05 11:47:40 +000036 IPacketBufferPtr buffer = std::move(m_AvailableList.back());
Narumol Prangnawarat7be47ef2019-09-27 18:00:11 +010037 m_AvailableList.pop_back();
38 availableListLock.unlock();
39 reservedSize = requestedSize;
40 return buffer;
41}
42
Sadik Armagan3896b472020-02-10 12:24:15 +000043void BufferManager::Commit(IPacketBufferPtr& packetBuffer, unsigned int size, bool notifyConsumer)
Narumol Prangnawarat7be47ef2019-09-27 18:00:11 +010044{
45 std::unique_lock<std::mutex> readableListLock(m_ReadableMutex, std::defer_lock);
46 packetBuffer->Commit(size);
47 readableListLock.lock();
48 m_ReadableList.push_back(std::move(packetBuffer));
49 readableListLock.unlock();
Sadik Armagan3896b472020-02-10 12:24:15 +000050
51 if (notifyConsumer)
52 {
53 FlushReadList();
54 }
Finn Williams09ad6f92019-12-19 17:05:18 +000055}
56
57void BufferManager::Initialize()
58{
59 m_AvailableList.reserve(m_NumberOfBuffers);
60 for (unsigned int i = 0; i < m_NumberOfBuffers; ++i)
61 {
62 IPacketBufferPtr buffer = std::make_unique<PacketBuffer>(m_MaxBufferSize);
63 m_AvailableList.emplace_back(std::move(buffer));
64 }
65 m_ReadableList.reserve(m_NumberOfBuffers);
Narumol Prangnawarat7be47ef2019-09-27 18:00:11 +010066}
67
Matteo Martincigh2ffcc412019-11-05 11:47:40 +000068void BufferManager::Release(IPacketBufferPtr& packetBuffer)
Narumol Prangnawarat7be47ef2019-09-27 18:00:11 +010069{
70 std::unique_lock<std::mutex> availableListLock(m_AvailableMutex, std::defer_lock);
71 packetBuffer->Release();
72 availableListLock.lock();
73 m_AvailableList.push_back(std::move(packetBuffer));
74 availableListLock.unlock();
75}
76
Finn Williams09ad6f92019-12-19 17:05:18 +000077void BufferManager::Reset()
78{
79 //This method should only be called once all threads have been joined
80 std::lock_guard<std::mutex> readableListLock(m_ReadableMutex);
81 std::lock_guard<std::mutex> availableListLock(m_AvailableMutex);
82
83 m_AvailableList.clear();
84 m_ReadableList.clear();
85
86 Initialize();
87}
88
Matteo Martincigh2ffcc412019-11-05 11:47:40 +000089IPacketBufferPtr BufferManager::GetReadableBuffer()
Narumol Prangnawarat7be47ef2019-09-27 18:00:11 +010090{
91 std::unique_lock<std::mutex> readableListLock(m_ReadableMutex);
92 if (!m_ReadableList.empty())
93 {
Matteo Martincigh2ffcc412019-11-05 11:47:40 +000094 IPacketBufferPtr buffer = std::move(m_ReadableList.back());
Narumol Prangnawarat7be47ef2019-09-27 18:00:11 +010095 m_ReadableList.pop_back();
96 readableListLock.unlock();
97 return buffer;
98 }
99 return nullptr;
100}
101
Matteo Martincigh2ffcc412019-11-05 11:47:40 +0000102void BufferManager::MarkRead(IPacketBufferPtr& packetBuffer)
Narumol Prangnawarat7be47ef2019-09-27 18:00:11 +0100103{
104 std::unique_lock<std::mutex> availableListLock(m_AvailableMutex, std::defer_lock);
105 packetBuffer->MarkRead();
106 availableListLock.lock();
107 m_AvailableList.push_back(std::move(packetBuffer));
108 availableListLock.unlock();
109}
110
Sadik Armagan3896b472020-02-10 12:24:15 +0000111void BufferManager::SetConsumer(IConsumer* consumer)
112{
113 m_Consumer = consumer;
114}
115
116void BufferManager::FlushReadList()
117{
118 // notify consumer that packet is ready to read
119 if (m_Consumer != nullptr)
120 {
121 m_Consumer->SetReadyToRead();
122 }
123}
124
Narumol Prangnawarat7be47ef2019-09-27 18:00:11 +0100125} // namespace profiling
126
127} // namespace armnn