From 5165b29b1945e1cff5e8c042bd371a5b2da9b492 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sun, 18 Apr 2021 00:34:36 -0700 Subject: Optionally use RTKit/D-Bus to set elevated priority If pthread_setschedparam fails or is unavailable. --- core/dbus_wrap.h | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 core/dbus_wrap.h (limited to 'core/dbus_wrap.h') diff --git a/core/dbus_wrap.h b/core/dbus_wrap.h new file mode 100644 index 00000000..61dbb971 --- /dev/null +++ b/core/dbus_wrap.h @@ -0,0 +1,75 @@ +#ifndef CORE_DBUS_WRAP_H +#define CORE_DBUS_WRAP_H + +#include + +#include + +#include "dynload.h" + + +#define DBUS_FUNCTIONS(MAGIC) \ +MAGIC(dbus_error_init) \ +MAGIC(dbus_error_free) \ +MAGIC(dbus_bus_get) \ +MAGIC(dbus_connection_set_exit_on_disconnect) \ +MAGIC(dbus_connection_unref) \ +MAGIC(dbus_connection_send_with_reply_and_block) \ +MAGIC(dbus_message_unref) \ +MAGIC(dbus_message_new_method_call) \ +MAGIC(dbus_message_append_args) \ +MAGIC(dbus_message_iter_init) \ +MAGIC(dbus_message_iter_next) \ +MAGIC(dbus_message_iter_recurse) \ +MAGIC(dbus_message_iter_get_arg_type) \ +MAGIC(dbus_message_iter_get_basic) \ +MAGIC(dbus_set_error_from_message) + +#ifdef HAVE_DYNLOAD + +#include + +extern void *dbus_handle; +#define DECL_FUNC(x) extern decltype(x) *p##x; +DBUS_FUNCTIONS(DECL_FUNC) +#undef DECL_FUNC + +void PrepareDBus(); + +inline auto HasDBus() +{ + static std::once_flag init_dbus{}; + std::call_once(init_dbus, PrepareDBus); + return dbus_handle; +} + +#else + +#define DECL_FUNC(x) constexpr auto p##x = &x; +DBUS_FUNCTIONS(DECL_FUNC) +#undef DECL_FUNC + +constexpr bool HasDBus() noexcept { return true; } +#endif /* HAVE_DYNLOAD */ + + +namespace dbus { + +struct Error { + Error() { (*pdbus_error_init)(&mError); } + ~Error() { (*pdbus_error_free)(&mError); } + DBusError* operator->() { return &mError; } + DBusError &get() { return mError; } +private: + DBusError mError{}; +}; + +struct ConnectionDeleter { + void operator()(DBusConnection *c) { (*pdbus_connection_unref)(c); } +}; +using ConnectionPtr = std::unique_ptr; + +} // namespace dbus + + +#endif /* CORE_DBUS_WRAP_H */ -- cgit v1.2.3 From 4920167fa0c90b276459107c18a67cf64bd11c4d Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Tue, 18 Jan 2022 11:45:08 -0800 Subject: Avoid passing a function pointer to std::call_once --- core/dbus_wrap.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'core/dbus_wrap.h') diff --git a/core/dbus_wrap.h b/core/dbus_wrap.h index 61dbb971..298ce09a 100644 --- a/core/dbus_wrap.h +++ b/core/dbus_wrap.h @@ -39,7 +39,7 @@ void PrepareDBus(); inline auto HasDBus() { static std::once_flag init_dbus{}; - std::call_once(init_dbus, PrepareDBus); + std::call_once(init_dbus, []{ PrepareDBus(); }); return dbus_handle; } -- cgit v1.2.3 From 388f10319b91b043c9a17833eb437bde33e3fa2e Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Tue, 18 Jan 2022 15:55:51 -0800 Subject: Handle _gettid on FreeBSD And simplify handling D-Bus/RTKit interfaces --- core/dbus_wrap.cpp | 2 +- core/dbus_wrap.h | 36 ++++++++++++------ core/helpers.cpp | 4 +- core/rtkit.cpp | 108 +++++++++++++++++++++++++---------------------------- core/rtkit.h | 9 ----- 5 files changed, 77 insertions(+), 82 deletions(-) (limited to 'core/dbus_wrap.h') diff --git a/core/dbus_wrap.cpp b/core/dbus_wrap.cpp index 506dd815..7f221706 100644 --- a/core/dbus_wrap.cpp +++ b/core/dbus_wrap.cpp @@ -12,7 +12,7 @@ void *dbus_handle{nullptr}; -#define DECL_FUNC(x) decltype(x) *p##x{}; +#define DECL_FUNC(x) decltype(p##x) p##x{}; DBUS_FUNCTIONS(DECL_FUNC) #undef DECL_FUNC diff --git a/core/dbus_wrap.h b/core/dbus_wrap.h index 298ce09a..09eaacf9 100644 --- a/core/dbus_wrap.h +++ b/core/dbus_wrap.h @@ -7,6 +7,9 @@ #include "dynload.h" +#ifdef HAVE_DYNLOAD + +#include #define DBUS_FUNCTIONS(MAGIC) \ MAGIC(dbus_error_init) \ @@ -25,15 +28,29 @@ MAGIC(dbus_message_iter_get_arg_type) \ MAGIC(dbus_message_iter_get_basic) \ MAGIC(dbus_set_error_from_message) -#ifdef HAVE_DYNLOAD - -#include - extern void *dbus_handle; #define DECL_FUNC(x) extern decltype(x) *p##x; DBUS_FUNCTIONS(DECL_FUNC) #undef DECL_FUNC +#ifndef IN_IDE_PARSER +#define dbus_error_init (*pdbus_error_init) +#define dbus_error_free (*pdbus_error_free) +#define dbus_bus_get (*pdbus_bus_get) +#define dbus_connection_set_exit_on_disconnect (*pdbus_connection_set_exit_on_disconnect) +#define dbus_connection_unref (*pdbus_connection_unref) +#define dbus_connection_send_with_reply_and_block (*pdbus_connection_send_with_reply_and_block) +#define dbus_message_unref (*pdbus_message_unref) +#define dbus_message_new_method_call (*pdbus_message_new_method_call) +#define dbus_message_append_args (*pdbus_message_append_args) +#define dbus_message_iter_init (*pdbus_message_iter_init) +#define dbus_message_iter_next (*pdbus_message_iter_next) +#define dbus_message_iter_recurse (*pdbus_message_iter_recurse) +#define dbus_message_iter_get_arg_type (*pdbus_message_iter_get_arg_type) +#define dbus_message_iter_get_basic (*pdbus_message_iter_get_basic) +#define dbus_set_error_from_message (*pdbus_set_error_from_message) +#endif + void PrepareDBus(); inline auto HasDBus() @@ -45,10 +62,6 @@ inline auto HasDBus() #else -#define DECL_FUNC(x) constexpr auto p##x = &x; -DBUS_FUNCTIONS(DECL_FUNC) -#undef DECL_FUNC - constexpr bool HasDBus() noexcept { return true; } #endif /* HAVE_DYNLOAD */ @@ -56,8 +69,8 @@ constexpr bool HasDBus() noexcept { return true; } namespace dbus { struct Error { - Error() { (*pdbus_error_init)(&mError); } - ~Error() { (*pdbus_error_free)(&mError); } + Error() { dbus_error_init(&mError); } + ~Error() { dbus_error_free(&mError); } DBusError* operator->() { return &mError; } DBusError &get() { return mError; } private: @@ -65,11 +78,10 @@ private: }; struct ConnectionDeleter { - void operator()(DBusConnection *c) { (*pdbus_connection_unref)(c); } + void operator()(DBusConnection *c) { dbus_connection_unref(c); } }; using ConnectionPtr = std::unique_ptr; } // namespace dbus - #endif /* CORE_DBUS_WRAP_H */ diff --git a/core/helpers.cpp b/core/helpers.cpp index 3cc7bf8f..754e66c1 100644 --- a/core/helpers.cpp +++ b/core/helpers.cpp @@ -447,7 +447,7 @@ bool SetRTPriorityRTKit(int prio) return false; } dbus::Error error; - dbus::ConnectionPtr conn{(*pdbus_bus_get)(DBUS_BUS_SYSTEM, &error.get())}; + dbus::ConnectionPtr conn{dbus_bus_get(DBUS_BUS_SYSTEM, &error.get())}; if(!conn) { WARN("D-Bus connection failed with %s: %s\n", error->name, error->message); @@ -455,7 +455,7 @@ bool SetRTPriorityRTKit(int prio) } /* Don't stupidly exit if the connection dies while doing this. */ - (*pdbus_connection_set_exit_on_disconnect)(conn.get(), false); + dbus_connection_set_exit_on_disconnect(conn.get(), false); auto limit_rttime = [](DBusConnection *c) -> int { diff --git a/core/rtkit.cpp b/core/rtkit.cpp index 8b489e71..9210220e 100644 --- a/core/rtkit.cpp +++ b/core/rtkit.cpp @@ -32,8 +32,6 @@ #include -#ifdef __linux__ - #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif @@ -46,24 +44,37 @@ namespace dbus { - constexpr int TypeString{'s'}; - constexpr int TypeVariant{'v'}; - constexpr int TypeInt32{'i'}; - constexpr int TypeUInt32{'u'}; - constexpr int TypeInt64{'x'}; - constexpr int TypeUInt64{'t'}; - constexpr int TypeInvalid{'\0'}; - - struct MessageDeleter { - void operator()(DBusMessage *m) { (*pdbus_message_unref)(m); } - }; - using MessagePtr = std::unique_ptr; + +constexpr int TypeString{'s'}; +constexpr int TypeVariant{'v'}; +constexpr int TypeInt32{'i'}; +constexpr int TypeUInt32{'u'}; +constexpr int TypeInt64{'x'}; +constexpr int TypeUInt64{'t'}; +constexpr int TypeInvalid{'\0'}; + +struct MessageDeleter { + void operator()(DBusMessage *m) { dbus_message_unref(m); } +}; +using MessagePtr = std::unique_ptr; + } // namespace dbus namespace { inline pid_t _gettid() -{ return static_cast(syscall(SYS_gettid)); } +{ +#ifdef __linux__ + return static_cast(syscall(SYS_gettid)); +#elif defined(__FreeBSD__) + long pid{}; + thr_self(&pid); + return static_cast(pid); +#else +#warning gettid not available + return 0; +#endif +} int translate_error(const char *name) { @@ -80,41 +91,41 @@ int translate_error(const char *name) int rtkit_get_int_property(DBusConnection *connection, const char *propname, long long *propval) { - dbus::MessagePtr m{(*pdbus_message_new_method_call)(RTKIT_SERVICE_NAME, RTKIT_OBJECT_PATH, + dbus::MessagePtr m{dbus_message_new_method_call(RTKIT_SERVICE_NAME, RTKIT_OBJECT_PATH, "org.freedesktop.DBus.Properties", "Get")}; if(!m) return -ENOMEM; const char *interfacestr = RTKIT_SERVICE_NAME; - auto ready = (*pdbus_message_append_args)(m.get(), + auto ready = dbus_message_append_args(m.get(), dbus::TypeString, &interfacestr, dbus::TypeString, &propname, dbus::TypeInvalid); if(!ready) return -ENOMEM; dbus::Error error; - dbus::MessagePtr r{(*pdbus_connection_send_with_reply_and_block)(connection, m.get(), -1, + dbus::MessagePtr r{dbus_connection_send_with_reply_and_block(connection, m.get(), -1, &error.get())}; if(!r) return translate_error(error->name); - if((*pdbus_set_error_from_message)(&error.get(), r.get())) + if(dbus_set_error_from_message(&error.get(), r.get())) return translate_error(error->name); int ret{-EBADMSG}; DBusMessageIter iter{}; - (*pdbus_message_iter_init)(r.get(), &iter); - while(int curtype{(*pdbus_message_iter_get_arg_type)(&iter)}) + dbus_message_iter_init(r.get(), &iter); + while(int curtype{dbus_message_iter_get_arg_type(&iter)}) { if(curtype == dbus::TypeVariant) { DBusMessageIter subiter{}; - (*pdbus_message_iter_recurse)(&iter, &subiter); + dbus_message_iter_recurse(&iter, &subiter); - while((curtype=(*pdbus_message_iter_get_arg_type)(&subiter)) != dbus::TypeInvalid) + while((curtype=dbus_message_iter_get_arg_type(&subiter)) != dbus::TypeInvalid) { if(curtype == dbus::TypeInt32) { dbus_int32_t i32{}; - (*pdbus_message_iter_get_basic)(&subiter, &i32); + dbus_message_iter_get_basic(&subiter, &i32); *propval = i32; ret = 0; } @@ -122,15 +133,15 @@ int rtkit_get_int_property(DBusConnection *connection, const char *propname, lon if(curtype == dbus::TypeInt64) { dbus_int64_t i64{}; - (*pdbus_message_iter_get_basic)(&subiter, &i64); + dbus_message_iter_get_basic(&subiter, &i64); *propval = i64; ret = 0; } - (*pdbus_message_iter_next)(&subiter); + dbus_message_iter_next(&subiter); } } - (*pdbus_message_iter_next)(&iter); + dbus_message_iter_next(&iter); } return ret; @@ -138,7 +149,6 @@ int rtkit_get_int_property(DBusConnection *connection, const char *propname, lon } // namespace -extern "C" { int rtkit_get_max_realtime_priority(DBusConnection *connection) { long long retval{}; @@ -165,25 +175,27 @@ int rtkit_make_realtime(DBusConnection *connection, pid_t thread, int priority) { if(thread == 0) thread = _gettid(); + if(thread == 0) + return -ENOTSUP; - dbus::MessagePtr m{(*pdbus_message_new_method_call)(RTKIT_SERVICE_NAME, RTKIT_OBJECT_PATH, + dbus::MessagePtr m{dbus_message_new_method_call(RTKIT_SERVICE_NAME, RTKIT_OBJECT_PATH, "org.freedesktop.RealtimeKit1", "MakeThreadRealtime")}; if(!m) return -ENOMEM; auto u64 = static_cast(thread); auto u32 = static_cast(priority); - auto ready = (*pdbus_message_append_args)(m.get(), + auto ready = dbus_message_append_args(m.get(), dbus::TypeUInt64, &u64, dbus::TypeUInt32, &u32, dbus::TypeInvalid); if(!ready) return -ENOMEM; dbus::Error error; - dbus::MessagePtr r{(*pdbus_connection_send_with_reply_and_block)(connection, m.get(), -1, + dbus::MessagePtr r{dbus_connection_send_with_reply_and_block(connection, m.get(), -1, &error.get())}; if(!r) return translate_error(error->name); - if((*pdbus_set_error_from_message)(&error.get(), r.get())) + if(dbus_set_error_from_message(&error.get(), r.get())) return translate_error(error->name); return 0; @@ -193,48 +205,28 @@ int rtkit_make_high_priority(DBusConnection *connection, pid_t thread, int nice_ { if(thread == 0) thread = _gettid(); + if(thread == 0) + return -ENOTSUP; - dbus::MessagePtr m{(*pdbus_message_new_method_call)(RTKIT_SERVICE_NAME, RTKIT_OBJECT_PATH, + dbus::MessagePtr m{dbus_message_new_method_call(RTKIT_SERVICE_NAME, RTKIT_OBJECT_PATH, "org.freedesktop.RealtimeKit1", "MakeThreadHighPriority")}; if(!m) return -ENOMEM; auto u64 = static_cast(thread); auto s32 = static_cast(nice_level); - auto ready = (*pdbus_message_append_args)(m.get(), + auto ready = dbus_message_append_args(m.get(), dbus::TypeUInt64, &u64, dbus::TypeInt32, &s32, dbus::TypeInvalid); if(!ready) return -ENOMEM; dbus::Error error; - dbus::MessagePtr r{(*pdbus_connection_send_with_reply_and_block)(connection, m.get(), -1, + dbus::MessagePtr r{dbus_connection_send_with_reply_and_block(connection, m.get(), -1, &error.get())}; if(!r) return translate_error(error->name); - if((*pdbus_set_error_from_message)(&error.get(), r.get())) + if(dbus_set_error_from_message(&error.get(), r.get())) return translate_error(error->name); return 0; } -} // extern "C" - -#else - -extern "C" { -int rtkit_make_realtime(DBusConnection *connection, pid_t thread, int priority) -{ return -ENOTSUP; } - -int rtkit_make_high_priority(DBusConnection *connection, pid_t thread, int nice_level) -{ return -ENOTSUP; } - -int rtkit_get_max_realtime_priority(DBusConnection *connection) -{ return -ENOTSUP; } - -int rtkit_get_min_nice_level(DBusConnection *connection, int *min_nice_level) -{ return -ENOTSUP; } - -long long rtkit_get_rttime_usec_max(DBusConnection *connection) -{ return -ENOTSUP; } -} // extern "C" - -#endif diff --git a/core/rtkit.h b/core/rtkit.h index 96e81d4a..d4994e27 100644 --- a/core/rtkit.h +++ b/core/rtkit.h @@ -32,10 +32,6 @@ #include "dbus_wrap.h" -#ifdef __cplusplus -extern "C" { -#endif - /* This is the reference implementation for a client for * RealtimeKit. You don't have to use this, but if do, just copy these * sources into your repository */ @@ -72,9 +68,4 @@ int rtkit_get_min_nice_level(DBusConnection *system_bus, int *min_nice_level); */ long long rtkit_get_rttime_usec_max(DBusConnection *system_bus); - -#ifdef __cplusplus -} -#endif - #endif -- cgit v1.2.3