blob: a7b71e5fa1188fbc9d1a7dd1b40ed8235406717f [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();
Finn Williamsb6a402f2020-03-24 13:46:22 +000048 m_ReadableList.push(std::move(packetBuffer));
Narumol Prangnawarat7be47ef2019-09-27 18:00:11 +010049 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 }
Narumol Prangnawarat7be47ef2019-09-27 18:00:11 +010065}
66
Matteo Martincigh2ffcc412019-11-05 11:47:40 +000067void BufferManager::Release(IPacketBufferPtr& packetBuffer)
Narumol Prangnawarat7be47ef2019-09-27 18:00:11 +010068{
69 std::unique_lock<std::mutex> availableListLock(m_AvailableMutex, std::defer_lock);
70 packetBuffer->Release();
71 availableListLock.lock();
72 m_AvailableList.push_back(std::move(packetBuffer));
73 availableListLock.unlock();
74}
75
Finn Williams09ad6f92019-12-19 17:05:18 +000076void BufferManager::Reset()
77{
78 //This method should only be called once all threads have been joined
79 std::lock_guard<std::mutex> readableListLock(m_ReadableMutex);
80 std::lock_guard<std::mutex> availableListLock(m_AvailableMutex);
81
82 m_AvailableList.clear();
Finn Williamsb6a402f2020-03-24 13:46:22 +000083 std::queue<IPacketBufferPtr>().swap(m_ReadableList);
Finn Williams09ad6f92019-12-19 17:05:18 +000084
85 Initialize();
86}
87
Matteo Martincigh2ffcc412019-11-05 11:47:40 +000088IPacketBufferPtr BufferManager::GetReadableBuffer()
Narumol Prangnawarat7be47ef2019-09-27 18:00:11 +010089{
90 std::unique_lock<std::mutex> readableListLock(m_ReadableMutex);
91 if (!m_ReadableList.empty())
92 {
Finn Williamsb6a402f2020-03-24 13:46:22 +000093 IPacketBufferPtr buffer = std::move(m_ReadableList.front());
94 m_ReadableList.pop();
Narumol Prangnawarat7be47ef2019-09-27 18:00:11 +010095 readableListLock.unlock();
96 return buffer;
97 }
98 return nullptr;
99}
100
Matteo Martincigh2ffcc412019-11-05 11:47:40 +0000101void BufferManager::MarkRead(IPacketBufferPtr& packetBuffer)
Narumol Prangnawarat7be47ef2019-09-27 18:00:11 +0100102{
103 std::unique_lock<std::mutex> availableListLock(m_AvailableMutex, std::defer_lock);
104 packetBuffer->MarkRead();
105 availableListLock.lock();
106 m_AvailableList.push_back(std::move(packetBuffer));
107 availableListLock.unlock();
108}
109
Sadik Armagan3896b472020-02-10 12:24:15 +0000110void BufferManager::SetConsumer(IConsumer* consumer)
111{
112 m_Consumer = consumer;
113}
114
115void BufferManager::FlushReadList()
116{
117 // notify consumer that packet is ready to read
118 if (m_Consumer != nullptr)
119 {
120 m_Consumer->SetReadyToRead();
121 }
122}
123
Narumol Prangnawarat7be47ef2019-09-27 18:00:11 +0100124} // namespace profiling
125
126} // namespace armnn