return fds;
}
-void XskWorker::fillUniqueEmptyOffset()
-{
- auto frames = sharedEmptyFrameOffset->lock();
- const auto moveSize = std::min(static_cast<size_t>(32), frames->size());
- if (moveSize > 0) {
- // NOLINTNEXTLINE(bugprone-narrowing-conversions,cppcoreguidelines-narrowing-conversions)
- uniqueEmptyFrameOffset.insert(uniqueEmptyFrameOffset.end(), std::make_move_iterator(frames->end() - moveSize), std::make_move_iterator(frames->end()));
- frames->resize(frames->size() - moveSize);
- }
-}
-
std::optional<XskPacket> XskWorker::getEmptyFrame()
{
- if (!uniqueEmptyFrameOffset.empty()) {
- auto offset = uniqueEmptyFrameOffset.back();
- uniqueEmptyFrameOffset.pop_back();
- // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
- return XskPacket(offset + umemBufBase, 0, frameSize);
- }
- fillUniqueEmptyOffset();
- if (!uniqueEmptyFrameOffset.empty()) {
- auto offset = uniqueEmptyFrameOffset.back();
- uniqueEmptyFrameOffset.pop_back();
- // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
- return XskPacket(offset + umemBufBase, 0, frameSize);
+ auto frames = sharedEmptyFrameOffset->lock();
+ if (frames->empty()) {
+ return std::nullopt;
}
- return std::nullopt;
+ auto offset = frames->back();
+ frames->pop_back();
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
+ return XskPacket(offset + umemBufBase, 0, frameSize);
}
void XskWorker::markAsFree(const XskPacket& packet)
#ifdef DEBUG_UMEM
checkUmemIntegrity(__PRETTY_FUNCTION__, __LINE__, offset, {UmemEntryStatus::Status::Received, UmemEntryStatus::Status::TXQueue}, UmemEntryStatus::Status::Free);
#endif /* DEBUG_UMEM */
- uniqueEmptyFrameOffset.push_back(offset);
+ {
+ auto frames = sharedEmptyFrameOffset->lock();
+ frames->push_back(offset);
+ }
}
uint32_t XskPacket::getFlags() const noexcept
uint8_t* umemBufBase{nullptr};
// list of frames that are shared with the XskRouter
std::shared_ptr<LockGuarded<vector<uint64_t>>> sharedEmptyFrameOffset;
- // list of frames that we own, used to generate new packets (health-check)
- vector<uint64_t> uniqueEmptyFrameOffset;
const size_t frameSize{XskSocket::getFrameSize()};
FDWrapper workerWaker;
FDWrapper xskSocketWaker;
void cleanWorkerNotification() const noexcept;
void cleanSocketNotification() const noexcept;
[[nodiscard]] uint64_t frameOffset(const XskPacket& packet) const noexcept;
- // reap empty umem entry from sharedEmptyFrameOffset into uniqueEmptyFrameOffset
- void fillUniqueEmptyOffset();
- // look for an empty umem entry in uniqueEmptyFrameOffset
- // then sharedEmptyFrameOffset if needed
+ // get an empty umem entry from sharedEmptyFrameOffset
std::optional<XskPacket> getEmptyFrame();
};
std::vector<pollfd> getPollFdsForWorker(XskWorker& info);