VirtualBox

source: vbox/trunk/src/VBox/Runtime/r3/win32/sched-win32.cpp@ 4015

Last change on this file since 4015 was 2981, checked in by vboxsync, 17 years ago

InnoTek -> innotek: all the headers and comments.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 14.5 KB
Line 
1/* $Id: sched-win32.cpp 2981 2007-06-01 16:01:28Z vboxsync $ */
2/** @file
3 * innotek Portable Runtime - Scheduling, Win32.
4 */
5
6/*
7 * Copyright (C) 2006-2007 innotek GmbH
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License as published by the Free Software Foundation,
13 * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
14 * distribution. VirtualBox OSE is distributed in the hope that it will
15 * be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * If you received this file as part of a commercial VirtualBox
18 * distribution, then only the terms of your commercial VirtualBox
19 * license agreement apply instead of the previous paragraph.
20 */
21
22/** @def WIN32_SCHED_ENABLED
23 * Enables the priority scheme. */
24#define WIN32_SCHED_ENABLED
25
26
27/*******************************************************************************
28* Header Files *
29*******************************************************************************/
30#define LOG_GROUP RTLOGGROUP_THREAD
31#include <Windows.h>
32
33#include <iprt/thread.h>
34#include <iprt/log.h>
35#include <iprt/assert.h>
36#include <iprt/err.h>
37#include "internal/sched.h"
38#include "internal/thread.h"
39
40
41/*******************************************************************************
42* Structures and Typedefs *
43*******************************************************************************/
44/**
45 * Configuration of one priority.
46 */
47typedef struct
48{
49 /** The priority. */
50 RTPROCPRIORITY enmPriority;
51 /** The name of this priority. */
52 const char *pszName;
53 /** The Win32 process priority class. If ANY_PROCESS_PRIORITY_CLASS the
54 * process priority class is left unchanged. */
55 DWORD dwProcessPriorityClass;
56 /** Array scheduler attributes corresponding to each of the thread types. */
57 struct
58 {
59 /** For sanity include the array index. */
60 RTTHREADTYPE enmType;
61 /** The Win32 thread priority. */
62 DWORD dwThreadPriority;
63 } aTypes[RTTHREADTYPE_END];
64} PROCPRIORITY;
65
66/** Matches any process priority class. */
67#define ANY_PROCESS_PRIORITY_CLASS (~0U)
68
69
70/*******************************************************************************
71* Global Variables *
72*******************************************************************************/
73/**
74 * Array of static priority configurations.
75 */
76static const PROCPRIORITY g_aPriorities[] =
77{
78 {
79 RTPROCPRIORITY_FLAT, "Flat", ANY_PROCESS_PRIORITY_CLASS,
80 {
81 { RTTHREADTYPE_INVALID, ~0 },
82 { RTTHREADTYPE_INFREQUENT_POLLER, THREAD_PRIORITY_NORMAL },
83 { RTTHREADTYPE_MAIN_HEAVY_WORKER, THREAD_PRIORITY_NORMAL },
84 { RTTHREADTYPE_EMULATION, THREAD_PRIORITY_NORMAL },
85 { RTTHREADTYPE_DEFAULT, THREAD_PRIORITY_NORMAL },
86 { RTTHREADTYPE_GUI, THREAD_PRIORITY_NORMAL },
87 { RTTHREADTYPE_MAIN_WORKER, THREAD_PRIORITY_NORMAL },
88 { RTTHREADTYPE_VRDP_IO, THREAD_PRIORITY_NORMAL },
89 { RTTHREADTYPE_DEBUGGER, THREAD_PRIORITY_NORMAL },
90 { RTTHREADTYPE_MSG_PUMP, THREAD_PRIORITY_NORMAL },
91 { RTTHREADTYPE_IO, THREAD_PRIORITY_NORMAL },
92 { RTTHREADTYPE_TIMER, THREAD_PRIORITY_NORMAL }
93 }
94 },
95 {
96 RTPROCPRIORITY_LOW, "Low - Below Normal", BELOW_NORMAL_PRIORITY_CLASS,
97 {
98 { RTTHREADTYPE_INVALID, ~0 },
99 { RTTHREADTYPE_INFREQUENT_POLLER, THREAD_PRIORITY_LOWEST },
100 { RTTHREADTYPE_MAIN_HEAVY_WORKER, THREAD_PRIORITY_BELOW_NORMAL },
101 { RTTHREADTYPE_EMULATION, THREAD_PRIORITY_NORMAL },
102 { RTTHREADTYPE_DEFAULT, THREAD_PRIORITY_NORMAL },
103 { RTTHREADTYPE_GUI, THREAD_PRIORITY_NORMAL },
104 { RTTHREADTYPE_MAIN_WORKER, THREAD_PRIORITY_NORMAL },
105 { RTTHREADTYPE_VRDP_IO, THREAD_PRIORITY_ABOVE_NORMAL },
106 { RTTHREADTYPE_DEBUGGER, THREAD_PRIORITY_ABOVE_NORMAL },
107 { RTTHREADTYPE_MSG_PUMP, THREAD_PRIORITY_ABOVE_NORMAL },
108 { RTTHREADTYPE_IO, THREAD_PRIORITY_HIGHEST },
109 { RTTHREADTYPE_TIMER, THREAD_PRIORITY_HIGHEST }
110 }
111 },
112 {
113 RTPROCPRIORITY_LOW, "Low", ANY_PROCESS_PRIORITY_CLASS,
114 {
115 { RTTHREADTYPE_INVALID, ~0 },
116 { RTTHREADTYPE_INFREQUENT_POLLER, THREAD_PRIORITY_LOWEST },
117 { RTTHREADTYPE_MAIN_HEAVY_WORKER, THREAD_PRIORITY_LOWEST },
118 { RTTHREADTYPE_EMULATION, THREAD_PRIORITY_LOWEST },
119 { RTTHREADTYPE_DEFAULT, THREAD_PRIORITY_BELOW_NORMAL },
120 { RTTHREADTYPE_GUI, THREAD_PRIORITY_BELOW_NORMAL },
121 { RTTHREADTYPE_MAIN_WORKER, THREAD_PRIORITY_BELOW_NORMAL },
122 { RTTHREADTYPE_VRDP_IO, THREAD_PRIORITY_NORMAL },
123 { RTTHREADTYPE_DEBUGGER, THREAD_PRIORITY_NORMAL },
124 { RTTHREADTYPE_MSG_PUMP, THREAD_PRIORITY_NORMAL },
125 { RTTHREADTYPE_IO, THREAD_PRIORITY_NORMAL },
126 { RTTHREADTYPE_TIMER, THREAD_PRIORITY_NORMAL }
127 }
128 },
129 {
130 RTPROCPRIORITY_NORMAL, "Normal - Normal", NORMAL_PRIORITY_CLASS,
131 {
132 { RTTHREADTYPE_INVALID, ~0 },
133 { RTTHREADTYPE_INFREQUENT_POLLER, THREAD_PRIORITY_LOWEST },
134 { RTTHREADTYPE_MAIN_HEAVY_WORKER, THREAD_PRIORITY_LOWEST },
135 { RTTHREADTYPE_EMULATION, THREAD_PRIORITY_BELOW_NORMAL },
136 { RTTHREADTYPE_DEFAULT, THREAD_PRIORITY_NORMAL },
137 { RTTHREADTYPE_GUI, THREAD_PRIORITY_NORMAL },
138 { RTTHREADTYPE_MAIN_WORKER, THREAD_PRIORITY_NORMAL },
139 { RTTHREADTYPE_VRDP_IO, THREAD_PRIORITY_ABOVE_NORMAL },
140 { RTTHREADTYPE_DEBUGGER, THREAD_PRIORITY_ABOVE_NORMAL },
141 { RTTHREADTYPE_MSG_PUMP, THREAD_PRIORITY_ABOVE_NORMAL },
142 { RTTHREADTYPE_IO, THREAD_PRIORITY_ABOVE_NORMAL },
143 { RTTHREADTYPE_TIMER, THREAD_PRIORITY_HIGHEST }
144 }
145 },
146 {
147 RTPROCPRIORITY_NORMAL, "Normal", ANY_PROCESS_PRIORITY_CLASS,
148 {
149 { RTTHREADTYPE_INVALID, ~0 },
150 { RTTHREADTYPE_INFREQUENT_POLLER, THREAD_PRIORITY_LOWEST },
151 { RTTHREADTYPE_MAIN_HEAVY_WORKER, THREAD_PRIORITY_LOWEST },
152 { RTTHREADTYPE_EMULATION, THREAD_PRIORITY_BELOW_NORMAL },
153 { RTTHREADTYPE_DEFAULT, THREAD_PRIORITY_NORMAL },
154 { RTTHREADTYPE_GUI, THREAD_PRIORITY_NORMAL },
155 { RTTHREADTYPE_MAIN_WORKER, THREAD_PRIORITY_NORMAL },
156 { RTTHREADTYPE_VRDP_IO, THREAD_PRIORITY_ABOVE_NORMAL },
157 { RTTHREADTYPE_DEBUGGER, THREAD_PRIORITY_ABOVE_NORMAL },
158 { RTTHREADTYPE_MSG_PUMP, THREAD_PRIORITY_ABOVE_NORMAL },
159 { RTTHREADTYPE_IO, THREAD_PRIORITY_ABOVE_NORMAL },
160 { RTTHREADTYPE_TIMER, THREAD_PRIORITY_HIGHEST }
161 }
162 },
163 {
164 RTPROCPRIORITY_HIGH, "High - High", HIGH_PRIORITY_CLASS,
165 {
166 { RTTHREADTYPE_INVALID, ~0 },
167 { RTTHREADTYPE_INFREQUENT_POLLER, THREAD_PRIORITY_LOWEST },
168 { RTTHREADTYPE_MAIN_HEAVY_WORKER, THREAD_PRIORITY_LOWEST },
169 { RTTHREADTYPE_EMULATION, THREAD_PRIORITY_BELOW_NORMAL },
170 { RTTHREADTYPE_DEFAULT, THREAD_PRIORITY_NORMAL },
171 { RTTHREADTYPE_GUI, THREAD_PRIORITY_NORMAL },
172 { RTTHREADTYPE_MAIN_WORKER, THREAD_PRIORITY_NORMAL },
173 { RTTHREADTYPE_VRDP_IO, THREAD_PRIORITY_ABOVE_NORMAL },
174 { RTTHREADTYPE_DEBUGGER, THREAD_PRIORITY_ABOVE_NORMAL },
175 { RTTHREADTYPE_MSG_PUMP, THREAD_PRIORITY_ABOVE_NORMAL },
176 { RTTHREADTYPE_IO, THREAD_PRIORITY_HIGHEST },
177 { RTTHREADTYPE_TIMER, THREAD_PRIORITY_HIGHEST }
178 }
179 },
180 {
181 RTPROCPRIORITY_HIGH, "High - Above Normal", ABOVE_NORMAL_PRIORITY_CLASS,
182 {
183 { RTTHREADTYPE_INVALID, ~0 },
184 { RTTHREADTYPE_INFREQUENT_POLLER, THREAD_PRIORITY_LOWEST },
185 { RTTHREADTYPE_MAIN_HEAVY_WORKER, THREAD_PRIORITY_LOWEST },
186 { RTTHREADTYPE_EMULATION, THREAD_PRIORITY_BELOW_NORMAL },
187 { RTTHREADTYPE_DEFAULT, THREAD_PRIORITY_NORMAL },
188 { RTTHREADTYPE_GUI, THREAD_PRIORITY_NORMAL },
189 { RTTHREADTYPE_MAIN_WORKER, THREAD_PRIORITY_NORMAL },
190 { RTTHREADTYPE_VRDP_IO, THREAD_PRIORITY_ABOVE_NORMAL },
191 { RTTHREADTYPE_DEBUGGER, THREAD_PRIORITY_ABOVE_NORMAL },
192 { RTTHREADTYPE_MSG_PUMP, THREAD_PRIORITY_ABOVE_NORMAL },
193 { RTTHREADTYPE_IO, THREAD_PRIORITY_HIGHEST },
194 { RTTHREADTYPE_TIMER, THREAD_PRIORITY_HIGHEST }
195 }
196 },
197 {
198 RTPROCPRIORITY_HIGH, "High", ANY_PROCESS_PRIORITY_CLASS,
199 {
200 { RTTHREADTYPE_INVALID, ~0 },
201 { RTTHREADTYPE_INFREQUENT_POLLER, THREAD_PRIORITY_BELOW_NORMAL },
202 { RTTHREADTYPE_MAIN_HEAVY_WORKER, THREAD_PRIORITY_NORMAL },
203 { RTTHREADTYPE_EMULATION, THREAD_PRIORITY_NORMAL },
204 { RTTHREADTYPE_DEFAULT, THREAD_PRIORITY_ABOVE_NORMAL },
205 { RTTHREADTYPE_GUI, THREAD_PRIORITY_ABOVE_NORMAL },
206 { RTTHREADTYPE_MAIN_WORKER, THREAD_PRIORITY_ABOVE_NORMAL },
207 { RTTHREADTYPE_VRDP_IO, THREAD_PRIORITY_ABOVE_NORMAL },
208 { RTTHREADTYPE_DEBUGGER, THREAD_PRIORITY_HIGHEST },
209 { RTTHREADTYPE_MSG_PUMP, THREAD_PRIORITY_HIGHEST },
210 { RTTHREADTYPE_IO, THREAD_PRIORITY_HIGHEST },
211 { RTTHREADTYPE_TIMER, THREAD_PRIORITY_HIGHEST }
212 }
213 }
214};
215
216/**
217 * The dynamic default priority configuration.
218 *
219 * This can be recalulated at runtime depending on what the
220 * system allow us to do. Presently we don't do this as it's
221 * generally not a bit issue on Win32 hosts.
222 */
223static PROCPRIORITY g_aDefaultPriority =
224{
225 RTPROCPRIORITY_LOW, "Default", ANY_PROCESS_PRIORITY_CLASS,
226 {
227 { RTTHREADTYPE_INVALID, ~0 },
228 { RTTHREADTYPE_INFREQUENT_POLLER, THREAD_PRIORITY_LOWEST },
229 { RTTHREADTYPE_MAIN_HEAVY_WORKER, THREAD_PRIORITY_BELOW_NORMAL },
230 { RTTHREADTYPE_EMULATION, THREAD_PRIORITY_NORMAL },
231 { RTTHREADTYPE_DEFAULT, THREAD_PRIORITY_NORMAL },
232 { RTTHREADTYPE_GUI, THREAD_PRIORITY_NORMAL },
233 { RTTHREADTYPE_MAIN_WORKER, THREAD_PRIORITY_NORMAL },
234 { RTTHREADTYPE_VRDP_IO, THREAD_PRIORITY_NORMAL },
235 { RTTHREADTYPE_DEBUGGER, THREAD_PRIORITY_ABOVE_NORMAL },
236 { RTTHREADTYPE_MSG_PUMP, THREAD_PRIORITY_ABOVE_NORMAL },
237 { RTTHREADTYPE_IO, THREAD_PRIORITY_HIGHEST },
238 { RTTHREADTYPE_TIMER, THREAD_PRIORITY_HIGHEST }
239 }
240};
241
242
243/** Pointer to the current priority configuration. */
244static const PROCPRIORITY *g_pProcessPriority = &g_aDefaultPriority;
245
246
247/**
248 * Calculate the scheduling properties for all the threads in the default
249 * process priority, assuming the current thread have the type enmType.
250 *
251 * @returns iprt status code.
252 * @param enmType The thread type to be assumed for the current thread.
253 */
254int rtSchedNativeCalcDefaultPriority(RTTHREADTYPE enmType)
255{
256 Assert(enmType > RTTHREADTYPE_INVALID && enmType < RTTHREADTYPE_END);
257 return VINF_SUCCESS;
258}
259
260
261/**
262 * Validates and sets the process priority.
263 * This will check that all rtThreadNativeSetPriority() will success for all the
264 * thread types when applied to the current thread.
265 *
266 * @returns iprt status code.
267 * @param enmPriority The priority to validate and set.
268 * @remark Located in sched.
269 */
270int rtProcNativeSetPriority(RTPROCPRIORITY enmPriority)
271{
272 Assert(enmPriority > RTPROCPRIORITY_INVALID && enmPriority < RTPROCPRIORITY_LAST);
273 return VINF_SUCCESS;
274}
275
276
277/**
278 * Gets the win32 thread handle.
279 *
280 * @returns Valid win32 handle for the specified thread.
281 * @param pThread The thread.
282 */
283inline HANDLE rtThreadNativeGetHandle(PRTTHREADINT pThread)
284{
285 if ((uintptr_t)pThread->Core.Key == GetCurrentThreadId())
286 return GetCurrentThread();
287 return (HANDLE)pThread->hThread;
288}
289
290
291/**
292 * Sets the priority of the thread according to the thread type
293 * and current process priority.
294 *
295 * The RTTHREADINT::enmType member has not yet been updated and will be updated by
296 * the caller on a successful return.
297 *
298 * @returns iprt status code.
299 * @param pThread The thread in question.
300 * @param enmType The thread type.
301 * @remark Located in sched.
302 */
303int rtThreadNativeSetPriority(PRTTHREADINT pThread, RTTHREADTYPE enmType)
304{
305 Assert(enmType > RTTHREADTYPE_INVALID && enmType < RTTHREADTYPE_END);
306 AssertMsg(g_pProcessPriority && g_pProcessPriority->aTypes[enmType].enmType == enmType,
307 ("enmType=%d entry=%d\n", enmType, g_pProcessPriority->aTypes[enmType].enmType));
308
309#ifdef WIN32_SCHED_ENABLED
310 if (SetThreadPriority(rtThreadNativeGetHandle(pThread), g_pProcessPriority->aTypes[enmType].dwThreadPriority))
311 return VINF_SUCCESS;
312
313 DWORD dwLastError = GetLastError();
314 int rc = RTErrConvertFromWin32(dwLastError);
315 AssertMsgFailed(("SetThreadPriority(%p, %d) failed, dwLastError=%d rc=%Vrc\n",
316 rtThreadNativeGetHandle(pThread), g_pProcessPriority->aTypes[enmType].dwThreadPriority, dwLastError, rc));
317 return rc;
318#else
319 return VINF_SUCCESS;
320#endif
321}
322
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette