Last active
January 10, 2022 18:25
-
-
Save zzag/16c0fda7aebf19b006294ff81426e2e2 to your computer and use it in GitHub Desktop.
RealtimeKit example (Qt)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "scheduler.h" | |
#include <QDBusConnection> | |
#include <QDBusMessage> | |
#include <QDBusVariant> | |
#include <mutex> | |
#include <sched.h> | |
#include <sys/resource.h> | |
#include <unistd.h> | |
#if defined(Q_OS_LINUX) | |
#include <sys/syscall.h> | |
#elif | |
#include <sys/thr.h> | |
#endif | |
static std::optional<rlim_t> rttimeUsecMax; | |
static std::once_flag onceFlag; | |
static std::optional<rlim_t> ensureRttimeUsecMax() | |
{ | |
std::call_once(onceFlag, []() { | |
QDBusMessage request = QDBusMessage::createMethodCall(QStringLiteral("org.freedesktop.RealtimeKit1"), | |
QStringLiteral("/org/freedesktop/RealtimeKit1"), | |
QStringLiteral("org.freedesktop.DBus.Properties"), | |
QStringLiteral("Get")); | |
request.setArguments({QStringLiteral("org.freedesktop.RealtimeKit1"), QStringLiteral("RTTimeUSecMax")}); | |
QDBusMessage reply = QDBusConnection::systemBus().call(request); | |
if (reply.type() == QDBusMessage::ReplyMessage) { | |
rttimeUsecMax = reply.arguments().constFirst().value<QDBusVariant>().variant().toUInt(); | |
} | |
}); | |
return rttimeUsecMax; | |
} | |
static quint64 currentThreadId() | |
{ | |
#if defined(Q_OS_LINUX) | |
return syscall(SYS_gettid); | |
#elif defined(Q_OS_FREEBSD) | |
long tid; | |
thr_self(&tid); | |
return tid; | |
#else | |
#error "currentThreadId() is not implemented for this platform" | |
#endif | |
} | |
void Scheduler::acquireRealTime() | |
{ | |
rlimit limits; | |
if (getrlimit(RLIMIT_RTTIME, &limits) == -1) { | |
return; | |
} | |
sched_param oldParams; | |
if (sched_getparam(0, &oldParams) == -1) { | |
return; | |
} | |
// Only clients with RLIMIT_RTTIME will get RT scheduling. | |
const std::optional<rlim_t> rttime = ensureRttimeUsecMax(); | |
if (!rttime) { | |
return; | |
} | |
limits.rlim_cur = std::min(limits.rlim_cur, *rttime); | |
limits.rlim_max = std::min(limits.rlim_max, *rttime); | |
if (setrlimit(RLIMIT_RTTIME, &limits) == -1) { | |
return; | |
} | |
if (sched_setscheduler(0, SCHED_OTHER | SCHED_RESET_ON_FORK, &oldParams) == -1) { | |
return; | |
} | |
const quint64 threadId = currentThreadId(); | |
const quint32 priority = sched_get_priority_min(SCHED_RR); | |
QDBusMessage message = QDBusMessage::createMethodCall(QStringLiteral("org.freedesktop.RealtimeKit1"), | |
QStringLiteral("/org/freedesktop/RealtimeKit1"), | |
QStringLiteral("org.freedesktop.RealtimeKit1"), | |
QStringLiteral("MakeThreadRealtime")); | |
message.setArguments({threadId, priority}); | |
const QDBusMessage reply = QDBusConnection::systemBus().call(message); | |
if (reply.type() == QDBusMessage::ErrorMessage) { | |
qDebug() << "Failed to acquire realtime scheduling on thread" << threadId; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
class Scheduler | |
{ | |
public: | |
static void acquireRealTime(); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment