Skip to content

Commit db5a0f5

Browse files
committed
support: timer ticks based on io broker
1 parent d7b8c38 commit db5a0f5

File tree

3 files changed

+70
-4
lines changed

3 files changed

+70
-4
lines changed

lib/support/network/io_timer_source.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,17 @@ io_timer_source::io_timer_source(timer_manager& tick_sink_,
2121
std::chrono::milliseconds tick_period_) :
2222
tick_sink(tick_sink_), broker(broker_), tick_period(tick_period_), logger(srslog::fetch_basic_logger("IO-EPOLL"))
2323
{
24+
using namespace std::chrono;
25+
2426
timer_fd = unique_fd{timerfd_create(CLOCK_REALTIME, 0)};
2527
if (not timer_fd.is_open()) {
2628
report_fatal_error_if_not("Failed to create timer source (errno={})", strerror(errno));
2729
}
2830

29-
struct itimerspec timerspec = {{0, 0},
30-
{std::chrono::duration_cast<std::chrono::seconds>(tick_period).count(),
31-
std::chrono::duration_cast<std::chrono::nanoseconds>(tick_period).count()}};
31+
auto tsecs = duration_cast<seconds>(tick_period);
32+
auto tnsecs = duration_cast<nanoseconds>(tick_period) - duration_cast<nanoseconds>(tsecs);
33+
struct timespec period = {tsecs.count(), tnsecs.count()};
34+
struct itimerspec timerspec = {period, period};
3235
timerfd_settime(timer_fd.value(), 0, &timerspec, nullptr);
3336

3437
io_sub = broker.register_fd(

tests/unittests/support/network/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@
88

99
set_directory_properties(PROPERTIES LABELS "io_broker")
1010

11-
add_executable(network_test transport_layer_address_test.cpp io_broker_epoll_test.cpp)
11+
add_executable(network_test transport_layer_address_test.cpp io_broker_epoll_test.cpp io_timer_source_test.cpp)
1212
target_link_libraries(network_test srsran_network srsran_support srslog gtest gtest_main)
1313
gtest_discover_tests(network_test)
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
*
3+
* Copyright 2021-2024 Software Radio Systems Limited
4+
*
5+
* By using this file, you agree to the terms and conditions set
6+
* forth in the LICENSE file which can be found at the top level of
7+
* the distribution.
8+
*
9+
*/
10+
11+
#include "srsran/support/executors/manual_task_worker.h"
12+
#include "srsran/support/io/io_broker_factory.h"
13+
#include "srsran/support/io/io_timer_source.h"
14+
#include "srsran/support/timers.h"
15+
#include <gtest/gtest.h>
16+
#include <optional>
17+
18+
using namespace srsran;
19+
20+
class io_timer_source_test : public ::testing::Test
21+
{
22+
public:
23+
manual_task_worker worker{16};
24+
timer_manager timers{16};
25+
std::unique_ptr<io_broker> broker = create_io_broker(srsran::io_broker_type::epoll);
26+
27+
void start() { source.emplace(timers, *broker, std::chrono::milliseconds{1}); }
28+
29+
void stop() { source.reset(); }
30+
31+
std::optional<io_timer_source> source;
32+
};
33+
34+
TEST_F(io_timer_source_test, timer_gets_ticked_when_source_starts)
35+
{
36+
std::chrono::milliseconds run_duration{100};
37+
std::chrono::milliseconds timer_period{5};
38+
unsigned count = 0;
39+
unique_timer t = timers.create_unique_timer(worker);
40+
t.set(timer_period, [&count, &t](timer_id_t tid) {
41+
count++;
42+
t.run();
43+
});
44+
t.run();
45+
46+
std::this_thread::sleep_for(std::chrono::milliseconds{10});
47+
worker.run_pending_tasks();
48+
ASSERT_EQ(count, 0);
49+
50+
start();
51+
for (unsigned i = 0; i != run_duration.count(); i++) {
52+
std::this_thread::sleep_for(std::chrono::milliseconds{1});
53+
worker.run_pending_tasks();
54+
}
55+
ASSERT_GT(count, 1);
56+
fmt::print("Tick count: expected={} actual={}\n", run_duration / timer_period, count);
57+
58+
stop();
59+
count = 0;
60+
std::this_thread::sleep_for(std::chrono::milliseconds{10});
61+
worker.run_pending_tasks();
62+
ASSERT_EQ(count, 0);
63+
}

0 commit comments

Comments
 (0)