SetThreadPriority, gamerz needed (Re: Game sound problem with wine 20050310 (Debian testing))
Andreas Mohr
andi at rhlx01.fht-esslingen.de
Sun May 15 16:32:58 CDT 2005
Hi,
On Sat, May 07, 2005 at 12:13:00PM +0100, J. Grant wrote:
> On 07/05/05 10:49, Andreas Mohr wrote:
> Okay, great! I am running debian sarge 2.6.8-2-k7 kernel, not
> sure if that is SCHED_ISO and SCHED_BATCH aware, but I can
> upgrade to the latest kernel in debian testing/sarge if necessary.
Haha, good joke. That stuff will require a REAL self-made kernel,
a -ck one with that improved scheduling and much better
interactivity, probably best to grab the 2.6.11-ck8 patch version,
from http://members.optusnet.com.au/ckolivas/kernel/
(normal kernels don't have non-root realtime scheduling, due to very
tricky implementation of usually easily DoS-able realtime priorities)
> Hopefully it would give some improvement.
You'd be able to test it now, with my very preliminary
proof-of-concept patch that is attached (it's not tested since I
currently don't know of any software/game that uses
SetThreadPriority()).
Also, testing would best be done based on known-to-be-problematic
games. If this patch together with a SCHED_ISO-capable kernel
makes a real difference, then we have something that we should
continue to work on.
OK, again, you need:
- 2.6.X-ckX kernel (the ones with SCHED_ISO, SCHED_BATCH support)
- rather current (CVS) Wine, since it requires the SetThreadPriority
patches in various multimedia/sound threads in Wine
- my patch in that Wine
- one or better several preferrably problematic game(s) with in-game
lags or sound distortion etc. pp.
And of course you should first run the game *without* my patch,
since the -ck kernel may very well significantly improve game
behaviour anyway (or actually deteriorate it), so the test basis
is VERY different from running a normal kernel and this should
be taken into account properly, otherwise you can just bin those
test findings. :)
I'm interested in test results from as many people as possible,
preferrably people with a good (excessive?) gaming background ;)
The best result would be to have this patch dramatically improve
lag or sound or graphics interactivity in games in a recent CVS
Wine version on a -ck kernel, compared to exactly the same
environment *minus* my SetThreadPriority() patch.
One last thing: you might have to change the unix_tid in the
patch into unix_pid in case it fails with the unmodified patch.
Please report any changes you observe.
Have fun,
Andreas Mohr
-------------- next part --------------
Determining best CVS host...
Using CVSROOT :pserver:cvs at rhlx01.fht-esslingen.de:/home/wine
Index: server/thread.c
===================================================================
RCS file: /home/wine/wine/server/thread.c,v
retrieving revision 1.112
diff -u -r1.112 thread.c
--- server/thread.c 24 Apr 2005 17:35:52 -0000 1.112
+++ server/thread.c 15 May 2005 21:29:30 -0000
@@ -35,6 +35,7 @@
#ifdef HAVE_POLL_H
#include <poll.h>
#endif
+#include <sched.h>
#include "windef.h"
#include "winbase.h"
@@ -299,12 +300,66 @@
return NULL;
}
+static inline void set_thread_priority(struct thread *thread, int priority)
+{
+ struct sched_param parm;
+ int unix_priority = 0;
+ int unix_policy = SCHED_OTHER;
+
+ /* register the windows data... */
+ thread->priority = priority;
+
+ /* ...then try to do something useful on the Unix side */
+ switch (priority) {
+ case THREAD_PRIORITY_IDLE:
+#ifdef SCHED_BATCH
+ fprintf(stderr, "setting SCHED_BATCH idle scheduling\n");
+ unix_policy = SCHED_BATCH;
+#else
+ fprintf(stderr, "SCHED_BATCH Linux scheduling policy not available - you probably aren't running a Con Kolivas kernel...\n");
+#endif
+ break;
+ case THREAD_PRIORITY_TIME_CRITICAL:
+#ifdef SCHED_ISO
+ fprintf(stderr, "setting SCHED_ISO real-time scheduling\n");
+ unix_policy = SCHED_ISO;
+#else
+ fprintf(stderr, "SCHED_ISO Linux scheduling policy not available - you probably aren't running a Con Kolivas kernel...\n");
+#endif
+ break;
+ default:
+#if 0
+ if ((priority >= THREAD_PRIORITY_LOWEST)
+ && (priority <= THREAD_PRIORITY_HIGHEST))
+ {
+ fprintf(stderr, "not sure how to map standard priorities yet, using a best-effort implementation\n");
+ /* we can only renice to positive numbers, so... */
+ if ((priority >= THREAD_PRIORITY_LOWEST)
+ && (priority <= 0))
+ unix_priority = -priority * 4; /* multiplication might be useful */
+ }
+ else
+ fprintf(stderr, "strange priority %d, ignoring!\n");
+#else
+ /* hmm, not sure what to do here, according to
+ * man sched_setscheduler, the nice level must be set
+ * via setpriority */
+#endif
+ break;
+ }
+
+ parm.sched_priority = unix_priority;
+ /* FIXME: need to use unix_pid here instead?? */
+ if (sched_setscheduler(thread->unix_tid, unix_policy, &parm))
+ fprintf(stderr, "sched_setscheduler() failed, errno %d\n", errno);
+}
+
/* 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)
- thread->priority = req->priority;
+ set_thread_priority(thread, req->priority);
if (req->mask & SET_THREAD_INFO_AFFINITY)
{
if (req->affinity != 1) set_error( STATUS_INVALID_PARAMETER );
More information about the wine-devel
mailing list