[rfc] server: Use rtkit to set realtime priority, try 3
Maarten Lankhorst
m.b.lankhorst at gmail.com
Wed May 5 08:44:44 CDT 2010
---
Hi gus,
Thought I'd try again :) This is a cleaned up version. The license on
rtkit.c will still have to change, but since it's so heavily modified
to get it into a shape for wine, that only a few lines in
make_realtime are still original, so it would be easy to rewrite the
remainder of that function to get it fully lgplv2.1.
See also https://tango.0pointer.de/pipermail/pulseaudio-discuss/2010-May/007058.html
Are there any issues left, or shall I submit this one to wine-patches
after the patch linked above is merged into rtkit.git ?
Cheers,
Maarten
-------------- next part --------------
From 9e494e4a1587cc07752897a787f626b99f711756 Mon Sep 17 00:00:00 2001
From: Maarten Lankhorst <m.b.lankhorst at gmail.com>
Date: Fri, 23 Apr 2010 23:21:37 +0200
Subject: [PATCH 03/10] server: Use rtkit to set realtime priority, try 3
---
configure | 117 ++++++++++++++++++++++++--------
configure.ac | 41 +++++++++---
include/config.h.in | 3 +
libs/wine/loader.c | 27 +++++++
server/Makefile.in | 2 +
server/rtkit.c | 187 +++++++++++++++++++++++++++++++++++++++++++++++++++
server/thread.c | 16 +++++
7 files changed, 354 insertions(+), 39 deletions(-)
create mode 100644 server/rtkit.c
diff --git a/configure b/configure
index 52410fb..d732d9d 100755
--- a/configure
+++ b/configure
@@ -634,6 +634,7 @@ gphoto2_devel
SANEINCL
sane_devel
GNUTLSINCL
+DBUSINCL
HALINCL
XSLTINCL
XML2INCL
@@ -772,6 +773,7 @@ with_cms
with_coreaudio
with_cups
with_curses
+with_dbus
with_esd
with_fontconfig
with_freetype
@@ -1459,6 +1461,7 @@ Optional Packages:
--without-coreaudio do not use the CoreAudio sound support
--without-cups do not use CUPS
--without-curses do not use (n)curses
+ --without-dbus do not use dbus (will also disable HAL support)
--without-esd do not use the EsounD sound support
--without-fontconfig do not use fontconfig
--without-freetype do not use the FreeType library
@@ -2539,6 +2542,12 @@ if test "${with_curses+set}" = set; then :
fi
+# Check whether --with-dbus was given.
+if test "${with_dbus+set}" = set; then :
+ withval=$with_dbus;
+fi
+
+
# Check whether --with-esd was given.
if test "${with_esd+set}" = set; then :
withval=$with_esd;
@@ -9260,39 +9269,40 @@ fi
HALINCL=""
-if test "x$with_hal" != "xno"
+DBUSINCL=""
+
+
+if test "x$with_dbus" != "xno"
then
ac_save_CPPFLAGS="$CPPFLAGS"
if test "$PKG_CONFIG" != "false"
then
- ac_hal_libs="`$PKG_CONFIG --libs hal 2>/dev/null`"
- ac_hal_cflags="`$PKG_CONFIG --cflags hal 2>/dev/null`"
- CPPFLAGS="$CPPFLAGS $ac_hal_cflags"
+ ac_dbus_libs="`$PKG_CONFIG --libs dbus-1 2>/dev/null`"
+ ac_dbus_cflags="`$PKG_CONFIG --cflags dbus-1 2>/dev/null`"
+ CPPFLAGS="$CPPFLAGS $ac_dbus_cflags"
fi
- for ac_header in dbus/dbus.h hal/libhal.h
+ for ac_header in dbus/dbus.h
do :
- as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
-ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
-eval as_val=\$$as_ac_Header
- if test "x$as_val" = x""yes; then :
+ ac_fn_c_check_header_mongrel "$LINENO" "dbus/dbus.h" "ac_cv_header_dbus_dbus_h" "$ac_includes_default"
+if test "x$ac_cv_header_dbus_dbus_h" = x""yes; then :
cat >>confdefs.h <<_ACEOF
-#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+#define HAVE_DBUS_DBUS_H 1
_ACEOF
fi
done
- if test "$ac_cv_header_dbus_dbus_h" = "yes" -a "$ac_cv_header_hal_libhal_h" = "yes"
+ if test "$ac_cv_header_dbus_dbus_h" = "yes"
then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dbus_connection_close in -ldbus-1" >&5
-$as_echo_n "checking for dbus_connection_close in -ldbus-1... " >&6; }
-if test "${ac_cv_lib_dbus_1_dbus_connection_close+set}" = set; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -ldbus-1" >&5
+$as_echo_n "checking for -ldbus-1... " >&6; }
+if test "${ac_cv_lib_soname_dbus_1+set}" = set; then :
$as_echo_n "(cached) " >&6
else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-ldbus-1 $ac_hal_libs $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ ac_check_soname_save_LIBS=$LIBS
+LIBS="-ldbus-1 $ac_dbus_libs $LIBS"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
/* Override any GCC internal prototype to avoid an error.
@@ -9311,18 +9321,67 @@ return dbus_connection_close ();
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_lib_dbus_1_dbus_connection_close=yes
-else
- ac_cv_lib_dbus_1_dbus_connection_close=no
+ case "$LIBEXT" in
+ dll) ac_cv_lib_soname_dbus_1=`$ac_cv_path_LDD conftest.exe | grep "dbus-1" | sed -e "s/dll.*/dll/"';2,$d'` ;;
+ dylib) ac_cv_lib_soname_dbus_1=`otool -L conftest$ac_exeext | grep "libdbus-1\\.[0-9A-Za-z.]*dylib" | sed -e "s/^.*\/\(libdbus-1\.[0-9A-Za-z.]*dylib\).*$/\1/"';2,$d'` ;;
+ *) ac_cv_lib_soname_dbus_1=`$ac_cv_path_LDD conftest$ac_exeext | grep "libdbus-1\\.$LIBEXT" | sed -e "s/^.*\(libdbus-1\.$LIBEXT[^ ]*\).*$/\1/"';2,$d'` ;;
+ esac
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
+ LIBS=$ac_check_soname_save_LIBS
+fi
+if test "x$ac_cv_lib_soname_dbus_1" = "x"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
+$as_echo "not found" >&6; }
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_soname_dbus_1" >&5
+$as_echo "$ac_cv_lib_soname_dbus_1" >&6; }
+
+cat >>confdefs.h <<_ACEOF
+#define SONAME_LIBDBUS_1 "$ac_cv_lib_soname_dbus_1"
+_ACEOF
+
+ DBUSINCL="$ac_dbus_cflags"
+fi
+ fi
+
+ CPPFLAGS="$ac_save_CPPFLAGS"
fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dbus_1_dbus_connection_close" >&5
-$as_echo "$ac_cv_lib_dbus_1_dbus_connection_close" >&6; }
-if test "x$ac_cv_lib_dbus_1_dbus_connection_close" = x""yes; then :
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -lhal" >&5
+if test "x$ac_cv_lib_soname_dbus_1" = "x" -a "x$ac_cv_header_DiskArbitration_DiskArbitration_h" != "xyes"; then :
+ case "x$with_dbus" in
+ x) as_fn_append wine_notices "|libdbus and libhal ${notice_platform}development files not found, HAL and rtkit support disabled" ;;
+ xno) ;;
+ *) as_fn_error "libdbus and libhal ${notice_platform}development files not found, HAL and rtkit support disabled
+This is an error since --with-dbus was requested." "$LINENO" 5 ;;
+esac
+fi
+
+if test "x$with_hal" != "xno" -a "x$ac_cv_lib_soname_dbus_1" != "x"
+then
+ ac_save_CPPFLAGS="$CPPFLAGS"
+ if test "$PKG_CONFIG" != "false"
+ then
+ ac_hal_libs="`$PKG_CONFIG --libs hal 2>/dev/null`"
+ ac_hal_cflags="`$PKG_CONFIG --cflags hal 2>/dev/null`"
+ CPPFLAGS="$CPPFLAGS $ac_hal_cflags"
+ fi
+ for ac_header in hal/libhal.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "hal/libhal.h" "ac_cv_header_hal_libhal_h" "$ac_includes_default"
+if test "x$ac_cv_header_hal_libhal_h" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_HAL_LIBHAL_H 1
+_ACEOF
+
+fi
+
+done
+
+ if test "$ac_cv_header_hal_libhal_h" = "yes"
+ then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -lhal" >&5
$as_echo_n "checking for -lhal... " >&6; }
if test "${ac_cv_lib_soname_hal+set}" = set; then :
$as_echo_n "(cached) " >&6
@@ -9372,16 +9431,14 @@ _ACEOF
HALINCL="$ac_hal_cflags"
fi
-fi
-
fi
CPPFLAGS="$ac_save_CPPFLAGS"
fi
-if test "x$ac_cv_lib_soname_hal" = "x" -a "x$ac_cv_header_DiskArbitration_DiskArbitration_h" != "xyes"; then :
+if test "x$ac_cv_lib_soname_hal" = "x" -a "x$ac_cv_header_DiskArbitration_DiskArbitration_h" != "xyes" -a "x$ac_cv_lib_soname_dbus_1" != "x"; then :
case "x$with_hal" in
- x) as_fn_append wine_notices "|libhal/libdbus ${notice_platform}development files not found, no dynamic device support." ;;
+ x) as_fn_append wine_notices "|libhal ${notice_platform}development files not found, no dynamic device support." ;;
xno) ;;
- *) as_fn_error "libhal/libdbus ${notice_platform}development files not found, no dynamic device support.
+ *) as_fn_error "libhal ${notice_platform}development files not found, no dynamic device support.
This is an error since --with-hal was requested." "$LINENO" 5 ;;
esac
fi
diff --git a/configure.ac b/configure.ac
index 227dee5..179bcc3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -36,6 +36,7 @@ AC_ARG_WITH(coreaudio, AS_HELP_STRING([--without-coreaudio],[do not use the Core
AC_ARG_WITH(cups, AS_HELP_STRING([--without-cups],[do not use CUPS]))
AC_ARG_WITH(curses, AS_HELP_STRING([--without-curses],[do not use (n)curses]),
[if test "x$withval" = "xno"; then ac_cv_header_ncurses_h=no; ac_cv_header_curses_h=no; fi])
+AC_ARG_WITH(dbus, AS_HELP_STRING([--without-dbus],[do not use dbus (will also disable HAL support)]))
AC_ARG_WITH(esd, AS_HELP_STRING([--without-esd],[do not use the EsounD sound support]))
AC_ARG_WITH(fontconfig,AS_HELP_STRING([--without-fontconfig],[do not use fontconfig]),
[if test "x$withval" = "xno"; then ac_cv_header_fontconfig_fontconfig_h=no; fi])
@@ -1113,9 +1114,32 @@ fi
WINE_WARNING_WITH(xslt,[test "x$ac_cv_lib_soname_xslt" = "x"],
[libxslt ${notice_platform}development files not found, xslt won't be supported.])
-dnl **** Check for libhal ****
+dnl **** Check for libdbus-1 and libhal ****
AC_SUBST(HALINCL,"")
-if test "x$with_hal" != "xno"
+AC_SUBST(DBUSINCL,"")
+
+if test "x$with_dbus" != "xno"
+then
+ ac_save_CPPFLAGS="$CPPFLAGS"
+ if test "$PKG_CONFIG" != "false"
+ then
+ ac_dbus_libs="`$PKG_CONFIG --libs dbus-1 2>/dev/null`"
+ ac_dbus_cflags="`$PKG_CONFIG --cflags dbus-1 2>/dev/null`"
+ CPPFLAGS="$CPPFLAGS $ac_dbus_cflags"
+ fi
+ AC_CHECK_HEADERS([dbus/dbus.h])
+ if test "$ac_cv_header_dbus_dbus_h" = "yes"
+ then
+ WINE_CHECK_SONAME(dbus-1, dbus_connection_close,
+ [DBUSINCL="$ac_dbus_cflags"],,[$ac_dbus_libs])
+ fi
+
+ CPPFLAGS="$ac_save_CPPFLAGS"
+fi
+WINE_NOTICE_WITH(dbus,[test "x$ac_cv_lib_soname_dbus_1" = "x" -a "x$ac_cv_header_DiskArbitration_DiskArbitration_h" != "xyes"],
+ [libdbus and libhal ${notice_platform}development files not found, HAL and rtkit support disabled])
+
+if test "x$with_hal" != "xno" -a "x$ac_cv_lib_soname_dbus_1" != "x"
then
ac_save_CPPFLAGS="$CPPFLAGS"
if test "$PKG_CONFIG" != "false"
@@ -1124,17 +1148,16 @@ then
ac_hal_cflags="`$PKG_CONFIG --cflags hal 2>/dev/null`"
CPPFLAGS="$CPPFLAGS $ac_hal_cflags"
fi
- AC_CHECK_HEADERS([dbus/dbus.h hal/libhal.h])
- if test "$ac_cv_header_dbus_dbus_h" = "yes" -a "$ac_cv_header_hal_libhal_h" = "yes"
+ AC_CHECK_HEADERS([hal/libhal.h])
+ if test "$ac_cv_header_hal_libhal_h" = "yes"
then
- AC_CHECK_LIB(dbus-1, dbus_connection_close,
- [WINE_CHECK_SONAME(hal, libhal_ctx_new,
- [HALINCL="$ac_hal_cflags"],,[$ac_hal_libs])],,[$ac_hal_libs])
+ WINE_CHECK_SONAME(hal, libhal_ctx_new,
+ [HALINCL="$ac_hal_cflags"],,[$ac_hal_libs])
fi
CPPFLAGS="$ac_save_CPPFLAGS"
fi
-WINE_NOTICE_WITH(hal,[test "x$ac_cv_lib_soname_hal" = "x" -a "x$ac_cv_header_DiskArbitration_DiskArbitration_h" != "xyes"],
- [libhal/libdbus ${notice_platform}development files not found, no dynamic device support.])
+WINE_NOTICE_WITH(hal,[test "x$ac_cv_lib_soname_hal" = "x" -a "x$ac_cv_header_DiskArbitration_DiskArbitration_h" != "xyes" -a "x$ac_cv_lib_soname_dbus_1" != "x"],
+ [libhal ${notice_platform}development files not found, no dynamic device support.])
dnl **** Check for libgnutls ****
if test "x$with_gnutls" != "xno"
diff --git a/include/config.h.in b/include/config.h.in
index 0faf127..60e12a4 100644
--- a/include/config.h.in
+++ b/include/config.h.in
@@ -1181,6 +1181,9 @@
/* Define to the soname of the libcurses library. */
#undef SONAME_LIBCURSES
+/* Define to the soname of the libdbus-1 library. */
+#undef SONAME_LIBDBUS_1
+
/* Define to the soname of the libfontconfig library. */
#undef SONAME_LIBFONTCONFIG
diff --git a/libs/wine/loader.c b/libs/wine/loader.c
index 37c603e..69a9292 100644
--- a/libs/wine/loader.c
+++ b/libs/wine/loader.c
@@ -669,6 +669,32 @@ static void set_max_limit( int limit )
/***********************************************************************
+ * set_rttime_limit
+ *
+ * set a limit on the cpu time used
+ */
+static void set_rttime_limit(void)
+{
+#if defined(HAVE_SETRLIMIT) && defined(__linux__)
+#ifndef RLIMIT_RTTIME
+#define RLIMIT_RTTIME 15
+#endif
+ struct rlimit rlimit;
+
+ if (!getrlimit( RLIMIT_RTTIME, &rlimit ))
+ {
+ /* 50 ms realtime, then 10 ms to undo realtime */
+ if (rlimit.rlim_max > 60000000ULL)
+ rlimit.rlim_max = 60000000ULL;
+ rlimit.rlim_cur = rlimit.rlim_max - 10000000ULL;
+
+ setrlimit( RLIMIT_RTTIME, &rlimit );
+ }
+#endif
+}
+
+
+/***********************************************************************
* wine_init
*
* Main Wine initialisation.
@@ -687,6 +713,7 @@ void wine_init( int argc, char *argv[], char *error, int error_size )
#ifdef RLIMIT_AS
set_max_limit( RLIMIT_AS );
#endif
+ set_rttime_limit();
wine_init_argv0_path( argv[0] );
build_dll_path();
diff --git a/server/Makefile.in b/server/Makefile.in
index 7a67707..1197066 100644
--- a/server/Makefile.in
+++ b/server/Makefile.in
@@ -5,6 +5,7 @@ SRCDIR = @srcdir@
VPATH = @srcdir@
MODULE = none
EXTRALIBS = @LIBPOLL@
+MODCFLAGS = @DBUSINCL@
C_SRCS = \
async.c \
@@ -36,6 +37,7 @@ C_SRCS = \
region.c \
registry.c \
request.c \
+ rtkit.c \
semaphore.c \
serial.c \
signal.c \
diff --git a/server/rtkit.c b/server/rtkit.c
new file mode 100644
index 0000000..890c8a6
--- /dev/null
+++ b/server/rtkit.c
@@ -0,0 +1,187 @@
+/*-*- Mode: C; c-basic-offset: 8 -*-*/
+
+/***
+ Copyright 2009 Lennart Poettering
+
+ Permission is hereby granted, free of charge, to any person
+ obtaining a copy of this software and associated documentation files
+ (the "Software"), to deal in the Software without restriction,
+ including without limitation the rights to use, copy, modify, merge,
+ publish, distribute, sublicense, and/or sell copies of the Software,
+ and to permit persons to whom the Software is furnished to do so,
+ subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+***/
+
+#include "config.h"
+#include "wine/port.h"
+#include "wine/library.h"
+
+#include <errno.h>
+#include <sys/types.h>
+#ifdef HAVE_SYS_SCHED_H
+#include <sys/sched.h>
+#endif
+#include <sys/resource.h>
+
+#if defined(HAVE_SETRLIMIT) && defined(__linux__) && defined(SONAME_LIBDBUS_1)
+
+#include <sched.h>
+#include <string.h>
+#include <unistd.h>
+#include <dbus/dbus.h>
+#include <sys/syscall.h>
+
+#ifndef RLIMIT_RTTIME
+#define RLIMIT_RTTIME 15
+#endif
+
+#define RTKIT_SERVICE_NAME "org.freedesktop.RealtimeKit1"
+#define RTKIT_OBJECT_PATH "/org/freedesktop/RealtimeKit1"
+
+#define FUNCPTR(fn) static typeof(fn) *p ##fn
+
+FUNCPTR(dbus_error_init);
+FUNCPTR(dbus_error_free);
+FUNCPTR(dbus_bus_get);
+FUNCPTR(dbus_message_new_method_call);
+FUNCPTR(dbus_message_append_args);
+FUNCPTR(dbus_connection_send_with_reply_and_block);
+FUNCPTR(dbus_message_unref);
+FUNCPTR(dbus_set_error_from_message);
+#undef FUNCPTR
+
+static int translate_error(const char *name) {
+ if (strcmp(name, DBUS_ERROR_NO_MEMORY) == 0)
+ return -ENOMEM;
+ if (strcmp(name, DBUS_ERROR_SERVICE_UNKNOWN) == 0 ||
+ strcmp(name, DBUS_ERROR_NAME_HAS_NO_OWNER) == 0)
+ return -ENOENT;
+ if (strcmp(name, DBUS_ERROR_ACCESS_DENIED) == 0 ||
+ strcmp(name, DBUS_ERROR_AUTH_FAILED) == 0)
+ return -EACCES;
+
+ return -EIO;
+}
+
+static void init_dbus(void) {
+#define FUNCPTR(fn) p ##fn = wine_dlsym(libdbus, #fn, NULL, 0);
+ char error[512];
+ void *libdbus = wine_dlopen(SONAME_LIBDBUS_1, RTLD_NOW, error, sizeof(error));
+ FUNCPTR(dbus_error_init);
+ FUNCPTR(dbus_error_free);
+ FUNCPTR(dbus_bus_get);
+ FUNCPTR(dbus_message_new_method_call);
+ FUNCPTR(dbus_message_append_args);
+ FUNCPTR(dbus_connection_send_with_reply_and_block);
+ FUNCPTR(dbus_message_unref);
+ FUNCPTR(dbus_set_error_from_message);
+#undef FUNCPTR
+}
+
+static DBusConnection *get_dbus(void) {
+ static DBusConnection *bus;
+ DBusError error;
+
+ if (bus)
+ return bus;
+ init_dbus();
+ pdbus_error_init(&error);
+
+ bus = pdbus_bus_get(DBUS_BUS_SYSTEM, &error);
+ return bus;
+}
+
+int rtkit_make_realtime(pid_t process, pid_t thread, int priority) {
+ DBusConnection *bus = get_dbus();
+ DBusMessage *m = NULL, *r = NULL;
+ dbus_uint64_t pid, tid;
+ dbus_uint32_t u32;
+ DBusError error;
+ int ret;
+
+ if (!bus)
+ return -ENOTSUP;
+
+ pdbus_error_init(&error);
+
+ if (!(m = pdbus_message_new_method_call(
+ RTKIT_SERVICE_NAME,
+ RTKIT_OBJECT_PATH,
+ "org.freedesktop.RealtimeKit1",
+ "MakeThreadRealtimeWithPID"))) {
+ ret = -ENOMEM;
+ goto finish;
+ }
+
+ pid = (dbus_uint64_t) process;
+ tid = (dbus_uint64_t) thread;
+ u32 = (dbus_uint32_t) priority;
+
+ if (!pdbus_message_append_args(m, DBUS_TYPE_UINT64, &pid,
+ DBUS_TYPE_UINT64, &tid,
+ DBUS_TYPE_UINT32, &u32,
+ DBUS_TYPE_INVALID)) {
+ ret = -ENOMEM;
+ goto finish;
+ }
+
+ if (!(r = pdbus_connection_send_with_reply_and_block(bus, m, -1, &error))) {
+ ret = translate_error(error.name);
+ goto finish;
+ }
+
+
+ if (pdbus_set_error_from_message(&error, r)) {
+ ret = translate_error(error.name);
+ goto finish;
+ }
+
+ ret = 0;
+
+finish:
+
+ if (m)
+ pdbus_message_unref(m);
+
+ if (r)
+ pdbus_message_unref(r);
+
+ pdbus_error_free(&error);
+
+ return ret;
+}
+
+int rtkit_undo_realtime(pid_t thread) {
+ struct sched_param parm;
+ int ret;
+ memset(&parm, 0, sizeof(parm));
+ ret = sched_setscheduler(thread, SCHED_OTHER, &parm);
+ if (ret < 0)
+ return -errno;
+ return ret;
+}
+
+#else
+
+int rtkit_make_realtime(pid_t process, pid_t thread, int priority) {
+ return -ENOTSUP;
+}
+
+int rtkit_undo_realtime(pid_t thread) {
+ return -ENOTSUP;
+}
+
+#endif
+
diff --git a/server/thread.c b/server/thread.c
index a6bc55a..40dd6f0 100644
--- a/server/thread.c
+++ b/server/thread.c
@@ -52,6 +52,8 @@
#include "user.h"
#include "security.h"
+extern int rtkit_make_realtime(pid_t process, pid_t thread, int priority);
+extern int rtkit_undo_realtime(pid_t thread);
#define CPU_FLAG(cpu) (1 << (cpu))
#ifdef __i386__
@@ -455,7 +457,17 @@ static void set_thread_info( struct thread *thread,
if ((req->priority >= min && req->priority <= max) ||
req->priority == THREAD_PRIORITY_IDLE ||
req->priority == THREAD_PRIORITY_TIME_CRITICAL)
+ {
+ if (thread->unix_tid == -1)
+ {}
+ else if (thread->priority == THREAD_PRIORITY_TIME_CRITICAL &&
+ req->priority != THREAD_PRIORITY_TIME_CRITICAL)
+ rtkit_undo_realtime(thread->unix_tid);
+ else if (thread->priority != THREAD_PRIORITY_TIME_CRITICAL &&
+ req->priority == THREAD_PRIORITY_TIME_CRITICAL)
+ rtkit_make_realtime(thread->unix_pid, thread->unix_tid, 1);
thread->priority = req->priority;
+ }
else
set_error( STATUS_INVALID_PARAMETER );
}
@@ -1167,6 +1179,10 @@ DECL_HANDLER(init_thread)
debug_level = max( debug_level, req->debug_level );
set_thread_affinity( current, current->affinity );
+ /* Raced with SetThreadPriority */
+ if (current->priority == THREAD_PRIORITY_TIME_CRITICAL)
+ rtkit_make_realtime(current->unix_pid, current->unix_tid, 1);
+
reply->pid = get_process_id( process );
reply->tid = get_thread_id( current );
reply->version = SERVER_PROTOCOL_VERSION;
--
1.7.0.4
More information about the wine-devel
mailing list