From 18a26fb38ff2422cb4839d76f5314bd09231c0e9 Mon Sep 17 00:00:00 2001 From: David Henningsson Date: Sun, 7 Feb 2010 13:59:21 +0100 Subject: rtkit: Add client-side testing of properties To complete the previous patch that implemented properties in rtkit, here's the client-side code that tests that the properties work, and make them more accessible for the casual C programmer. --- rtkit-test.c | 22 +++++++++-- rtkit.c | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ rtkit.h | 17 +++++++++ 3 files changed, 155 insertions(+), 3 deletions(-) diff --git a/rtkit-test.c b/rtkit-test.c index 2841b52..a6b79df 100644 --- a/rtkit-test.c +++ b/rtkit-test.c @@ -76,7 +76,8 @@ static void print_status(const char *t) { int main(int argc, char *argv[]) { DBusError error; DBusConnection *bus; - int r; + int r, max_realtime_priority, min_nice_level; + long long rttime_nsec_max; struct rlimit rlim; dbus_error_init(&error); @@ -86,6 +87,21 @@ int main(int argc, char *argv[]) { return 1; } + if ((max_realtime_priority = rtkit_get_max_realtime_priority(bus)) < 0) + fprintf(stderr, "Failed to retrieve max realtime priority: %s\n", strerror(-max_realtime_priority)); + else + printf("Max realtime priority is: %d\n", max_realtime_priority); + + if ((r = rtkit_get_min_nice_level(bus, &min_nice_level))) + fprintf(stderr, "Failed to retrieve min nice level: %s\n", strerror(-r)); + else + printf("Min nice level is: %d\n", min_nice_level); + + if ((rttime_nsec_max = rtkit_get_rttime_nsec_max(bus)) < 0) + fprintf(stderr, "Failed to retrieve rttime limit: %s\n", strerror(-rttime_nsec_max)); + else + printf("Rttime limit is: %lld ns\n", rttime_nsec_max); + memset(&rlim, 0, sizeof(rlim)); rlim.rlim_cur = rlim.rlim_max = 100000000ULL; /* 100ms */ if ((setrlimit(RLIMIT_RTTIME, &rlim) < 0)) @@ -96,14 +112,14 @@ int main(int argc, char *argv[]) { if ((r = rtkit_make_high_priority(bus, 0, -10)) < 0) fprintf(stderr, "Failed to become high priority: %s\n", strerror(-r)); else - printf("Sucessfully became high priority.\n"); + printf("Successfully became high priority.\n"); print_status("after high priority"); if ((r = rtkit_make_realtime(bus, 0, 10)) < 0) fprintf(stderr, "Failed to become realtime: %s\n", strerror(-r)); else - printf("Sucessfully became realtime.\n"); + printf("Successfully became realtime.\n"); print_status("after realtime"); diff --git a/rtkit.c b/rtkit.c index aecc4e3..77731d9 100644 --- a/rtkit.c +++ b/rtkit.c @@ -2,6 +2,7 @@ /*** Copyright 2009 Lennart Poettering + Copyright 2010 David Henningsson Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files @@ -56,6 +57,112 @@ static int translate_error(const char *name) { return -EIO; } +static long long rtkit_get_int_property(DBusConnection *connection, const char* propname, long long* propval) { + DBusMessage *m = NULL, *r = NULL; + DBusMessageIter iter, subiter; + dbus_int64_t i64; + dbus_int32_t i32; + DBusError error; + int current_type; + long long ret; + const char * interfacestr = "org.freedesktop.RealtimeKit1"; + + dbus_error_init(&error); + + if (!(m = dbus_message_new_method_call( + RTKIT_SERVICE_NAME, + RTKIT_OBJECT_PATH, + "org.freedesktop.DBus.Properties", + "Get"))) { + ret = -ENOMEM; + goto finish; + } + + if (!dbus_message_append_args( + m, + DBUS_TYPE_STRING, &interfacestr, + DBUS_TYPE_STRING, &propname, + DBUS_TYPE_INVALID)) { + ret = -ENOMEM; + goto finish; + } + + if (!(r = dbus_connection_send_with_reply_and_block(connection, m, -1, &error))) { + ret = translate_error(error.name); + goto finish; + } + + if (dbus_set_error_from_message(&error, r)) { + ret = translate_error(error.name); + goto finish; + } + + ret = -EBADMSG; + dbus_message_iter_init(r, &iter); + while ((current_type = dbus_message_iter_get_arg_type (&iter)) != DBUS_TYPE_INVALID) { + + if (current_type == DBUS_TYPE_VARIANT) { + dbus_message_iter_recurse(&iter, &subiter); + + while ((current_type = dbus_message_iter_get_arg_type (&subiter)) != DBUS_TYPE_INVALID) { + + if (current_type == DBUS_TYPE_INT32) { + dbus_message_iter_get_basic(&subiter, &i32); + *propval = i32; + ret = 0; + } + + if (current_type == DBUS_TYPE_INT64) { + dbus_message_iter_get_basic(&subiter, &i64); + *propval = i64; + ret = 0; + } + + dbus_message_iter_next (&subiter); + } + } + dbus_message_iter_next (&iter); + } + +finish: + + if (m) + dbus_message_unref(m); + + if (r) + dbus_message_unref(r); + + dbus_error_free(&error); + + return ret; +} + +int rtkit_get_max_realtime_priority(DBusConnection *connection) { + long long retval; + int err; + + err = rtkit_get_int_property(connection, "MaxRealtimePriority", &retval); + return err < 0 ? err : retval; +} + +int rtkit_get_min_nice_level(DBusConnection *connection, int* min_nice_level) { + long long retval; + int err; + + err = rtkit_get_int_property(connection, "MinNiceLevel", &retval); + if (err >= 0) + *min_nice_level = retval; + return err; +} + +long long rtkit_get_rttime_nsec_max(DBusConnection *connection) { + long long retval; + int err; + + err = rtkit_get_int_property(connection, "RTTimeNSecMax", &retval); + return err < 0 ? err : retval; +} + int rtkit_make_realtime(DBusConnection *connection, pid_t thread, int priority) { DBusMessage *m = NULL, *r = NULL; dbus_uint64_t u64; @@ -186,4 +293,16 @@ int rtkit_make_high_priority(DBusConnection *connection, pid_t thread, int nice_ 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_nsec_max(DBusConnection *connection) { + return -ENOTSUP; +} + #endif diff --git a/rtkit.h b/rtkit.h index 2081b4e..2b5b2c2 100644 --- a/rtkit.h +++ b/rtkit.h @@ -5,6 +5,7 @@ /*** Copyright 2009 Lennart Poettering + Copyright 2010 David Henningsson Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files @@ -55,6 +56,22 @@ int rtkit_make_realtime(DBusConnection *system_bus, pid_t thread, int priority); * on success.*/ int rtkit_make_high_priority(DBusConnection *system_bus, pid_t thread, int nice_level); +/* Return the maximum value of realtime priority available. Realtime requests + * above this value will fail. A negative value is an errno style error code. + */ +int rtkit_get_max_realtime_priority(DBusConnection *system_bus); + +/* Retreive the minimum value of nice level available. High prio requests + * below this value will fail. The returned value is a negative errno + * style error code, or 0 on success.*/ +int rtkit_get_min_nice_level(DBusConnection *system_bus, int* min_nice_level); + +/* Return the maximum value of RLIMIT_RTTIME to set before attempting a + * realtime request. A negative value is an errno style error code. + */ +long long rtkit_get_rttime_nsec_max(DBusConnection *system_bus); + + #ifdef __cplusplus } #endif -- cgit