1 /* HSCUTL2.C    (c) Copyright Mark L. Gaubatz and others, 2003-2006  */
2 /*              Host-specific functions for Hercules                 */
3 
4 /**********************************************************************/
5 /*                                                                    */
6 /*  HSCUTL2.C                                                         */
7 /*                                                                    */
8 /*  (c) 2003-2006 Mark L. Gaubatz and others                          */
9 /*                                                                    */
10 /*  Implementation of functions used in Hercules that may be missing  */
11 /*  on some platform ports.                                           */
12 /*                                                                    */
13 /*  HSCUTL2.C differs from HSCUTL.C in that the only Hercules header  */
14 /*  files permitted are config.h and hscutl.h.  This is necessary to  */
15 /*  include some header files that conflict with definitions in some  */
16 /*  Hercules header files.                                            */
17 /*                                                                    */
18 /*  Released under the Q Public License                               */
19 /*  (http://www.hercules-390.org/herclic.html)                        */
20 /*  as modifications to Hercules.                                     */
21 /*                                                                    */
22 /*  This file is portion of the HERCULES S/370, S/390 and             */
23 /*  z/Architecture emulator.                                          */
24 /*                                                                    */
25 /**********************************************************************/
26 
27 #include "hstdinc.h"
28 
29 #define _HSCUTL2_C_
30 #define _HUTIL_DLL_
31 
32 #include "hercules.h"
33 
34 #if defined(WIN32)
35 
36 /**********************************************************************/
37 /*                                                                    */
38 /*      Win32 Patches                                                 */
39 /*                                                                    */
40 /*      The following functional equivalents are provided             */
41 /*      for the Win32 environment:                                    */
42 /*                                                                    */
43 /*      int getpriority(int which, id_t who);                         */
44 /*      int setpriority(int which, id_t who, int prio);               */
45 /*                                                                    */
46 /*                                                                    */
47 /**********************************************************************/
48 
49 //                                   Windows       Unix
50 //      THREAD_PRIORITY_TIME_CRITICAL  15           -20
51 //      THREAD_PRIORITY_HIGHEST         2           -15
52 //      THREAD_PRIORITY_ABOVE_NORMAL    1            -8
53 //      THREAD_PRIORITY_NORMAL          0             0
54 //      THREAD_PRIORITY_BELOW_NORMAL   -1             8
55 //      THREAD_PRIORITY_LOWEST         -2            15
56 //      THREAD_PRIORITY_IDLE          -15            20
57 
58 
59 /**********************************************************************/
60 /*                                                                    */
61 /*      int getpriority(int which , id_t who );                       */
62 /*                                                                    */
63 /*      Notes:                                                        */
64 /*                                                                    */
65 /*      1.      PRIO_USER not supported.                              */
66 /*      2.      who may only be specified as 0, for the current       */
67 /*              process or process group id.                          */
68 /*                                                                    */
69 /*                                                                    */
70 /**********************************************************************/
71 
72 static inline int
getpriority_process(id_t who)73 getpriority_process(id_t who)
74 {
75 
76     HANDLE process;
77     DWORD  priority;
78 
79     if (who)
80        return EINVAL;
81 
82     process = (HANDLE) -1;
83     priority = GetPriorityClass (process);
84 
85     switch (priority) {
86       case REALTIME_PRIORITY_CLASS:        return -20;
87       case HIGH_PRIORITY_CLASS:            return -15;
88       case ABOVE_NORMAL_PRIORITY_CLASS:    return  -8;
89       case NORMAL_PRIORITY_CLASS:          return   0;
90       case BELOW_NORMAL_PRIORITY_CLASS:    return   8;
91       }
92       /*   IDLE_PRIORITY_CLASS:         */ return  15;
93 }
94 
95 
96 static inline int
getpriority_thread(id_t who)97 getpriority_thread(id_t who)
98 {
99 
100     HANDLE thread;
101     int priority;
102 
103     if (who)
104        return EINVAL;
105 
106     thread = GetCurrentThread();
107     priority = GetThreadPriority (thread);
108 
109     switch (priority) {
110       case THREAD_PRIORITY_TIME_CRITICAL:  return -20;
111       case THREAD_PRIORITY_HIGHEST:        return -15;
112       case THREAD_PRIORITY_ABOVE_NORMAL:   return  -8;
113       case THREAD_PRIORITY_NORMAL:         return   0;
114       case THREAD_PRIORITY_BELOW_NORMAL:   return   8;
115       case THREAD_PRIORITY_LOWEST:         return  15;
116       }
117       /*   THREAD_PRIORITY_IDLE:        */ return  20;
118 }
119 
120 
121 static inline int
getpriority_user(id_t who)122 getpriority_user(id_t who)
123 {
124     if (who)
125        return EINVAL;
126     return 0;
127 }
128 
129 
130 DLL_EXPORT int
getpriority(int which,id_t who)131 getpriority(int which , id_t who )
132 {
133     switch (which) {
134       case PRIO_PROCESS:
135         return getpriority_thread(who);
136       case PRIO_PGRP:
137         return getpriority_process(who);
138       case PRIO_USER:
139         return getpriority_user(who);
140     }
141     return EINVAL;
142 }
143 
144 
145 /**********************************************************************/
146 /*                                                                    */
147 /*      int setpriority(int which , id_t who , int prio );            */
148 /*                                                                    */
149 /*      Notes:                                                        */
150 /*                                                                    */
151 /*      1.      PRIO_USER not supported.                              */
152 /*      2.      who may only be specified as 0, for the current       */
153 /*              process or process group id.                          */
154 /*                                                                    */
155 /*                                                                    */
156 /**********************************************************************/
157 
158 DLL_EXPORT inline int
setpriority_process(id_t who,int prio)159 setpriority_process(id_t who , int prio )
160 {
161 
162     HANDLE process;
163     DWORD  priority;
164 
165     if (who)
166        return EINVAL;
167 
168     process = (HANDLE) -1;      /* Force to current process */
169 
170     if      (prio < -15) priority = REALTIME_PRIORITY_CLASS;
171     else if (prio <  -8) priority = HIGH_PRIORITY_CLASS;
172     else if (prio <   0) priority = ABOVE_NORMAL_PRIORITY_CLASS;
173     else if (prio <   8) priority = NORMAL_PRIORITY_CLASS;
174     else if (prio <  15) priority = BELOW_NORMAL_PRIORITY_CLASS;
175     else                 priority = IDLE_PRIORITY_CLASS;
176 
177     if (!SetPriorityClass (process, priority))
178        return GetLastError();
179     return 0;
180 }
181 
182 
183 static inline int
setpriority_thread(id_t who,int prio)184 setpriority_thread(id_t who , int prio )
185 {
186 
187     HANDLE thread;
188     int priority;
189 
190     if (who)
191        return EINVAL;
192 
193     thread = GetCurrentThread();
194 
195     if      (prio < -15) priority = THREAD_PRIORITY_TIME_CRITICAL;
196     else if (prio <  -8) priority = THREAD_PRIORITY_HIGHEST;
197     else if (prio <   0) priority = THREAD_PRIORITY_ABOVE_NORMAL;
198     else if (prio <   8) priority = THREAD_PRIORITY_NORMAL;
199     else if (prio <  15) priority = THREAD_PRIORITY_BELOW_NORMAL;
200     else if (prio <  20) priority = THREAD_PRIORITY_LOWEST;
201     else                 priority = THREAD_PRIORITY_IDLE;
202 
203     if (!SetThreadPriority (thread, priority))
204        return GetLastError();
205     return 0;
206 }
207 
208 
209 static inline int
setpriority_user(id_t who,int prio)210 setpriority_user(id_t who , int prio )
211 {
212     if (who)
213        return EINVAL;
214     return 0;                   /* Ignore */
215     prio = prio;                        /* Unreferenced               */
216 }
217 
218 
219 DLL_EXPORT int
setpriority(int which,id_t who,int prio)220 setpriority(int which , id_t who , int prio )
221 {
222     switch (which) {
223       case PRIO_PROCESS:
224         return setpriority_thread(who, prio);
225       case PRIO_PGRP:
226         return setpriority_process(who, prio);
227       case PRIO_USER:
228         return setpriority_user(who, prio);
229     }
230     return EINVAL;
231 }
232 
233 #endif // defined(WIN32)
234