StimBuff: Add opportunity for early lock release

This commit is contained in:
2025-11-12 15:08:44 -04:00
parent d87c71b794
commit 116a642a9f
2 changed files with 24 additions and 31 deletions
+19 -26
View File
@@ -6,7 +6,6 @@
#include <boost/asio/deadline_timer.hpp>
#include <boost/system/error_code.hpp>
#include <spinLock.h>
#include <asynchronousBridge.h>
#include <user/stimulusBuffer.h>
namespace smo {
@@ -14,37 +13,21 @@ namespace stim_buff {
void StimulusBuffer::stop()
{
shouldContinue.store(false);
// Set up a timeout bridge using the io_service
boost::asio::deadline_timer delayTimer(ioService);
AsynchronousBridge bridge(ioService);
// Set up the delay to let in-flight operation finish
delayTimer.expires_from_now(
boost::posix_time::milliseconds(getStopDelayMs()));
delayTimer.async_wait(
[&bridge](const boost::system::error_code& error)
{
(void)error;
SpinLock::Guard lock(shouldContinueLock);
shouldContinue = false;
}
// Always signal complete, whether timeout expired or was cancelled
bridge.setAsyncOperationComplete();
});
bridge.waitForAsyncOperationCompleteOrIoServiceStopped();
// Cancel timer immediately
timer.cancel();
std::cout << __func__ << ": Stopped stimulus buffer for device "
<< deviceAttachmentSpec->deviceSelector << std::endl;
// After delay, cancel timer and perform cleanup
timer.cancel();
}
void StimulusBuffer::scheduleNextTimeout(int delayMs)
{
if (!shouldContinue.load())
if (!shouldContinue)
{ return; }
// Schedule the next timeout using the provided delay
@@ -70,7 +53,8 @@ void StimulusBuffer::onTimeout(const boost::system::error_code& error)
return;
}
if (!shouldContinue.load())
SpinLock::Guard lock(shouldContinueLock);
if (!shouldContinue)
{ return; }
/** EXPLANATION:
@@ -85,6 +69,7 @@ void StimulusBuffer::onTimeout(const boost::system::error_code& error)
* sleep for CONFIG_STIMBUFF_FRAME_RETRY_DELAY_MS ms before trying again.
*/
int nextWakeupDelayMs;
bool deferred = false;
if (frameAssemblyRateLimiter.tryAcquire())
{
nextWakeupDelayMs = CONFIG_STIMBUFF_FRAME_PERIOD_MS;
@@ -97,13 +82,21 @@ void StimulusBuffer::onTimeout(const boost::system::error_code& error)
*/
stimFrameProductionTimesliceInd();
}
else {
std::cout << __func__ << ": Deferring frame production due to rate limit." << std::endl;
else
{
nextWakeupDelayMs = CONFIG_STIMBUFF_FRAME_RETRY_DELAY_MS;
deferred = true;
}
// Schedule next timeout with the pre-determined duration
scheduleNextTimeout(nextWakeupDelayMs);
// We should be able to release the start/stop lock before printing here.
if (deferred)
{
std::cout << __func__ << ": Deferring frame by " << nextWakeupDelayMs
<< "ms due to rate limit." << std::endl;
}
}
} // namespace stim_buff
+3 -3
View File
@@ -13,7 +13,6 @@
#include <boost/asio/io_service.hpp>
#include <boost/asio/deadline_timer.hpp>
#include <spinLock.h>
#include <asynchronousBridge.h>
#include <user/spMcRingBuffer.h>
#include "stimulusFrame.h"
#include "deviceAttachmentSpec.h"
@@ -74,7 +73,7 @@ public:
std::cout << __func__ << ": Starting stimulus buffer for device "
<< deviceAttachmentSpec->deviceSelector << std::endl;
shouldContinue.store(true);
shouldContinue = true;
scheduleNextTimeout();
}
@@ -105,7 +104,8 @@ protected:
private:
boost::asio::io_service& ioService;
std::atomic<bool> shouldContinue;
SpinLock shouldContinueLock;
bool shouldContinue;
boost::asio::deadline_timer timer;
void scheduleNextTimeout(int delayMs = CONFIG_STIMBUFF_FRAME_PERIOD_MS);