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
+21 -28
View File
@@ -6,7 +6,6 @@
#include <boost/asio/deadline_timer.hpp> #include <boost/asio/deadline_timer.hpp>
#include <boost/system/error_code.hpp> #include <boost/system/error_code.hpp>
#include <spinLock.h> #include <spinLock.h>
#include <asynchronousBridge.h>
#include <user/stimulusBuffer.h> #include <user/stimulusBuffer.h>
namespace smo { namespace smo {
@@ -14,37 +13,21 @@ namespace stim_buff {
void StimulusBuffer::stop() void StimulusBuffer::stop()
{ {
shouldContinue.store(false); {
SpinLock::Guard lock(shouldContinueLock);
shouldContinue = false;
}
// Set up a timeout bridge using the io_service // Cancel timer immediately
boost::asio::deadline_timer delayTimer(ioService); timer.cancel();
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;
// Always signal complete, whether timeout expired or was cancelled
bridge.setAsyncOperationComplete();
});
bridge.waitForAsyncOperationCompleteOrIoServiceStopped();
std::cout << __func__ << ": Stopped stimulus buffer for device " std::cout << __func__ << ": Stopped stimulus buffer for device "
<< deviceAttachmentSpec->deviceSelector << std::endl; << deviceAttachmentSpec->deviceSelector << std::endl;
// After delay, cancel timer and perform cleanup
timer.cancel();
} }
void StimulusBuffer::scheduleNextTimeout(int delayMs) void StimulusBuffer::scheduleNextTimeout(int delayMs)
{ {
if (!shouldContinue.load()) if (!shouldContinue)
{ return; } { return; }
// Schedule the next timeout using the provided delay // Schedule the next timeout using the provided delay
@@ -70,7 +53,8 @@ void StimulusBuffer::onTimeout(const boost::system::error_code& error)
return; return;
} }
if (!shouldContinue.load()) SpinLock::Guard lock(shouldContinueLock);
if (!shouldContinue)
{ return; } { return; }
/** EXPLANATION: /** 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. * sleep for CONFIG_STIMBUFF_FRAME_RETRY_DELAY_MS ms before trying again.
*/ */
int nextWakeupDelayMs; int nextWakeupDelayMs;
bool deferred = false;
if (frameAssemblyRateLimiter.tryAcquire()) if (frameAssemblyRateLimiter.tryAcquire())
{ {
nextWakeupDelayMs = CONFIG_STIMBUFF_FRAME_PERIOD_MS; nextWakeupDelayMs = CONFIG_STIMBUFF_FRAME_PERIOD_MS;
@@ -97,13 +82,21 @@ void StimulusBuffer::onTimeout(const boost::system::error_code& error)
*/ */
stimFrameProductionTimesliceInd(); stimFrameProductionTimesliceInd();
} }
else { else
std::cout << __func__ << ": Deferring frame production due to rate limit." << std::endl; {
nextWakeupDelayMs = CONFIG_STIMBUFF_FRAME_RETRY_DELAY_MS; nextWakeupDelayMs = CONFIG_STIMBUFF_FRAME_RETRY_DELAY_MS;
deferred = true;
} }
// Schedule next timeout with the pre-determined duration // Schedule next timeout with the pre-determined duration
scheduleNextTimeout(nextWakeupDelayMs); 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 } // namespace stim_buff
+3 -3
View File
@@ -13,7 +13,6 @@
#include <boost/asio/io_service.hpp> #include <boost/asio/io_service.hpp>
#include <boost/asio/deadline_timer.hpp> #include <boost/asio/deadline_timer.hpp>
#include <spinLock.h> #include <spinLock.h>
#include <asynchronousBridge.h>
#include <user/spMcRingBuffer.h> #include <user/spMcRingBuffer.h>
#include "stimulusFrame.h" #include "stimulusFrame.h"
#include "deviceAttachmentSpec.h" #include "deviceAttachmentSpec.h"
@@ -74,7 +73,7 @@ public:
std::cout << __func__ << ": Starting stimulus buffer for device " std::cout << __func__ << ": Starting stimulus buffer for device "
<< deviceAttachmentSpec->deviceSelector << std::endl; << deviceAttachmentSpec->deviceSelector << std::endl;
shouldContinue.store(true); shouldContinue = true;
scheduleNextTimeout(); scheduleNextTimeout();
} }
@@ -105,7 +104,8 @@ protected:
private: private:
boost::asio::io_service& ioService; boost::asio::io_service& ioService;
std::atomic<bool> shouldContinue; SpinLock shouldContinueLock;
bool shouldContinue;
boost::asio::deadline_timer timer; boost::asio::deadline_timer timer;
void scheduleNextTimeout(int delayMs = CONFIG_STIMBUFF_FRAME_PERIOD_MS); void scheduleNextTimeout(int delayMs = CONFIG_STIMBUFF_FRAME_PERIOD_MS);