Replace concurrentqueue with ringbuffer

This commit is contained in:
Jonathan Schwartz
2024-04-05 17:24:53 +00:00
parent 7d2d12c5cd
commit 63f0516318
22 changed files with 361 additions and 169 deletions
+2 -4
View File
@@ -140,9 +140,8 @@ bool CDCACM::close() {
int ret = ::close(fd);
fd = -1;
uint8_t flush;
WriteOperation flushop;
while (readQueue.try_dequeue(flush)) {}
readBuffer.clear();
while (writeQueue.try_dequeue(flushop)) {}
if(modeChanging) {
@@ -191,8 +190,7 @@ void CDCACM::readTask() {
}
std::cout << std::dec << std::endl;
#endif
readQueue.enqueue_bulk(readbuf, bytesRead);
readBuffer.write(readbuf, bytesRead);
} else {
if(modeChanging) {
// We were expecting a disconnect for reenumeration
+17 -11
View File
@@ -16,6 +16,7 @@
#include <errno.h>
#include <sys/select.h>
#include <sys/mman.h>
#include <sys/resource.h>
using namespace icsneo;
@@ -44,13 +45,13 @@ void FirmIO::Find(std::vector<FoundDevice>& found) {
const auto start = steady_clock::now();
// Get an absolute wall clock to compare to
const auto overallTimeout = start + milliseconds(500);
while(temp.readWait(payload, milliseconds(50))) {
while(!temp.readAvailable()) {
if(steady_clock::now() > overallTimeout) {
// failed to read out a serial number reponse in time
break;
}
if(!packetizer.input(payload))
if(!packetizer.input(temp.getReadBuffer()))
continue; // A full packet has not yet been read out
for(const auto& packet : packetizer.output()) {
@@ -182,9 +183,6 @@ bool FirmIO::close() {
ret |= ::close(fd);
fd = -1;
uint8_t flush;
while (readQueue.try_dequeue(flush)) {}
if(ret == 0) {
return true;
} else {
@@ -198,6 +196,12 @@ void FirmIO::readTask() {
Msg msg;
std::vector<Msg> toFree;
// attempt to elevate the thread priority. PRIO_MIN is actually the highest priority but the lowest value.
int err = setpriority(PRIO_PROCESS, 0, -1);
if (err != 0) {
std::cerr << "FirmIO::readTask setpriority failed : " << strerror(errno) << std::endl;
}
while(!closing && !isDisconnected()) {
fd_set rfds = {0};
struct timeval tv = {0};
@@ -219,10 +223,7 @@ void FirmIO::readTask() {
toFree.clear();
int i = 0;
while(!in->isEmpty() && i++ < 1000) {
if(!in->read(&msg))
break;
while(in->read(&msg) && i++ < 1000) {
switch(msg.command) {
case Msg::Command::ComData: {
if(toFree.empty() || toFree.back().payload.free.refCount == 6) {
@@ -241,9 +242,14 @@ void FirmIO::readTask() {
// Translate the physical address back to our virtual address space
uint8_t* addr = reinterpret_cast<uint8_t*>(msg.payload.data.addr - PHY_ADDR_BASE + vbase);
readQueue.enqueue_bulk(addr, msg.payload.data.len);
break;
while (!readBuffer.write(addr, msg.payload.data.len)) {
std::this_thread::sleep_for(std::chrono::milliseconds(1)); // back-off so reading thread can empty the buffer
if (closing || isDisconnected()) {
break;
}
}
}
break;
case Msg::Command::ComFree: {
std::lock_guard<std::mutex> lk(outMutex);
// std::cout << "Got some free " << std::hex << msg.payload.free.ref[0] << std::endl;
+2 -3
View File
@@ -109,9 +109,8 @@ bool FTDI::close() {
report(APIEvent::Type::DriverFailedToClose, APIEvent::Severity::Error);
}
uint8_t flush;
WriteOperation flushop;
while(readQueue.try_dequeue(flush)) {}
readBuffer.clear();
while(writeQueue.try_dequeue(flushop)) {}
closing = false;
@@ -214,7 +213,7 @@ void FTDI::readTask() {
} else
report(APIEvent::Type::FailedToRead, APIEvent::Severity::EventWarning);
} else
readQueue.enqueue_bulk(readbuf, readBytes);
readBuffer.write(readbuf, readBytes);
}
}
+6 -4
View File
@@ -136,6 +136,8 @@ void PCAP::Find(std::vector<FoundDevice>& found) {
pcap_sendpacket(iface.fp, bs.data(), (int)bs.size());
auto timeout = std::chrono::high_resolution_clock::now() + std::chrono::milliseconds(50);
constexpr const size_t TempBufferSize = 4096;
RingBuffer tempBuffer(TempBufferSize);
while(std::chrono::high_resolution_clock::now() <= timeout) { // Wait up to 50ms for the response
struct pcap_pkthdr* header;
const uint8_t* data;
@@ -158,7 +160,8 @@ void PCAP::Find(std::vector<FoundDevice>& found) {
continue; // This packet is not for us
Packetizer packetizer([](APIEvent::Type, APIEvent::Severity) {});
if(!packetizer.input(ethPacketizer.outputUp()))
tempBuffer.write(ethPacketizer.outputUp());
if(!packetizer.input(tempBuffer))
continue; // This packet was not well formed
EthernetPacketizer::EthernetPacket decoded(data, header->caplen);
@@ -267,9 +270,8 @@ bool PCAP::close() {
pcap_close(iface.fp);
iface.fp = nullptr;
uint8_t flush;
WriteOperation flushop;
while(readQueue.try_dequeue(flush)) {}
readBuffer.clear();
while(writeQueue.try_dequeue(flushop)) {}
return true;
@@ -282,7 +284,7 @@ void PCAP::readTask() {
PCAP* driver = reinterpret_cast<PCAP*>(obj);
if(driver->ethPacketizer.inputUp({data, data + header->caplen})) {
const auto bytes = driver->ethPacketizer.outputUp();
driver->readQueue.enqueue_bulk(bytes.data(), bytes.size());
driver->readBuffer.write(bytes.data(), bytes.size());
}
}, (uint8_t*)this);
}