From 3ac76c00207c2d9fca46e067c1d11a6a8af4b849 Mon Sep 17 00:00:00 2001 From: Florian Fischer <florian.fischer@muhq.space> Date: Sun, 4 Sep 2022 17:06:20 +0200 Subject: [PATCH] AbstractIoSleepStrategy: remove erroneous assertion In my master's thesis, I described in listing 4.4 an io_uring-based suspension and notification algorithm, which is slightly different from what emper does. The described algorithm does not reset the sleep state if a worker skips sleeping because of a global sleeper count of less than 0 (line 21). Emper does always reset the sleep state to SleeperState::Running if the sleep method returned early (either the worker was specifically notified or the global sleep count indicated to skip the sleep attempt). Both variants are sound, but invariably resetting the sleeper count to running minimizes the windows of useless specific notifications. However, the assertion in onNewWorkNotification assumes the sleep state is always SleeperState::Notified if a specific notification is received through the worker's io_uring. Emper, resetting the sleep state, introduces a race between the notifier observing the state as sleeping, setting it to notified, and posting a notification to the potential sleeper's io_uring. But the sleeper skips the sleep attempt because the global sleeper count righteously resetting its state to running while invalidating the assertion. Therefore we remove the assertion because it is not invariant. --- emper/sleep_strategy/AbstractIoSleepStrategy.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/emper/sleep_strategy/AbstractIoSleepStrategy.cpp b/emper/sleep_strategy/AbstractIoSleepStrategy.cpp index 188fb696..6eae8bdc 100644 --- a/emper/sleep_strategy/AbstractIoSleepStrategy.cpp +++ b/emper/sleep_strategy/AbstractIoSleepStrategy.cpp @@ -123,16 +123,13 @@ void AbstractIoSleepStrategy::onNewWorkNotification(IoContext& io, if (data.isMarked()) { LOGD("Got specific notification"); - - ATTR_UNUSED auto oldState = - sleepState.exchange(SleeperState::Running, std::memory_order_release); - assert(oldState == SleeperState::Notified); } else { LOGD("Got new work notification"); - sleepState.store(SleeperState::Running, std::memory_order_release); // Reset global flag to indicate that a new sleep cqe must be prepared readingGlobal = false; } + + sleepState.store(SleeperState::Running, std::memory_order_release); } template void AbstractIoSleepStrategy::onNewWorkNotification<CallerEnvironment::OWNER>( -- GitLab