G2A Many GEOs
SHARE
TWEET

Untitled

a guest Sep 8th, 2012 1,170 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. From 1dceb627db51a239a63ed5276f7e8911be6751bc Mon Sep 17 00:00:00 2001
  2. From: Joakim B Hernberg <jhernberg@alchemy.lu>
  3. Date: Sun, 7 Nov 2010 19:10:49 +0100
  4. Subject: [PATCH] 3:rd wine-rt patch 101107
  5.  
  6. ---
  7.  README.WINE-RT  |   27 +++++++++++++++++
  8.  server/main.c   |   60 ++++++++++++++++++++++++++++++++++++++
  9.  server/thread.c |   87 ++++++++++++++++++++++++++++++++++++++++++------------
  10.  3 files changed, 154 insertions(+), 20 deletions(-)
  11.  create mode 100644 README.WINE-RT
  12.  
  13. diff --git a/README.WINE-RT b/README.WINE-RT
  14. new file mode 100644
  15. index 0000000..3f3f2c1
  16. --- /dev/null
  17. +++ b/README.WINE-RT
  18. @@ -0,0 +1,27 @@
  19. +What is it?
  20. +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.
  21. +Windows' concept of priority classes is not implemented at all.
  22. +
  23. +Please note that threads running SCHED_FIFO might hang your entire system, so please exercise caution!
  24. +
  25. +How does it work?
  26. +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.
  27. +
  28. +How to use it?
  29. +The Wine-RT functionality is not enabled by default. Instead it is controlled by 2 environment variables "WINE_RT" and "WINE_SRV_RT".
  30. +
  31. +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.
  32. +
  33. +WINE_SRV_RT makes the wineserver main thread run SCHED_FIFO.  Valid values range from 1 to your system's rtprio max value.
  34. +
  35. +We can set these variables in 2 simple ways.
  36. +First one is using a terminal with "exports", like this:
  37. +export WINE_RT=#
  38. +export WINE_SRV_RT=#
  39. +wine <app>
  40. +
  41. +or just prefix your application with 'env VARIABLE=value', like this:
  42. +env WINE_RT=# WINE_SRV_RT=# wine <app>
  43. +
  44. +A recommended starting point might be "env WINE_RT=15 WINE_SRV_RT=10 wine appname.exe".
  45. +
  46. diff --git a/server/main.c b/server/main.c
  47. index 2d841e8..a89d1e0 100644
  48. --- a/server/main.c
  49. +++ b/server/main.c
  50. @@ -27,10 +27,18 @@
  51.  #include <stdio.h>
  52.  #include <stdlib.h>
  53.  #include <sys/time.h>
  54. +#include <sys/resource.h>
  55. +#include <sys/mman.h>
  56.  #include <unistd.h>
  57.  #ifdef HAVE_GETOPT_H
  58.  # include <getopt.h>
  59.  #endif
  60. +#ifdef HAVE_SCHED_H
  61. +#include <sched.h>
  62. +#ifndef SCHED_NORMAL
  63. +#define SCHED_NORMAL SCHED_OTHER
  64. +#endif
  65. +#endif
  66.  
  67.  #include "object.h"
  68.  #include "file.h"
  69. @@ -44,6 +52,9 @@ int foreground = 0;
  70.  timeout_t master_socket_timeout = 3 * -TICKS_PER_SEC;  /* master socket timeout, default is 3 seconds */
  71.  const char *server_argv0;
  72.  
  73. +/* global variable used here and in thread.c to determine whether wine runs with rt threads and at what base value */
  74. +int base_rt_priority = -1;
  75. +
  76.  /* parse-line args */
  77.  
  78.  static void usage(void)
  79. @@ -125,6 +136,51 @@ static void sigterm_handler( int signum )
  80.      exit(1);  /* make sure atexit functions get called */
  81.  }
  82.  
  83. +#ifdef HAVE_SCHED_H
  84. +void init_rt_scheduling( void )
  85. +{
  86. +    struct sched_param param;
  87. +    struct rlimit limit;
  88. +    int priority_max, policy, wine_server_rt_priority;
  89. +    char *enviroment, *endptr;
  90. +
  91. +    getrlimit( RLIMIT_RTPRIO, &limit );
  92. +    priority_max = limit.rlim_max;
  93. +
  94. +    /* check for realtime mode and set the base priority level */
  95. +
  96. +    if (!(enviroment = getenv( "WINE_RT" )))
  97. +        return;
  98. +    base_rt_priority = (int) strtol( enviroment, &endptr, 10 );
  99. +    if (enviroment == endptr || base_rt_priority == 0 || base_rt_priority > priority_max - 10)
  100. +    {
  101. +        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 );
  102. +        base_rt_priority = -1;
  103. +        return;
  104. +    }
  105. +    fprintf( stderr, "WINE realtime scheduling hack enabled, realtime base priority has been set to %i\n", base_rt_priority );
  106. +
  107. +    /* determine scheduling policy for the main wineserver thread */
  108. +
  109. +    if (!(enviroment = getenv( "WINE_SRV_RT" )))
  110. +    {
  111. +        fprintf( stderr, "wineserver running SCHED_NORMAL\n" );
  112. +        return;
  113. +    }
  114. +    wine_server_rt_priority = (int) strtol( enviroment, &endptr, 10 );
  115. +    if (enviroment == endptr || wine_server_rt_priority == 0 || wine_server_rt_priority > priority_max)
  116. +    {
  117. +        fprintf( stderr, "Unable to run the wineserver SCHED_FIFO, valid WINE_SRV_RT values range from 1 to %i\n", priority_max );
  118. +        return;
  119. +    }
  120. +    fprintf( stderr, "wineserver running SCHED_FIFO at priority %i\n", wine_server_rt_priority );
  121. +    policy = SCHED_FIFO;
  122. +    param.sched_priority = wine_server_rt_priority;
  123. +    if  ( (sched_setscheduler ( 0, policy, &param) != 0) && (setpriority ( 0, 0, 19) != 0) )
  124. +        fprintf (stderr, "Error scheduling wineserver as SCHED_FIFO\n");
  125. +}
  126. +#endif
  127. +
  128.  int main( int argc, char *argv[] )
  129.  {
  130.      setvbuf( stderr, NULL, _IOLBF, 0 );
  131. @@ -138,6 +194,10 @@ int main( int argc, char *argv[] )
  132.      signal( SIGTERM, sigterm_handler );
  133.      signal( SIGABRT, sigterm_handler );
  134.  
  135. +#ifdef HAVE_SCHED_H
  136. +    init_rt_scheduling();
  137. +#endif
  138. +    mlockall(MCL_FUTURE);
  139.      sock_init();
  140.      open_master_socket();
  141.  
  142. diff --git a/server/thread.c b/server/thread.c
  143. index 05e4121..2d103b4 100644
  144. --- a/server/thread.c
  145. +++ b/server/thread.c
  146. @@ -32,11 +32,18 @@
  147.  #include <sys/types.h>
  148.  #include <unistd.h>
  149.  #include <time.h>
  150. -#ifdef HAVE_POLL_H
  151. -#include <poll.h>
  152. -#endif
  153.  #ifdef HAVE_SCHED_H
  154.  #include <sched.h>
  155. +#ifndef SCHED_NORMAL
  156. +#define SCHED_NORMAL SCHED_OTHER
  157. +#endif
  158. +#ifndef SCHED_IDLE
  159. +#define SCHED_IDLE 5 /* missing from my glibc, taken from linux/sched.h */
  160. +#endif
  161. +#endif
  162. +
  163. +#ifdef HAVE_POLL_H
  164. +#include <poll.h>
  165.  #endif
  166.  
  167.  #include "ntstatus.h"
  168. @@ -164,6 +171,8 @@ static const struct fd_ops thread_fd_ops =
  169.  
  170.  static struct list thread_list = LIST_INIT(thread_list);
  171.  
  172. +extern int base_rt_priority;
  173. +
  174.  /* initialize the structure for a newly allocated thread */
  175.  static inline void init_thread_structure( struct thread *thread )
  176.  {
  177. @@ -432,29 +441,67 @@ int set_thread_affinity( struct thread *thread, affinity_t affinity )
  178.      return ret;
  179.  }
  180.  
  181. -#define THREAD_PRIORITY_REALTIME_HIGHEST 6
  182. -#define THREAD_PRIORITY_REALTIME_LOWEST -7
  183. +void set_thread_priority( struct thread *thread, int priority )
  184. +{
  185. +#ifdef HAVE_SCHED_H
  186. +    struct sched_param param;
  187. +    int policy;
  188. +    int nicelevel;
  189. +    if (base_rt_priority == -1 || (thread->unix_tid == -1)) return;
  190. +
  191. +    switch (priority)
  192. +    {
  193. +      case THREAD_PRIORITY_TIME_CRITICAL:
  194. +        param.sched_priority = base_rt_priority + 10;
  195. +        policy = SCHED_FIFO; nicelevel = -10;
  196. +        fprintf( stderr, "Thread %i at THREAD_PRIORITY_TIME_CRITICAL set to SCHED_FIFO - priority %i\n", thread->unix_tid, param.sched_priority );
  197. +        break;
  198. +      case THREAD_PRIORITY_HIGHEST:
  199. +        param.sched_priority = base_rt_priority;
  200. +        policy = SCHED_RR; nicelevel = -4;
  201. +        fprintf( stderr, "Thread %i at THREAD_PRIORITY_HIGHEST set to SCHED_RR - priority %i\n", thread->unix_tid, param.sched_priority );
  202. +        break;
  203. +      case THREAD_PRIORITY_ABOVE_NORMAL:
  204. +        param.sched_priority = 0;
  205. +        policy = 4; nicelevel = -1;
  206. +        fprintf( stderr, "Thread %i at THREAD_PRIORITY_ABOVE_NORMAL set to SCHED_ISO - priority %i\n", thread->unix_tid, param.sched_priority );
  207. +        break;
  208. +      case THREAD_PRIORITY_NORMAL:
  209. +        param.sched_priority = 0;
  210. +        policy = SCHED_NORMAL; nicelevel = 0;
  211. +        fprintf( stderr, "Setting thread %i at level THREAD_PRIORITY_NORMAL to SCHED_NORMAL\n", thread->unix_tid );
  212. +       break;
  213. +      case THREAD_PRIORITY_BELOW_NORMAL:
  214. +        param.sched_priority = 0;
  215. +        policy = SCHED_BATCH; nicelevel = 1;
  216. +        fprintf( stderr, "Setting thread %i at level THREAD_PRIORITY_BELOW_NORMAL to SCHED_BATCH\n", thread->unix_tid );
  217. +        break;
  218. +      case THREAD_PRIORITY_LOWEST:
  219. +        param.sched_priority = 0;
  220. +        policy = SCHED_BATCH; nicelevel = 10;
  221. +        fprintf( stderr, "Setting thread %i at THREAD_PRIORITY_LOWEST level to SCHED_BATCH\n", thread->unix_tid );
  222. +        break;
  223. +      case THREAD_PRIORITY_IDLE:
  224. +        param.sched_priority = 0;
  225. +        policy = SCHED_IDLE; nicelevel = 19;
  226. +        fprintf( stderr, "Setting thread %i with level THREAD_PRIORITY_IDLE to SCHED_IDLE\n", thread->unix_tid );
  227. +        break;
  228. +      default:
  229. +        fprintf( stderr, "Error setting scheduling priority level, unknown should never come here\n" );
  230. +        return;
  231. +    }
  232. +    if (sched_setscheduler (thread->unix_tid, policy, &param) != 0) fprintf (stderr, "Error setting priorities\n"); if (setpriority ( 0, thread->unix_tid, nicelevel) != 0) fprintf (stderr, "Error setting priorities\n");
  233. +    thread->priority = priority;
  234. +    return;
  235. +#endif
  236. +}
  237.  
  238.  /* set all information about a thread */
  239.  static void set_thread_info( struct thread *thread,
  240.                               const struct set_thread_info_request *req )
  241.  {
  242.      if (req->mask & SET_THREAD_INFO_PRIORITY)
  243. -    {
  244. -        int max = THREAD_PRIORITY_HIGHEST;
  245. -        int min = THREAD_PRIORITY_LOWEST;
  246. -        if (thread->process->priority == PROCESS_PRIOCLASS_REALTIME)
  247. -        {
  248. -            max = THREAD_PRIORITY_REALTIME_HIGHEST;
  249. -            min = THREAD_PRIORITY_REALTIME_LOWEST;
  250. -        }
  251. -        if ((req->priority >= min && req->priority <= max) ||
  252. -            req->priority == THREAD_PRIORITY_IDLE ||
  253. -            req->priority == THREAD_PRIORITY_TIME_CRITICAL)
  254. -            thread->priority = req->priority;
  255. -        else
  256. -            set_error( STATUS_INVALID_PARAMETER );
  257. -    }
  258. +        set_thread_priority( thread, req->priority );
  259.      if (req->mask & SET_THREAD_INFO_AFFINITY)
  260.      {
  261.          if ((req->affinity & thread->process->affinity) != req->affinity)
  262. --
  263. 1.7.3.2
RAW Paste Data
Ledger Nano X - The secure hardware wallet
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Top