Skip to content

Commit 91a5fd2

Browse files
committed
[cru] Use folly instead of boost queue
1 parent a45fe7c commit 91a5fd2

File tree

3 files changed

+63
-40
lines changed

3 files changed

+63
-40
lines changed

src/CommandLineUtilities/ProgramDmaBench.cxx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -576,7 +576,7 @@ class ProgramDmaBench : public Program
576576
BOOST_THROW_EXCEPTION(Exception() << ErrorInfo::Message("RDH reports cumulative dma page sizes that exceed the superpage size"));
577577
}
578578
}
579-
std::cout << "[popped superpage " << i << " ], size= " << superpage.getSize() << " received= " << superpage.getReceived() << " isFilled=" << superpage.isFilled() << " isReady=" << superpage.isReady() << std::endl;
579+
//std::cout << "[popped superpage " << i << " ], size= " << superpage.getSize() << " received= " << superpage.getReceived() << " isFilled=" << superpage.isFilled() << " isReady=" << superpage.isReady() << std::endl;
580580
}
581581
popped += size;
582582
}

src/Cru/CruDmaChannel.cxx

Lines changed: 55 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ namespace roc
2929
{
3030

3131
CruDmaChannel::CruDmaChannel(const Parameters& parameters)
32-
: DmaChannelPdaBase(parameters, allowedChannels()), //
32+
: DmaChannelPdaBase(parameters, allowedChannels()),
3333
mInitialResetLevel(ResetLevel::Internal), // It's good to reset at least the card channel in general
3434
mDataSource(parameters.getDataSource().get_value_or(DataSource::Internal)), // DG loopback mode by default
3535
mDmaPageSize(parameters.getDmaPageSize().get_value_or(Cru::DMA_PAGE_SIZE))
@@ -81,7 +81,10 @@ CruDmaChannel::CruDmaChannel(const Parameters& parameters)
8181
<< ErrorInfo::LinkId(id));
8282
}
8383
stream << id << " ";
84-
mLinks.push_back({ static_cast<LinkId>(id) });
84+
//Implicit constructors are deleted for the folly Queue. Workaround to keep the Link struct with a queue * field.
85+
std::shared_ptr<SuperpageQueue> linkQueue = std::make_shared<SuperpageQueue>(LINK_QUEUE_CAPACITY);
86+
Link newLink = { static_cast<LinkId>(id), 0, linkQueue };
87+
mLinks.push_back(newLink);
8588
}
8689
log(stream.str());
8790
}
@@ -96,8 +99,8 @@ auto CruDmaChannel::allowedChannels() -> AllowedChannels
9699
CruDmaChannel::~CruDmaChannel()
97100
{
98101
setBufferNonReady();
99-
if (mReadyQueue.size() > 0) {
100-
log((format("Remaining superpages in the ready queue: %1%") % mReadyQueue.size()).str());
102+
if (mReadyQueue.sizeGuess() > 0) {
103+
log((format("Remaining superpages in the ready queue: %1%") % mReadyQueue.sizeGuess()).str());
101104
}
102105

103106
if (mDataSource == DataSource::Internal) {
@@ -128,10 +131,15 @@ void CruDmaChannel::deviceStartDma()
128131

129132
// Initialize link queues
130133
for (auto& link : mLinks) {
131-
link.queue.clear();
134+
//link.queue->clear();
135+
while (!link.queue->isEmpty()) {
136+
link.queue->popFront();
137+
}
132138
link.superpageCounter = 0;
133139
}
134-
mReadyQueue.clear();
140+
while (!mReadyQueue.isEmpty()) {
141+
mReadyQueue.popFront();
142+
}
135143
mLinkQueuesTotalAvailable = LINK_QUEUE_CAPACITY * mLinks.size();
136144

137145
// Start DMA
@@ -167,16 +175,17 @@ void CruDmaChannel::deviceStopDma()
167175
fillSuperpages();
168176

169177
// Return any superpages that have been pushed up in the meantime but won't get filled
178+
reclaimSuperpages();
179+
}
180+
181+
void CruDmaChannel::reclaimSuperpages()
182+
{
170183
for (auto& link : mLinks) {
171-
while (!link.queue.empty()) {
172-
link.queue.front().setReceived(0);
173-
link.queue.front().setReady(false);
174-
mReadyQueue.push_back(link.queue.front());
175-
link.queue.pop_front();
176-
mLinkQueuesTotalAvailable++;
184+
while (!link.queue->isEmpty()) {
185+
transferSuperpageFromLinkToReady(link, true); // Reclaim pages, do *not* set as ready
177186
}
178187

179-
if (!link.queue.empty()) {
188+
if (!link.queue->isEmpty()) {
180189
log((format("Superpage queue of link %1% not empty after DMA stop. Superpages unclaimed.") % link.id).str(),
181190
InfoLogger::InfoLogger::Error);
182191
}
@@ -211,7 +220,7 @@ auto CruDmaChannel::getNextLinkIndex() -> LinkIndex
211220
auto smallestQueueSize = std::numeric_limits<size_t>::max();
212221

213222
for (size_t i = 0; i < mLinks.size(); ++i) {
214-
auto queueSize = mLinks[i].queue.size();
223+
auto queueSize = mLinks[i].queue->sizeGuess();
215224
if (queueSize < smallestQueueSize) {
216225
smallestQueueIndex = i;
217226
smallestQueueSize = queueSize;
@@ -238,7 +247,7 @@ bool CruDmaChannel::pushSuperpage(Superpage superpage)
238247
// Get the next link to push
239248
auto& link = mLinks[getNextLinkIndex()];
240249

241-
if (link.queue.size() >= LINK_QUEUE_CAPACITY) {
250+
if (link.queue->sizeGuess() >= LINK_QUEUE_CAPACITY) {
242251
// Is the link's FIFO out of space?
243252
// This should never happen
244253
BOOST_THROW_EXCEPTION(Exception() << ErrorInfo::Message("Could not push superpage, link queue was full"));
@@ -255,59 +264,69 @@ bool CruDmaChannel::pushSuperpage(Superpage superpage)
255264

256265
auto CruDmaChannel::getSuperpage() -> Superpage
257266
{
258-
if (mReadyQueue.empty()) {
267+
if (mReadyQueue.isEmpty()) {
259268
BOOST_THROW_EXCEPTION(Exception() << ErrorInfo::Message("Could not get superpage, ready queue was empty"));
260269
}
261-
return mReadyQueue.front();
270+
return *mReadyQueue.frontPtr();
262271
}
263272

264273
auto CruDmaChannel::popSuperpage() -> Superpage
265274
{
266-
if (mReadyQueue.empty()) {
275+
if (mReadyQueue.isEmpty()) {
267276
BOOST_THROW_EXCEPTION(Exception() << ErrorInfo::Message("Could not pop superpage, ready queue was empty"));
268277
}
269-
auto superpage = mReadyQueue.front();
270-
mReadyQueue.pop_front();
278+
auto superpage = *mReadyQueue.frontPtr();
279+
mReadyQueue.popFront();
280+
271281
return superpage;
272282
}
273283

274284
void CruDmaChannel::pushSuperpageToLink(Link& link, const Superpage& superpage)
275285
{
276286
mLinkQueuesTotalAvailable--;
277-
link.queue.push_back(superpage);
287+
link.queue->write(superpage);
278288
}
279289

280-
void CruDmaChannel::transferSuperpageFromLinkToReady(Link& link)
290+
void CruDmaChannel::transferSuperpageFromLinkToReady(Link& link, bool reclaim)
281291
{
282-
if (link.queue.empty()) {
292+
if (link.queue->isEmpty()) {
283293
BOOST_THROW_EXCEPTION(Exception() << ErrorInfo::Message("Could not transfer Superpage from link to ready queue, link queue is empty"));
284294
}
285295

286-
link.queue.front().setReady(true);
287-
288-
uint32_t superpageSize = getBar()->getSuperpageSize(link.id);
289-
if (superpageSize == 0) {
290-
link.queue.front().setReceived(link.queue.front().getSize()); // force the full superpage size for backwards compatibility
296+
if (!reclaim) {
297+
link.queue->frontPtr()->setReady(true);
298+
uint32_t superpageSize = getBar()->getSuperpageSize(link.id);
299+
if (superpageSize == 0) {
300+
link.queue->frontPtr()->setReceived(link.queue->frontPtr()->getSize()); // force the full superpage size for backwards compatibility
301+
} else {
302+
link.queue->frontPtr()->setReceived(superpageSize);
303+
}
291304
} else {
292-
link.queue.front().setReceived(superpageSize);
305+
link.queue->frontPtr()->setReady(false);
306+
link.queue->frontPtr()->setReceived(0);
293307
}
294308

295-
mReadyQueue.push_back(link.queue.front());
296-
link.queue.pop_front();
309+
mReadyQueue.write(*link.queue->frontPtr());
310+
link.queue->popFront();
297311
link.superpageCounter++;
298312
mLinkQueuesTotalAvailable++;
299313
}
300314

301315
void CruDmaChannel::fillSuperpages()
302316
{
317+
318+
/*if (mDmaState != DmaState::STARTED) { //Would block fillSuperpages from deviceStopDma()
319+
//return;
320+
}*/
321+
303322
// Check for arrivals & handle them
304323
for (auto& link : mLinks) {
305324
int32_t superpageCount = getBar()->getSuperpageCount(link.id);
306325
uint32_t amountAvailable = superpageCount - link.superpageCounter;
307-
if (amountAvailable > link.queue.size()) {
326+
if (amountAvailable > link.queue->sizeGuess()) {
308327

309328
std::stringstream stream;
310-
stream << "FATAL: Firmware reported more superpages available (" << amountAvailable << ") than should be present in FIFO (" << link.queue.size() << "); "
329+
stream << "FATAL: Firmware reported more superpages available (" << amountAvailable << ") than should be present in FIFO (" << link.queue->sizeGuess() << "); "
311330
<< link.superpageCounter << " superpages received from link " << int(link.id) << " according to driver, "
312331
<< superpageCount << " pushed according to firmware";
313332
log(stream.str(), InfoLogger::InfoLogger::Error);
@@ -316,7 +335,7 @@ void CruDmaChannel::fillSuperpages()
316335
}
317336

318337
while (amountAvailable) {
319-
if (mReadyQueue.size() >= READY_QUEUE_CAPACITY) {
338+
if (mReadyQueue.sizeGuess() >= READY_QUEUE_CAPACITY) {
320339
break;
321340
}
322341

@@ -340,14 +359,14 @@ bool CruDmaChannel::isTransferQueueEmpty()
340359

341360
int CruDmaChannel::getReadyQueueSize()
342361
{
343-
return mReadyQueue.size();
362+
return mReadyQueue.sizeGuess();
344363
}
345364

346365
// Return a boolean that denotes whether the ready queue is full
347366
// The ready queue is full when the CRU has filled it up
348367
bool CruDmaChannel::isReadyQueueFull()
349368
{
350-
return mReadyQueue.size() == READY_QUEUE_CAPACITY;
369+
return mReadyQueue.isFull();
351370
}
352371

353372
int32_t CruDmaChannel::getDroppedPackets()

src/Cru/CruDmaChannel.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "Cru/CruBar.h"
2626
#include "Cru/FirmwareFeatures.h"
2727
#include "ReadoutCard/Parameters.h"
28+
#include "folly/ProducerConsumerQueue.h"
2829

2930
namespace AliceO2
3031
{
@@ -74,7 +75,7 @@ class CruDmaChannel final : public DmaChannelPdaBase
7475
static constexpr size_t READY_QUEUE_CAPACITY = Cru::MAX_SUPERPAGE_DESCRIPTORS * Cru::MAX_LINKS;
7576

7677
/// Queue for one link
77-
using SuperpageQueue = boost::circular_buffer<Superpage>;
78+
using SuperpageQueue = folly::ProducerConsumerQueue<Superpage>;
7879

7980
/// Index into mLinks
8081
using LinkIndex = uint32_t;
@@ -91,7 +92,7 @@ class CruDmaChannel final : public DmaChannelPdaBase
9192
uint32_t superpageCounter = 0;
9293

9394
/// The superpage queue
94-
SuperpageQueue queue{ LINK_QUEUE_CAPACITY };
95+
std::shared_ptr<SuperpageQueue> queue;
9596
};
9697

9798
void resetCru();
@@ -115,14 +116,17 @@ class CruDmaChannel final : public DmaChannelPdaBase
115116
void pushSuperpageToLink(Link& link, const Superpage& superpage);
116117

117118
/// Mark the front superpage of a link ready and transfer it to the ready queue
118-
void transferSuperpageFromLinkToReady(Link& link);
119+
void transferSuperpageFromLinkToReady(Link& link, bool reclaim = false);
119120

120121
/// Enable debug mode by writing to the appropriate CRU register
121122
void enableDebugMode();
122123

123124
/// Reset debug mode to the state it was in prior to the start of execution
124125
void resetDebugMode();
125126

127+
/// Reclaims superpages pushed to the CRU but not filled on DMA stop
128+
void reclaimSuperpages();
129+
126130
/// BAR 0 is needed for DMA engine interaction and various other functions
127131
std::shared_ptr<CruBar> cruBar;
128132

0 commit comments

Comments
 (0)