wok diff wine-rt/stuff/wine-rt-101107.patch @ rev 23475
updated python-cssutils (0.9.10b1 -> 1.0.2)
author | Hans-G?nter Theisgen |
---|---|
date | Sun Apr 05 15:03:14 2020 +0100 (2020-04-05) |
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 Apr 05 15:03:14 2020 +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, ¶m) != 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, ¶m) != 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 +