wok diff wine-rt/stuff/wine-rt-101107.patch @ rev 15416

Up: thunderbird-langpack-en_US (17.0.9esr)
author Dominique Corbex <domcox@slitaz.org>
date Sun Nov 03 21:52:37 2013 +0100 (2013-11-03)
parents
children
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/wine-rt/stuff/wine-rt-101107.patch	Sun Nov 03 21:52:37 2013 +0100
     1.3 @@ -0,0 +1,264 @@
     1.4 +From 1dceb627db51a239a63ed5276f7e8911be6751bc Mon Sep 17 00:00:00 2001
     1.5 +From: Joakim B Hernberg <jhernberg@alchemy.lu>
     1.6 +Date: Sun, 7 Nov 2010 19:10:49 +0100
     1.7 +Subject: [PATCH] 3:rd wine-rt patch 101107
     1.8 +
     1.9 +---
    1.10 + README.WINE-RT  |   27 +++++++++++++++++
    1.11 + server/main.c   |   60 ++++++++++++++++++++++++++++++++++++++
    1.12 + server/thread.c |   87 ++++++++++++++++++++++++++++++++++++++++++------------
    1.13 + 3 files changed, 154 insertions(+), 20 deletions(-)
    1.14 + create mode 100644 README.WINE-RT
    1.15 +
    1.16 +diff --git a/README.WINE-RT b/README.WINE-RT
    1.17 +new file mode 100644
    1.18 +index 0000000..3f3f2c1
    1.19 +--- /dev/null
    1.20 ++++ b/README.WINE-RT
    1.21 +@@ -0,0 +1,27 @@
    1.22 ++What is it?
    1.23 ++The Wine-RT patch allows programs that use windows' concept of thread priority to gain similar functionality under linux.  It maps windows priority levels to linux scheduling policies.  THREAD_PRIORITY_ABOVE_NORMAL, THREAD_PRIORITY_HIGHEST and THREAD_PRIORITY_TIME_CRITICAL levels which are made to run as linux SCHED_FIFO threads at priority levels that are defined by the WINERT variable.  THREAD_PRIORITY_NORMAL threads are run as normal linux threads (as all threads are without the patch), and the priorities below normal (THREAD_PRIORITY_BELOW_NORMAL, THREAD_PRIORITY_LOWEST) are run as SCHED_BATCH.  THREAD_PRIORITY_IDLE threads are run as SCHED_IDLE.
    1.24 ++Windows' concept of priority classes is not implemented at all.
    1.25 ++
    1.26 ++Please note that threads running SCHED_FIFO might hang your entire system, so please exercise caution! 
    1.27 ++
    1.28 ++How does it work?
    1.29 ++When a windows program asks for a thread to be run at a higher priority, Wine will ask the linux system to schedule it as a SCHED_FIFO thread, which means that the tread will keep on executing until it has either finished, voluntarily yields execution or gets preempted by a higher priority SCHED_FIFO thread.  This is already done by many linux audio applications, to ensure less xruns on lower buffer sizes.  With Wine-RT, the same thing can be done for Wine applications.
    1.30 ++ 
    1.31 ++How to use it?
    1.32 ++The Wine-RT functionality is not enabled by default. Instead it is controlled by 2 environment variables "WINE_RT" and "WINE_SRV_RT".
    1.33 ++
    1.34 ++The "WINE_RT" variable has 2 purposes, it has to be set in order to activate the patch, and it determines the priority of the SCHED_FIFO threads, Its value can be set from 1 to your system's rtprio max value minus 10, as set in limits.conf or limits.d/audio.conf. (In Debian, Ubuntu and KXStudio this value is 99). THREAD_PRIORITY_ABOVE_NORMAL threads will run at this  priority level, THREAD_PRIORITY_HIGHEST threads at this level + 5, and THREAD_PRIORITY_TIME_CRITICAL threads at this level + 10.
    1.35 ++
    1.36 ++WINE_SRV_RT makes the wineserver main thread run SCHED_FIFO.  Valid values range from 1 to your system's rtprio max value.
    1.37 ++
    1.38 ++We can set these variables in 2 simple ways.
    1.39 ++First one is using a terminal with "exports", like this:
    1.40 ++export WINE_RT=#
    1.41 ++export WINE_SRV_RT=#
    1.42 ++wine <app>
    1.43 ++
    1.44 ++or just prefix your application with 'env VARIABLE=value', like this:
    1.45 ++env WINE_RT=# WINE_SRV_RT=# wine <app>
    1.46 ++
    1.47 ++A recommended starting point might be "env WINE_RT=15 WINE_SRV_RT=10 wine appname.exe".
    1.48 ++
    1.49 +diff --git a/server/main.c b/server/main.c
    1.50 +index 2d841e8..a89d1e0 100644
    1.51 +--- a/server/main.c
    1.52 ++++ b/server/main.c
    1.53 +@@ -27,10 +27,18 @@
    1.54 + #include <stdio.h>
    1.55 + #include <stdlib.h>
    1.56 + #include <sys/time.h>
    1.57 ++#include <sys/resource.h>
    1.58 ++#include <sys/mman.h>
    1.59 + #include <unistd.h>
    1.60 + #ifdef HAVE_GETOPT_H
    1.61 + # include <getopt.h>
    1.62 + #endif
    1.63 ++#ifdef HAVE_SCHED_H
    1.64 ++#include <sched.h>
    1.65 ++#ifndef SCHED_NORMAL
    1.66 ++#define SCHED_NORMAL SCHED_OTHER
    1.67 ++#endif
    1.68 ++#endif
    1.69 + 
    1.70 + #include "object.h"
    1.71 + #include "file.h"
    1.72 +@@ -44,6 +52,9 @@ int foreground = 0;
    1.73 + timeout_t master_socket_timeout = 3 * -TICKS_PER_SEC;  /* master socket timeout, default is 3 seconds */
    1.74 + const char *server_argv0;
    1.75 + 
    1.76 ++/* global variable used here and in thread.c to determine whether wine runs with rt threads and at what base value */
    1.77 ++int base_rt_priority = -1;
    1.78 ++
    1.79 + /* parse-line args */
    1.80 + 
    1.81 + static void usage(void)
    1.82 +@@ -125,6 +136,51 @@ static void sigterm_handler( int signum )
    1.83 +     exit(1);  /* make sure atexit functions get called */
    1.84 + }
    1.85 + 
    1.86 ++#ifdef HAVE_SCHED_H
    1.87 ++void init_rt_scheduling( void )
    1.88 ++{
    1.89 ++    struct sched_param param;
    1.90 ++    struct rlimit limit;
    1.91 ++    int priority_max, policy, wine_server_rt_priority;
    1.92 ++    char *enviroment, *endptr;
    1.93 ++
    1.94 ++    getrlimit( RLIMIT_RTPRIO, &limit );
    1.95 ++    priority_max = limit.rlim_max;
    1.96 ++
    1.97 ++    /* check for realtime mode and set the base priority level */
    1.98 ++
    1.99 ++    if (!(enviroment = getenv( "WINE_RT" )))
   1.100 ++        return;
   1.101 ++    base_rt_priority = (int) strtol( enviroment, &endptr, 10 );
   1.102 ++    if (enviroment == endptr || base_rt_priority == 0 || base_rt_priority > priority_max - 10)
   1.103 ++    {
   1.104 ++        fprintf( stderr, "Unable to run WINE in rt mode, WINE_RT values supported on this system range from 1 to  %i\n", priority_max - 10 );
   1.105 ++        base_rt_priority = -1;
   1.106 ++        return;
   1.107 ++    }
   1.108 ++    fprintf( stderr, "WINE realtime scheduling hack enabled, realtime base priority has been set to %i\n", base_rt_priority );
   1.109 ++
   1.110 ++    /* determine scheduling policy for the main wineserver thread */
   1.111 ++
   1.112 ++    if (!(enviroment = getenv( "WINE_SRV_RT" )))
   1.113 ++    {
   1.114 ++        fprintf( stderr, "wineserver running SCHED_NORMAL\n" );
   1.115 ++        return;
   1.116 ++    }
   1.117 ++    wine_server_rt_priority = (int) strtol( enviroment, &endptr, 10 );
   1.118 ++    if (enviroment == endptr || wine_server_rt_priority == 0 || wine_server_rt_priority > priority_max)
   1.119 ++    {
   1.120 ++        fprintf( stderr, "Unable to run the wineserver SCHED_FIFO, valid WINE_SRV_RT values range from 1 to %i\n", priority_max );
   1.121 ++        return;
   1.122 ++    }
   1.123 ++    fprintf( stderr, "wineserver running SCHED_FIFO at priority %i\n", wine_server_rt_priority );
   1.124 ++    policy = SCHED_FIFO;
   1.125 ++    param.sched_priority = wine_server_rt_priority;
   1.126 ++    if (sched_setscheduler ( 0, policy, &param) != 0)
   1.127 ++        fprintf (stderr, "Error scheduling wineserver as SCHED_FIFO\n");
   1.128 ++}
   1.129 ++#endif
   1.130 ++
   1.131 + int main( int argc, char *argv[] )
   1.132 + {
   1.133 +     setvbuf( stderr, NULL, _IOLBF, 0 );
   1.134 +@@ -138,6 +194,10 @@ int main( int argc, char *argv[] )
   1.135 +     signal( SIGTERM, sigterm_handler );
   1.136 +     signal( SIGABRT, sigterm_handler );
   1.137 + 
   1.138 ++#ifdef HAVE_SCHED_H
   1.139 ++    init_rt_scheduling();
   1.140 ++#endif
   1.141 ++    mlockall(MCL_FUTURE);
   1.142 +     sock_init();
   1.143 +     open_master_socket();
   1.144 + 
   1.145 +diff --git a/server/thread.c b/server/thread.c
   1.146 +index 05e4121..2d103b4 100644
   1.147 +--- a/server/thread.c
   1.148 ++++ b/server/thread.c
   1.149 +@@ -32,11 +32,18 @@
   1.150 + #include <sys/types.h>
   1.151 + #include <unistd.h>
   1.152 + #include <time.h>
   1.153 +-#ifdef HAVE_POLL_H
   1.154 +-#include <poll.h>
   1.155 +-#endif
   1.156 + #ifdef HAVE_SCHED_H
   1.157 + #include <sched.h>
   1.158 ++#ifndef SCHED_NORMAL
   1.159 ++#define SCHED_NORMAL SCHED_OTHER
   1.160 ++#endif
   1.161 ++#ifndef SCHED_IDLE
   1.162 ++#define SCHED_IDLE 5 /* missing from my glibc, taken from linux/sched.h */
   1.163 ++#endif
   1.164 ++#endif
   1.165 ++
   1.166 ++#ifdef HAVE_POLL_H
   1.167 ++#include <poll.h>
   1.168 + #endif
   1.169 + 
   1.170 + #include "ntstatus.h"
   1.171 +@@ -164,6 +171,8 @@ static const struct fd_ops thread_fd_ops =
   1.172 + 
   1.173 + static struct list thread_list = LIST_INIT(thread_list);
   1.174 + 
   1.175 ++extern int base_rt_priority;
   1.176 ++
   1.177 + /* initialize the structure for a newly allocated thread */
   1.178 + static inline void init_thread_structure( struct thread *thread )
   1.179 + {
   1.180 +@@ -432,29 +441,67 @@ int set_thread_affinity( struct thread *thread, affinity_t affinity )
   1.181 +     return ret;
   1.182 + }
   1.183 + 
   1.184 +-#define THREAD_PRIORITY_REALTIME_HIGHEST 6
   1.185 +-#define THREAD_PRIORITY_REALTIME_LOWEST -7
   1.186 ++void set_thread_priority( struct thread *thread, int priority )
   1.187 ++{
   1.188 ++#ifdef HAVE_SCHED_H
   1.189 ++    struct sched_param param;
   1.190 ++    int policy;
   1.191 ++
   1.192 ++    if (base_rt_priority == -1 || (thread->unix_tid == -1)) return;
   1.193 ++
   1.194 ++    switch (priority)
   1.195 ++    {
   1.196 ++      case THREAD_PRIORITY_TIME_CRITICAL:
   1.197 ++        param.sched_priority = base_rt_priority + 10;
   1.198 ++        policy = SCHED_FIFO;
   1.199 ++        fprintf( stderr, "Thread %i at THREAD_PRIORITY_TIME_CRITICAL set to SCHED_FIFO - priority %i\n", thread->unix_tid, param.sched_priority );
   1.200 ++        break;
   1.201 ++      case THREAD_PRIORITY_HIGHEST:
   1.202 ++        param.sched_priority = base_rt_priority + 5;
   1.203 ++        policy = SCHED_FIFO;
   1.204 ++        fprintf( stderr, "Thread %i at THREAD_PRIORITY_HIGHEST set to SCHED_FIFO - priority %i\n", thread->unix_tid, param.sched_priority );
   1.205 ++        break;
   1.206 ++      case THREAD_PRIORITY_ABOVE_NORMAL:
   1.207 ++        param.sched_priority = base_rt_priority;
   1.208 ++        policy = SCHED_FIFO;
   1.209 ++        fprintf( stderr, "Thread %i at THREAD_PRIORITY_ABOVE_NORMAL set to SCHED_FIFO - priority %i\n", thread->unix_tid, param.sched_priority );
   1.210 ++        break;
   1.211 ++      case THREAD_PRIORITY_NORMAL:
   1.212 ++        param.sched_priority = 0;
   1.213 ++        policy = SCHED_NORMAL;
   1.214 ++        fprintf( stderr, "Setting thread %i at level THREAD_PRIORITY_NORMAL to SCHED_NORMAL\n", thread->unix_tid );
   1.215 ++	break;
   1.216 ++      case THREAD_PRIORITY_BELOW_NORMAL:
   1.217 ++        param.sched_priority = 0;
   1.218 ++        policy = SCHED_BATCH;
   1.219 ++        fprintf( stderr, "Setting thread %i at level THREAD_PRIORITY_BELOW_NORMAL to SCHED_BATCH\n", thread->unix_tid );
   1.220 ++        break;
   1.221 ++      case THREAD_PRIORITY_LOWEST:
   1.222 ++        param.sched_priority = 0;
   1.223 ++        policy = SCHED_BATCH;
   1.224 ++        fprintf( stderr, "Setting thread %i at THREAD_PRIORITY_LOWEST level to SCHED_BATCH\n", thread->unix_tid );
   1.225 ++        break;
   1.226 ++      case THREAD_PRIORITY_IDLE:
   1.227 ++        param.sched_priority = 0;
   1.228 ++        policy = SCHED_IDLE;
   1.229 ++        fprintf( stderr, "Setting thread %i with level THREAD_PRIORITY_IDLE to SCHED_IDLE\n", thread->unix_tid );
   1.230 ++        break;
   1.231 ++      default:
   1.232 ++        fprintf( stderr, "Error setting scheduling priority level, unknown should never come here\n" );
   1.233 ++        return;
   1.234 ++    }
   1.235 ++    if (sched_setscheduler (thread->unix_tid, policy, &param) != 0) fprintf (stderr, "Error setting priorities\n");
   1.236 ++    thread->priority = priority;
   1.237 ++    return;
   1.238 ++#endif
   1.239 ++}
   1.240 + 
   1.241 + /* set all information about a thread */
   1.242 + static void set_thread_info( struct thread *thread,
   1.243 +                              const struct set_thread_info_request *req )
   1.244 + {
   1.245 +     if (req->mask & SET_THREAD_INFO_PRIORITY)
   1.246 +-    {
   1.247 +-        int max = THREAD_PRIORITY_HIGHEST;
   1.248 +-        int min = THREAD_PRIORITY_LOWEST;
   1.249 +-        if (thread->process->priority == PROCESS_PRIOCLASS_REALTIME)
   1.250 +-        {
   1.251 +-            max = THREAD_PRIORITY_REALTIME_HIGHEST;
   1.252 +-            min = THREAD_PRIORITY_REALTIME_LOWEST;
   1.253 +-        }
   1.254 +-        if ((req->priority >= min && req->priority <= max) ||
   1.255 +-            req->priority == THREAD_PRIORITY_IDLE ||
   1.256 +-            req->priority == THREAD_PRIORITY_TIME_CRITICAL)
   1.257 +-            thread->priority = req->priority;
   1.258 +-        else
   1.259 +-            set_error( STATUS_INVALID_PARAMETER );
   1.260 +-    }
   1.261 ++        set_thread_priority( thread, req->priority );
   1.262 +     if (req->mask & SET_THREAD_INFO_AFFINITY)
   1.263 +     {
   1.264 +         if ((req->affinity & thread->process->affinity) != req->affinity)
   1.265 +-- 
   1.266 +1.7.3.2
   1.267 +