Skip to content

Commit 9db941d

Browse files
author
MacroFake
committed
Merge bitcoin/bitcoin#25100: Switch scheduler to steady_clock
fa90516 Switch scheduler to steady_clock (MacroFake) Pull request description: There is already `mockscheduler`, so it seems brittle, confusing and redundant to be able to mock the scheduler by adjusting the system clock. ACKs for top commit: laanwj: Code review ACK fa90516 w0xlt: crACK bitcoin/bitcoin@fa90516 Tree-SHA512: 60e99065ffb881a9fb25a346d311d99424fbc72a3b636c94b5f5c17ed6373c40f358a9b27825c518d12968c033e6cfd3c62d2b62cacdddc44a0b5b74f6c1a7ae
2 parents cca900e + fa90516 commit 9db941d

File tree

3 files changed

+27
-27
lines changed

3 files changed

+27
-27
lines changed

src/scheduler.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@
44

55
#include <scheduler.h>
66

7-
#include <random.h>
7+
#include <sync.h>
88
#include <util/syscall_sandbox.h>
99
#include <util/time.h>
1010

11-
#include <assert.h>
11+
#include <cassert>
1212
#include <functional>
1313
#include <utility>
1414

@@ -43,7 +43,7 @@ void CScheduler::serviceQueue()
4343
// the time of the first item on the queue:
4444

4545
while (!shouldStop() && !taskQueue.empty()) {
46-
std::chrono::system_clock::time_point timeToWaitFor = taskQueue.begin()->first;
46+
std::chrono::steady_clock::time_point timeToWaitFor = taskQueue.begin()->first;
4747
if (newTaskScheduled.wait_until(lock, timeToWaitFor) == std::cv_status::timeout) {
4848
break; // Exit loop after timeout, it means we reached the time of the event
4949
}
@@ -72,7 +72,7 @@ void CScheduler::serviceQueue()
7272
newTaskScheduled.notify_one();
7373
}
7474

75-
void CScheduler::schedule(CScheduler::Function f, std::chrono::system_clock::time_point t)
75+
void CScheduler::schedule(CScheduler::Function f, std::chrono::steady_clock::time_point t)
7676
{
7777
{
7878
LOCK(newTaskMutex);
@@ -89,7 +89,7 @@ void CScheduler::MockForward(std::chrono::seconds delta_seconds)
8989
LOCK(newTaskMutex);
9090

9191
// use temp_queue to maintain updated schedule
92-
std::multimap<std::chrono::system_clock::time_point, Function> temp_queue;
92+
std::multimap<std::chrono::steady_clock::time_point, Function> temp_queue;
9393

9494
for (const auto& element : taskQueue) {
9595
temp_queue.emplace_hint(temp_queue.cend(), element.first - delta_seconds, element.second);
@@ -114,8 +114,8 @@ void CScheduler::scheduleEvery(CScheduler::Function f, std::chrono::milliseconds
114114
scheduleFromNow([this, f, delta] { Repeat(*this, f, delta); }, delta);
115115
}
116116

117-
size_t CScheduler::getQueueInfo(std::chrono::system_clock::time_point& first,
118-
std::chrono::system_clock::time_point& last) const
117+
size_t CScheduler::getQueueInfo(std::chrono::steady_clock::time_point& first,
118+
std::chrono::steady_clock::time_point& last) const
119119
{
120120
LOCK(newTaskMutex);
121121
size_t result = taskQueue.size();
@@ -143,7 +143,7 @@ void SingleThreadedSchedulerClient::MaybeScheduleProcessQueue()
143143
if (m_are_callbacks_running) return;
144144
if (m_callbacks_pending.empty()) return;
145145
}
146-
m_scheduler.schedule([this] { this->ProcessQueue(); }, std::chrono::system_clock::now());
146+
m_scheduler.schedule([this] { this->ProcessQueue(); }, std::chrono::steady_clock::now());
147147
}
148148

149149
void SingleThreadedSchedulerClient::ProcessQueue()

src/scheduler.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,12 @@ class CScheduler
4646
typedef std::function<void()> Function;
4747

4848
/** Call func at/after time t */
49-
void schedule(Function f, std::chrono::system_clock::time_point t);
49+
void schedule(Function f, std::chrono::steady_clock::time_point t);
5050

5151
/** Call f once after the delta has passed */
5252
void scheduleFromNow(Function f, std::chrono::milliseconds delta)
5353
{
54-
schedule(std::move(f), std::chrono::system_clock::now() + delta);
54+
schedule(std::move(f), std::chrono::steady_clock::now() + delta);
5555
}
5656

5757
/**
@@ -93,16 +93,16 @@ class CScheduler
9393
* Returns number of tasks waiting to be serviced,
9494
* and first and last task times
9595
*/
96-
size_t getQueueInfo(std::chrono::system_clock::time_point& first,
97-
std::chrono::system_clock::time_point& last) const;
96+
size_t getQueueInfo(std::chrono::steady_clock::time_point& first,
97+
std::chrono::steady_clock::time_point& last) const;
9898

9999
/** Returns true if there are threads actively running in serviceQueue() */
100100
bool AreThreadsServicingQueue() const;
101101

102102
private:
103103
mutable Mutex newTaskMutex;
104104
std::condition_variable newTaskScheduled;
105-
std::multimap<std::chrono::system_clock::time_point, Function> taskQueue GUARDED_BY(newTaskMutex);
105+
std::multimap<std::chrono::steady_clock::time_point, Function> taskQueue GUARDED_BY(newTaskMutex);
106106
int nThreadsServicingQueue GUARDED_BY(newTaskMutex){0};
107107
bool stopRequested GUARDED_BY(newTaskMutex){false};
108108
bool stopWhenEmpty GUARDED_BY(newTaskMutex){false};

src/test/scheduler_tests.cpp

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,13 @@
1515

1616
BOOST_AUTO_TEST_SUITE(scheduler_tests)
1717

18-
static void microTask(CScheduler& s, std::mutex& mutex, int& counter, int delta, std::chrono::system_clock::time_point rescheduleTime)
18+
static void microTask(CScheduler& s, std::mutex& mutex, int& counter, int delta, std::chrono::steady_clock::time_point rescheduleTime)
1919
{
2020
{
2121
std::lock_guard<std::mutex> lock(mutex);
2222
counter += delta;
2323
}
24-
std::chrono::system_clock::time_point noTime = std::chrono::system_clock::time_point::min();
24+
auto noTime = std::chrono::steady_clock::time_point::min();
2525
if (rescheduleTime != noTime) {
2626
CScheduler::Function f = std::bind(&microTask, std::ref(s), std::ref(mutex), std::ref(counter), -delta + 1, noTime);
2727
s.schedule(f, rescheduleTime);
@@ -49,15 +49,15 @@ BOOST_AUTO_TEST_CASE(manythreads)
4949
auto randomMsec = [](FastRandomContext& rc) -> int { return -11 + (int)rc.randrange(1012); }; // [-11, 1000]
5050
auto randomDelta = [](FastRandomContext& rc) -> int { return -1000 + (int)rc.randrange(2001); }; // [-1000, 1000]
5151

52-
std::chrono::system_clock::time_point start = std::chrono::system_clock::now();
53-
std::chrono::system_clock::time_point now = start;
54-
std::chrono::system_clock::time_point first, last;
52+
auto start = std::chrono::steady_clock::now();
53+
auto now = start;
54+
std::chrono::steady_clock::time_point first, last;
5555
size_t nTasks = microTasks.getQueueInfo(first, last);
5656
BOOST_CHECK(nTasks == 0);
5757

5858
for (int i = 0; i < 100; ++i) {
59-
std::chrono::system_clock::time_point t = now + std::chrono::microseconds(randomMsec(rng));
60-
std::chrono::system_clock::time_point tReschedule = now + std::chrono::microseconds(500 + randomMsec(rng));
59+
auto t = now + std::chrono::microseconds(randomMsec(rng));
60+
auto tReschedule = now + std::chrono::microseconds(500 + randomMsec(rng));
6161
int whichCounter = zeroToNine(rng);
6262
CScheduler::Function f = std::bind(&microTask, std::ref(microTasks),
6363
std::ref(counterMutex[whichCounter]), std::ref(counter[whichCounter]),
@@ -75,14 +75,14 @@ BOOST_AUTO_TEST_CASE(manythreads)
7575
microThreads.emplace_back(std::bind(&CScheduler::serviceQueue, &microTasks));
7676

7777
UninterruptibleSleep(std::chrono::microseconds{600});
78-
now = std::chrono::system_clock::now();
78+
now = std::chrono::steady_clock::now();
7979

8080
// More threads and more tasks:
8181
for (int i = 0; i < 5; i++)
8282
microThreads.emplace_back(std::bind(&CScheduler::serviceQueue, &microTasks));
8383
for (int i = 0; i < 100; i++) {
84-
std::chrono::system_clock::time_point t = now + std::chrono::microseconds(randomMsec(rng));
85-
std::chrono::system_clock::time_point tReschedule = now + std::chrono::microseconds(500 + randomMsec(rng));
84+
auto t = now + std::chrono::microseconds(randomMsec(rng));
85+
auto tReschedule = now + std::chrono::microseconds(500 + randomMsec(rng));
8686
int whichCounter = zeroToNine(rng);
8787
CScheduler::Function f = std::bind(&microTask, std::ref(microTasks),
8888
std::ref(counterMutex[whichCounter]), std::ref(counter[whichCounter]),
@@ -111,8 +111,8 @@ BOOST_AUTO_TEST_CASE(wait_until_past)
111111
Mutex mtx;
112112
WAIT_LOCK(mtx, lock);
113113

114-
const auto no_wait= [&](const std::chrono::seconds& d) {
115-
return condvar.wait_until(lock, std::chrono::system_clock::now() - d);
114+
const auto no_wait = [&](const std::chrono::seconds& d) {
115+
return condvar.wait_until(lock, std::chrono::steady_clock::now() - d);
116116
};
117117

118118
BOOST_CHECK(std::cv_status::timeout == no_wait(std::chrono::seconds{1}));
@@ -183,7 +183,7 @@ BOOST_AUTO_TEST_CASE(mockforward)
183183
scheduler.scheduleFromNow(dummy, std::chrono::minutes{8});
184184

185185
// check taskQueue
186-
std::chrono::system_clock::time_point first, last;
186+
std::chrono::steady_clock::time_point first, last;
187187
size_t num_tasks = scheduler.getQueueInfo(first, last);
188188
BOOST_CHECK_EQUAL(num_tasks, 3ul);
189189

@@ -204,7 +204,7 @@ BOOST_AUTO_TEST_CASE(mockforward)
204204
BOOST_CHECK_EQUAL(counter, 2);
205205

206206
// check that the time of the remaining job has been updated
207-
std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
207+
auto now = std::chrono::steady_clock::now();
208208
int delta = std::chrono::duration_cast<std::chrono::seconds>(first - now).count();
209209
// should be between 2 & 3 minutes from now
210210
BOOST_CHECK(delta > 2*60 && delta < 3*60);

0 commit comments

Comments
 (0)