Implement THREAD_PRIORITY_TIME_CRITICAL
Mike Hearn
mh at codeweavers.com
Fri Mar 31 07:06:23 CST 2006
This patch gives me rock solid audio in Imperium Galactica 2, so now the
game works perfectly.
There has been discussion around this issue with respect to security in
the past, however, regardless of what approach is adopted this code will
have to be written anyway.
thanks -mike
-------------- next part --------------
diff --git a/server/thread.c b/server/thread.c
index 1c00ce7..ed0d09a 100644
--- a/server/thread.c
+++ b/server/thread.c
@@ -32,6 +32,9 @@
#include <sys/types.h>
#include <unistd.h>
#include <time.h>
+#ifdef HAVE_SCHED_H
+#include <sched.h>
+#endif
#ifdef HAVE_POLL_H
#include <poll.h>
#endif
@@ -314,12 +317,59 @@ struct thread *get_thread_from_pid( int
return NULL;
}
+static void set_thread_priority( int unix_tid, int ntprio )
+{
+#ifdef HAVE_SCHED_H
+ struct sched_param param;
+ int result, scheduler;
+
+ assert( unix_tid != -1 );
+
+ if (ntprio == THREAD_PRIORITY_TIME_CRITICAL)
+ {
+ param.sched_priority = 1;
+ scheduler = SCHED_FIFO;
+ }
+ else
+ {
+ param.sched_priority = 0;
+ scheduler = SCHED_OTHER;
+ }
+
+ result = sched_setscheduler( unix_tid, scheduler, ¶m );
+
+ if (result == 0) return;
+
+ if (result == -EPERM)
+ {
+ static int need_warning = 1;
+
+ if (need_warning)
+ {
+ fprintf( stderr, "\nwineserver: Failed to promote the priority of a time critical thread.\n" );
+ fprintf( stderr, "Audio may destabilise. To fix this re-run the application as root.\n\n" );
+ need_warning = 0;
+ }
+
+ return;
+ }
+
+ perror( "wineserver: sched_setscheduler" );
+#endif
+}
+
/* set all information about a thread */
static void set_thread_info( struct thread *thread,
const struct set_thread_info_request *req )
{
if (req->mask & SET_THREAD_INFO_PRIORITY)
+ {
+ if ((thread->priority != req->priority) && (thread->unix_tid != -1))
+ set_thread_priority( thread->unix_tid, req->priority );
+
thread->priority = req->priority;
+ }
+
if (req->mask & SET_THREAD_INFO_AFFINITY)
{
if (req->affinity != 1) set_error( STATUS_INVALID_PARAMETER );
@@ -902,6 +952,10 @@ DECL_HANDLER(init_thread)
}
debug_level = max( debug_level, req->debug_level );
+ /* we may have raced with a SetThreadPriority call */
+ if (current->priority != THREAD_PRIORITY_NORMAL)
+ set_thread_priority( current->unix_tid, current->priority );
+
reply->pid = get_process_id( process );
reply->tid = get_thread_id( current );
reply->version = SERVER_PROTOCOL_VERSION;
More information about the wine-patches
mailing list