Skip to content

Commit 40c5dd5

Browse files
committed
roc_recv: --real-time cli parameter
NetworkLoop and IoPump got realtime priority as a parameter, and if it's not 0, attempt to elevate their threads priorities.
1 parent 6bd629e commit 40c5dd5

File tree

22 files changed

+207
-82
lines changed

22 files changed

+207
-82
lines changed

src/internal_modules/roc_core/target_posix/roc_core/thread.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,12 @@ uint64_t Thread::get_tid() {
4646
#endif
4747
}
4848

49-
bool Thread::enable_realtime() {
49+
bool Thread::enable_realtime(const int sched_prio) {
5050
sched_param param;
5151
memset(&param, 0, sizeof(param));
52-
param.sched_priority = sched_get_priority_max(SCHED_RR);
52+
param.sched_priority = sched_prio;
5353

54-
roc_log(LogDebug, "thread: set realtime priority");
54+
roc_log(LogInfo, "thread: set realtime priority");
5555
if (int err = pthread_setschedparam(pthread_self(), SCHED_RR, &param)) {
5656
roc_log(LogError,
5757
"thread: can't set realtime priority: pthread_setschedparam(): %s",

src/internal_modules/roc_core/target_posix/roc_core/thread.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ class Thread : public NonCopyable<Thread> {
3333
static uint64_t get_tid();
3434

3535
//! Raise current thread priority to realtime.
36-
ROC_ATTR_NODISCARD static bool enable_realtime();
36+
ROC_ATTR_NODISCARD static bool enable_realtime(const int sched_prio);
3737

3838
//! Check if thread was started and can be joined.
3939
//! @returns

src/internal_modules/roc_netio/target_libuv/roc_netio/network_loop.cpp

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -104,10 +104,13 @@ NetworkLoop::Tasks::ResolveEndpointAddress::get_address() const {
104104

105105
NetworkLoop::NetworkLoop(core::IPool& packet_pool,
106106
core::IPool& buffer_pool,
107+
const int realtime_prio,
107108
core::IArena& arena)
108109
: packet_factory_(packet_pool, buffer_pool)
110+
, realtime_prio_(realtime_prio)
109111
, arena_(arena)
110112
, started_(false)
113+
, thr_init_cond_(thr_init_mutex_)
111114
, loop_initialized_(false)
112115
, stop_sem_initialized_(false)
113116
, task_sem_initialized_(false)
@@ -140,17 +143,15 @@ NetworkLoop::NetworkLoop(core::IPool& packet_pool,
140143
task_sem_.data = this;
141144
task_sem_initialized_ = true;
142145

143-
if (!enable_realtime()) {
144-
roc_log(LogInfo,
145-
"network loop: can't set realtime priority of network thread. May need "
146-
"to be root");
147-
}
148146
if (!(started_ = Thread::start())) {
149147
init_status_ = status::StatusErrThread;
150148
return;
151149
}
152150

153-
init_status_ = status::StatusOK;
151+
while (init_status_ == status::NoStatus) {
152+
core::Mutex::Lock lock(thr_init_mutex_);
153+
thr_init_cond_.wait();
154+
}
154155
}
155156

156157
NetworkLoop::~NetworkLoop() {
@@ -285,6 +286,21 @@ void NetworkLoop::handle_resolved(ResolverRequest& req) {
285286

286287
void NetworkLoop::run() {
287288
roc_log(LogDebug, "network loop: starting event loop");
289+
if (realtime_prio_ > 0 && !enable_realtime(realtime_prio_)) {
290+
core::Mutex::Lock lock(thr_init_mutex_);
291+
292+
roc_log(LogError,
293+
"network loop: can't set realtime priority of network thread. May need "
294+
"to be root");
295+
init_status_ = status::StatusFailedRealtime;
296+
thr_init_cond_.signal();
297+
} else {
298+
core::Mutex::Lock lock(thr_init_mutex_);
299+
300+
roc_log(LogDebug, "network loop: elevated realtime priority");
301+
init_status_ = status::StatusOK;
302+
thr_init_cond_.signal();
303+
}
288304

289305
int err = uv_run(&loop_, UV_RUN_DEFAULT);
290306
if (err != 0) {

src/internal_modules/roc_netio/target_libuv/roc_netio/network_loop.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "roc_address/socket_addr.h"
1818
#include "roc_core/atomic.h"
1919
#include "roc_core/attributes.h"
20+
#include "roc_core/cond.h"
2021
#include "roc_core/iarena.h"
2122
#include "roc_core/ipool.h"
2223
#include "roc_core/list.h"
@@ -54,6 +55,8 @@ class NetworkLoop : private ITerminateHandler,
5455
//! Opaque port handle.
5556
typedef struct PortHandle* PortHandle;
5657

58+
enum { DEFAULT_PRIORITY = 0 };
59+
5760
//! Subclasses for specific tasks.
5861
class Tasks {
5962
public:
@@ -189,7 +192,10 @@ class NetworkLoop : private ITerminateHandler,
189192
//! Initialize.
190193
//! @remarks
191194
//! Start background thread if the object was successfully constructed.
192-
NetworkLoop(core::IPool& packet_pool, core::IPool& buffer_pool, core::IArena& arena);
195+
NetworkLoop(core::IPool& packet_pool,
196+
core::IPool& buffer_pool,
197+
const int realtime_prio,
198+
core::IArena& arena);
193199

194200
//! Destroy. Stop all receivers and senders.
195201
//! @remarks
@@ -248,10 +254,14 @@ class NetworkLoop : private ITerminateHandler,
248254
void task_resolve_endpoint_address_(NetworkTask&);
249255

250256
packet::PacketFactory packet_factory_;
257+
const uint8_t realtime_prio_;
251258
core::IArena& arena_;
252259

253260
bool started_;
254261

262+
core::Mutex thr_init_mutex_;
263+
core::Cond thr_init_cond_;
264+
255265
uv_loop_t loop_;
256266
bool loop_initialized_;
257267

src/internal_modules/roc_node/context.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ Context::Context(const ContextConfig& config, core::IArena& arena)
2323
"frame_buffer_pool", arena_, sizeof(core::Buffer) + config.max_frame_size)
2424
, processor_map_(arena_)
2525
, encoding_map_(arena_)
26-
, network_loop_(packet_pool_, packet_buffer_pool_, arena_)
26+
, network_loop_(packet_pool_, packet_buffer_pool_, (int)config.realtime_prio, arena_)
2727
, control_loop_(network_loop_, arena_)
2828
, init_status_(status::NoStatus) {
2929
roc_log(LogDebug, "context: initializing");

src/internal_modules/roc_node/context.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,13 @@ struct ContextConfig {
3535
//! Maximum size in bytes of an audio frame.
3636
size_t max_frame_size;
3737

38+
//! Set real-time priority. Requires root priviligies.
39+
int realtime_prio;
40+
3841
ContextConfig()
3942
: max_packet_size(2048)
40-
, max_frame_size(4096) {
43+
, max_frame_size(4096)
44+
, realtime_prio(0) {
4145
}
4246
};
4347

src/internal_modules/roc_rtcp/rtt_estimator.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@
1212
namespace roc {
1313
namespace rtcp {
1414

15-
RttEstimator::RttEstimator(const RttConfig &config, core::IArena &arena, dbgio::CsvDumper *dumper)
15+
RttEstimator::RttEstimator(const RttConfig& config,
16+
core::IArena& arena,
17+
dbgio::CsvDumper* dumper)
1618
: config_(config)
1719
, metrics_()
1820
, has_metrics_(false)

src/internal_modules/roc_rtcp/rtt_estimator.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ struct RttMetrics {
6363
class RttEstimator {
6464
public:
6565
//! Initialize.
66-
RttEstimator(const RttConfig &config, core::IArena &arena, dbgio::CsvDumper *dumper);
66+
RttEstimator(const RttConfig& config, core::IArena& arena, dbgio::CsvDumper* dumper);
6767

6868
//! Check whether metrics are already available.
6969
bool has_metrics() const;

src/internal_modules/roc_sndio/io_pump.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "roc_sndio/io_pump.h"
1010
#include "roc_audio/sample_spec_to_str.h"
1111
#include "roc_core/log.h"
12+
#include "roc_core/thread.h"
1213
#include "roc_status/code_to_str.h"
1314

1415
namespace roc {
@@ -67,11 +68,18 @@ status::StatusCode IoPump::init_status() const {
6768
return init_status_;
6869
}
6970

70-
status::StatusCode IoPump::run() {
71+
status::StatusCode IoPump::run(const int realtime_priority) {
7172
roc_log(LogDebug, "io pump: starting main loop");
72-
7373
status::StatusCode code = status::NoStatus;
7474

75+
if (realtime_priority > 0 && !core::Thread::enable_realtime(realtime_priority)) {
76+
roc_log(LogError, "io pump: can't set realtime priority. May need to be root");
77+
code = status::StatusFailedRealtime;
78+
return code;
79+
} else {
80+
roc_log(LogDebug, "io pump: elevated realtime priority");
81+
}
82+
7583
for (;;) {
7684
// Transfer one frame from source to sink.
7785
if ((code = next_()) != status::StatusOK) {

src/internal_modules/roc_sndio/io_pump.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ class IoPump : public core::NonCopyable<> {
5959
//! @remarks
6060
//! Run until the stop() is called or, if oneshot mode is enabled,
6161
//! the source becomes inactive.
62-
ROC_ATTR_NODISCARD status::StatusCode run();
62+
ROC_ATTR_NODISCARD status::StatusCode run(const int realtime_priority = 0);
6363

6464
//! Stop the pump.
6565
//! @remarks

0 commit comments

Comments
 (0)