From 4907014e490a45b3eacce56889751d2399a55c7a Mon Sep 17 00:00:00 2001 From: Filip Leonarski Date: Sun, 8 Nov 2026 07:49:07 +0100 Subject: [PATCH] ImageBuffer::GetSlotStatus: the slot counters without scanning the buffer, for every image JFJochReceiverFPGA and JFJochReceiverRugnuxStills read three slot counters for each image through GetStatus, which walks every slot under the buffer mutex, lists the image numbers and sorts them. With a buffer sized for 2 kHz (thousands of slots) that is about a core of CPU and time on the mutex every other buffer user needs. GetSlotStatus returns only the counters; GetStatus stays for the HTTP status. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01HVeDQsU5a8AJUdJPgWevAK --- common/ImageBuffer.cpp | 11 +++++++++++ common/ImageBuffer.h | 2 ++ receiver/JFJochReceiverFPGA.cpp | 2 +- receiver/JFJochReceiverRugnuxStills.cpp | 2 +- tests/ImageBufferTest.cpp | 4 ++++ 5 files changed, 19 insertions(+), 2 deletions(-) diff --git a/common/ImageBuffer.cpp b/common/ImageBuffer.cpp index 6d448e809..22b3c882c 100644 --- a/common/ImageBuffer.cpp +++ b/common/ImageBuffer.cpp @@ -324,6 +324,17 @@ size_t ImageBuffer::GetBufferSize() const { return buffer_size; } +ImageBufferStatus ImageBuffer::GetSlotStatus() const { + ImageBufferStatus ret{}; + std::unique_lock ul(m); + ret.total_slots = slot_count; + ret.available_slots = slot_count - slots_sending - slots_preparation; + ret.preparation_slots = slots_preparation; + ret.sending_slots = slots_sending; + ret.current_counter = counter; + return ret; +} + ImageBufferStatus ImageBuffer::GetStatus() const { ImageBufferStatus ret; { diff --git a/common/ImageBuffer.h b/common/ImageBuffer.h index 8c954d419..e480b7b19 100644 --- a/common/ImageBuffer.h +++ b/common/ImageBuffer.h @@ -92,5 +92,7 @@ public: void SaveStartMessage(const std::vector &msg); void GetStartMessage(std::vector &out_v); + // Only the slot counters, no image list: cheap enough to call for every image + ImageBufferStatus GetSlotStatus() const; ImageBufferStatus GetStatus() const; }; diff --git a/receiver/JFJochReceiverFPGA.cpp b/receiver/JFJochReceiverFPGA.cpp index 9d6d1c4a6..0bea442ac 100644 --- a/receiver/JFJochReceiverFPGA.cpp +++ b/receiver/JFJochReceiverFPGA.cpp @@ -350,7 +350,7 @@ void JFJochReceiverFPGA::FrameTransformationThread(uint32_t threadid) { analyzer->Process(message, local_spot_finding_settings); - auto status = image_buffer.GetStatus(); + auto status = image_buffer.GetSlotStatus(); message.receiver_buf_available = status.available_slots; message.receiver_buf_in_preparation = status.preparation_slots; message.receiver_buf_in_sending = status.sending_slots; diff --git a/receiver/JFJochReceiverRugnuxStills.cpp b/receiver/JFJochReceiverRugnuxStills.cpp index 704839001..f57343ee3 100644 --- a/receiver/JFJochReceiverRugnuxStills.cpp +++ b/receiver/JFJochReceiverRugnuxStills.cpp @@ -152,7 +152,7 @@ ZeroCopyReturnValue *JFJochReceiverRugnuxStills::AnalysedImageSlot() { void JFJochReceiverRugnuxStills::SendAnalysedImage(DataMessage &message, const AzimuthalIntegrationProfile &profile) { try { - const auto status = image_buffer.GetStatus(); + const auto status = image_buffer.GetSlotStatus(); message.receiver_buf_available = status.available_slots; message.receiver_buf_in_preparation = status.preparation_slots; message.receiver_buf_in_sending = status.sending_slots; diff --git a/tests/ImageBufferTest.cpp b/tests/ImageBufferTest.cpp index 977c5ad81..9cd262217 100644 --- a/tests/ImageBufferTest.cpp +++ b/tests/ImageBufferTest.cpp @@ -49,6 +49,10 @@ TEST_CASE("ImageBuffer") { REQUIRE(buf_ctrl.GetStatus().preparation_slots == 2); REQUIRE(buf_ctrl.GetStatus().sending_slots == 2); REQUIRE(buf_ctrl.GetStatus().available_slots == 0); + REQUIRE(buf_ctrl.GetSlotStatus().total_slots == 4); + REQUIRE(buf_ctrl.GetSlotStatus().preparation_slots == 2); + REQUIRE(buf_ctrl.GetSlotStatus().sending_slots == 2); + REQUIRE(buf_ctrl.GetSlotStatus().available_slots == 0); ret2->ReadyToSend(); ret3->ReadyToSend();