mirror of
https://github.com/intrepidcs/libicsneo.git
synced 2026-08-05 01:18:36 +02:00
Replace concurrentqueue with ringbuffer
This commit is contained in:
+2
-3
@@ -89,9 +89,8 @@ bool FTD3XX::close() {
|
||||
if(writeThread.joinable())
|
||||
writeThread.join();
|
||||
|
||||
uint8_t flush;
|
||||
WriteOperation flushop;
|
||||
while(readQueue.try_dequeue(flush)) {}
|
||||
readBuffer.pop(readBuffer.size());
|
||||
while(writeQueue.try_dequeue(flushop)) {}
|
||||
|
||||
if(const auto ret = FT_Close(*handle); ret != FT_OK) {
|
||||
@@ -137,7 +136,7 @@ void FTD3XX::readTask() {
|
||||
}
|
||||
FT_ReleaseOverlapped(*handle, &overlap);
|
||||
if(received > 0) {
|
||||
readQueue.enqueue_bulk(buffer, received);
|
||||
readBuffer.write(buffer, received);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
+2
-3
@@ -510,9 +510,8 @@ bool TCP::close() {
|
||||
if(writeThread.joinable())
|
||||
writeThread.join();
|
||||
|
||||
uint8_t flush;
|
||||
WriteOperation flushop;
|
||||
while(readQueue.try_dequeue(flush)) {}
|
||||
readBuffer.pop(readBuffer.size());
|
||||
while(writeQueue.try_dequeue(flushop)) {}
|
||||
|
||||
socket.reset();
|
||||
@@ -534,7 +533,7 @@ void TCP::readTask() {
|
||||
uint8_t readbuf[READ_BUFFER_SIZE];
|
||||
while(!closing) {
|
||||
if(const auto received = ::recv(*socket, (char*)readbuf, READ_BUFFER_SIZE, 0); received > 0) {
|
||||
readQueue.enqueue_bulk(readbuf, received);
|
||||
readBuffer.write(readbuf, received);
|
||||
} else {
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = 50'000;
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "icsneo/communication/ethernetpacketizer.h"
|
||||
#include "icsneo/communication/packetizer.h"
|
||||
#include "icsneo/communication/decoder.h"
|
||||
#include "icsneo/communication/ringbuffer.h"
|
||||
#include <pcap.h>
|
||||
#include <iphlpapi.h>
|
||||
#pragma comment(lib, "IPHLPAPI.lib")
|
||||
@@ -123,7 +124,9 @@ void PCAP::Find(std::vector<FoundDevice>& found) {
|
||||
auto bs = requestPacket.getBytestream();
|
||||
pcap.sendpacket(iface.fp, bs.data(), (int)bs.size());
|
||||
|
||||
auto timeout = std::chrono::high_resolution_clock::now() + std::chrono::milliseconds(5);
|
||||
auto timeout = std::chrono::high_resolution_clock::now() + std::chrono::milliseconds(250);
|
||||
constexpr const size_t TempBufferSize = 4096;
|
||||
RingBuffer tempBuffer(TempBufferSize);
|
||||
while(std::chrono::high_resolution_clock::now() <= timeout) { // Wait up to 5ms for the response
|
||||
struct pcap_pkthdr* header;
|
||||
const uint8_t* data;
|
||||
@@ -142,7 +145,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);
|
||||
@@ -251,9 +255,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)) {}
|
||||
transmitQueue = nullptr;
|
||||
|
||||
@@ -275,7 +278,7 @@ void PCAP::readTask() {
|
||||
|
||||
if(ethPacketizer.inputUp({data, data + header->caplen})) {
|
||||
const auto bytes = ethPacketizer.outputUp();
|
||||
readQueue.enqueue_bulk(bytes.data(), bytes.size());
|
||||
readBuffer.write(bytes.data(), bytes.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -357,9 +357,8 @@ bool VCP::close() {
|
||||
detail->overlappedWait.hEvent = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
uint8_t flush;
|
||||
WriteOperation flushop;
|
||||
while(readQueue.try_dequeue(flush)) {}
|
||||
readBuffer.clear();
|
||||
while(writeQueue.try_dequeue(flushop)) {}
|
||||
|
||||
if(!ret)
|
||||
@@ -391,7 +390,7 @@ void VCP::readTask() {
|
||||
if(ReadFile(detail->handle, readbuf, READ_BUFFER_SIZE, nullptr, &detail->overlappedRead)) {
|
||||
if(GetOverlappedResult(detail->handle, &detail->overlappedRead, &bytesRead, FALSE)) {
|
||||
if(bytesRead)
|
||||
readQueue.enqueue_bulk(readbuf, bytesRead);
|
||||
readBuffer.write(readbuf, bytesRead);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@@ -414,7 +413,7 @@ void VCP::readTask() {
|
||||
auto ret = WaitForSingleObject(detail->overlappedRead.hEvent, 100);
|
||||
if(ret == WAIT_OBJECT_0) {
|
||||
if(GetOverlappedResult(detail->handle, &detail->overlappedRead, &bytesRead, FALSE)) {
|
||||
readQueue.enqueue_bulk(readbuf, bytesRead);
|
||||
readBuffer.write(readbuf, bytesRead);
|
||||
state = LAUNCH;
|
||||
} else
|
||||
report(APIEvent::Type::FailedToRead, APIEvent::Severity::Error);
|
||||
|
||||
Reference in New Issue
Block a user