Skip to content

Adjust acquisition thread to never overwrite circular buffer, keep track of pending frames, always fetch oldest frame. - #47

Open
Jakub Wlodek (jwlodek) wants to merge 5 commits into
NSLS2:mainfrom
jwlodek:eof-ring-buffer-fix
Open

Jakub Wlodek (jwlodek) wants to merge 5 commits into
NSLS2:mainfrom
jwlodek:eof-ring-buffer-fix

Conversation

@jwlodek

Copy link
Copy Markdown
Collaborator
  • Use CIRC_NO_OVERWRITE mode, and keep track of frames pending in circular buffer. Also track dropped frames
  • Remove defaults

Copilot AI balanced review requested due to automatic review settings October 13, 2026 16:38

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Error and synchronization paths can leave frame-buffer state invalid or discard valid EOF notifications.

3 open findings
What changed in this PR

Updates continuous acquisition to preserve buffered frames and expose queue diagnostics/configuration.

Changes:

  • Uses non-overwriting circular buffers and retrieves the oldest frame.
  • Tracks pending and dropped frames.
  • Adds configurable buffer sizing and unique-ID sources.
File Description
kinetixApp/​src/​ADKinetixDS.h Adds pending-frame state.
kinetixApp/​src/​ADKinetix.h Defines new parameters and unique-ID options.
kinetixApp/​src/​ADKinetix.cpp Implements buffered frame retrieval and diagnostics.
kinetixApp/​Db/​ADKinetix.template Adds corresponding EPICS records.
kinetixApp/​Db/​ADKinetix_settings.req Persists new configurable settings.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

INFO_ARGS("Allocated circular buffer for %d frames. Total size: %d bytes.",
KTX_CIRC_BUFF_SIZE, frameBufferSize * KTX_CIRC_BUFF_SIZE);
// Allocate entire circular buffer; PVCam takes its total size as uns32
uint64_t circBuffBytes = (uint64_t) circBuffSize * frameBufferSize;
Comment on lines +987 to +990
{
std::lock_guard<std::mutex> lock(this->cameraContext->eofEvent.mutex);
this->cameraContext->pendingFrames = 0;
}
Comment on lines +1043 to +1044
if (continuousMode && PV_OK != pl_exp_unlock_oldest_frame(this->cameraContext->hcam))
reportKinetixError(functionName);
Copilot AI balanced review requested due to automatic review settings October 13, 2026 16:56

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Failed dequeues can erase concurrently delivered EOF notifications and strand buffered frames.

3 open findings

🧠 Review effort: Balanced

Copilot AI balanced review requested due to automatic review settings October 14, 2026 20:22

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Concurrent stop/start requests can create overlapping acquisition workers and compromise shared buffer ownership.

4 open findings

🧠 Review effort: Balanced

Comment on lines +775 to +777
this->unlock();
epicsThreadMustJoin(this->acquisitionThreadId);
this->lock();
Copilot AI balanced review requested due to automatic review settings October 14, 2026 20:37

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Frame-number arithmetic can overflow, and startup failures do not retain an error status.

4 open findings
Previously missed (2)

In code that hasn't changed since last review

Medium severity Report allocation failures before publishing acquisition status

kinetixApp/​src/​ADKinetix.cpp:974

When buffer allocation or frame-info creation fails, execution still publishes ADStatusWaiting or ADStatusAcquire, skips the acquisition loop, and ends with ADStatusIdle. This hides the startup failure from status consumers. Clean up and return with ADStatusError before publishing an acquiring status.

Medium severity Prevent signed overflow at INT32_MAX frame number

kinetixApp/​src/​ADKinetix.cpp:1009

If a continuous acquisition reaches INT32_MAX, the next comparison evaluates lastFrameNr + 1 with signed 32-bit arithmetic, causing undefined behavior. Promote the addition to 64 bits to keep this comparison safe at the frame-number boundary.

🧠 Review effort: Balanced

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants