Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions include/silk/fibers/sequencer.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,12 @@ class FiberSequencer
return true;
}

/**
* Rebase the counter to @p value, up or down. The caller guarantees quiescence: no registered waiter
* and no concurrent increment / advance / wait.
*/
Comment on lines +129 to +132
void reset(uint64_t value) noexcept;

/**
* Transition into the stopped state and wake every unreached waiter with
* ECANCELED. After this, every unreached wait completes with ECANCELED
Expand Down
6 changes: 6 additions & 0 deletions src/fibers/sequencer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@
namespace silk
{

void FiberSequencer::reset(uint64_t value) noexcept
{
SILK_ASSERT(waiters.empty());
counter.store(value, std::memory_order_release);
}
Comment on lines +10 to +14

void FiberSequencer::registerWaiter(uint64_t token, Future * future) noexcept
{
// Slow path: register future in the request queue for the next combiner to process.
Expand Down
25 changes: 25 additions & 0 deletions src/fibers/tests/sequencer-test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,31 @@ TEST(FiberSequencer, waitAlreadySatisfied)
EXPECT_EQ(sequencer.wait(1), 0);
}

TEST(FiberSequencer, resetRebasesBelowCounter)
{
FiberSequencer sequencer;
bool advanced = sequencer.advance(10);
ASSERT_TRUE(advanced);

sequencer.reset(3);
ASSERT_EQ(sequencer.get(), 3u);

// A wait at or below the rebased counter completes immediately.
int r = sequencer.wait(3);
ASSERT_EQ(r, 0);

// A wait above it parks until advance reaches the token again.
FiberSequencer::Future future;
sequencer.wait(4, &future);
int err;
ASSERT_FALSE(future.isSet(&err));

advanced = sequencer.advance(4);
ASSERT_TRUE(advanced);
ASSERT_TRUE(future.isSet(&err));
ASSERT_EQ(err, 0);
}

TEST(FiberSequencer, stopCancelsUnreachedWaiters)
{
FiberSequencer sequencer;
Expand Down