1
0
mirror of https://github.com/golang/go synced 2024-11-19 21:34:45 -07:00

runtime: disable dynamic priority boosting on windows

Windows dynamic priority boosting assumes that a process has different types
of dedicated threads -- GUI, IO, computational, etc. Go processes use
equivalent threads that all do a mix of GUI, IO, computations, etc.
In such context dynamic priority boosting does nothing but harm, so turn it off.
In particular, if 2 goroutines do heavy IO on a server uniprocessor machine,
windows rejects to schedule timer thread for 2+ seconds when priority boosting is enabled.
Fixes #5971.

R=alex.brainman
CC=golang-dev
https://golang.org/cl/12406043
This commit is contained in:
Dmitriy Vyukov 2013-08-04 14:08:13 +04:00
parent 7d4ea6cc9e
commit a574822f80
3 changed files with 17 additions and 4 deletions

View File

@ -423,8 +423,6 @@ func testVariousDeadlines(t *testing.T, maxProcs int) {
switch runtime.GOOS { switch runtime.GOOS {
case "plan9": case "plan9":
t.Skipf("skipping test on %q", runtime.GOOS) t.Skipf("skipping test on %q", runtime.GOOS)
case "windows":
t.Skipf("skipping test on %q, see issue 5971", runtime.GOOS)
} }
defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(maxProcs)) defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(maxProcs))

View File

@ -78,8 +78,7 @@ retry:
qty = 0; qty = 0;
wait = INFINITE; wait = INFINITE;
if(!block) if(!block)
// TODO(brainman): should use 0 here instead, but scheduler hogs CPU wait = 0;
wait = 1;
// TODO(brainman): Need a loop here to fetch all pending notifications // TODO(brainman): Need a loop here to fetch all pending notifications
// (or at least a batch). Scheduler will behave better if is given // (or at least a batch). Scheduler will behave better if is given
// a batch of newly runnable goroutines. // a batch of newly runnable goroutines.

View File

@ -24,6 +24,7 @@
#pragma dynimport runtime·GetSystemTimeAsFileTime GetSystemTimeAsFileTime "kernel32.dll" #pragma dynimport runtime·GetSystemTimeAsFileTime GetSystemTimeAsFileTime "kernel32.dll"
#pragma dynimport runtime·GetThreadContext GetThreadContext "kernel32.dll" #pragma dynimport runtime·GetThreadContext GetThreadContext "kernel32.dll"
#pragma dynimport runtime·LoadLibrary LoadLibraryW "kernel32.dll" #pragma dynimport runtime·LoadLibrary LoadLibraryW "kernel32.dll"
#pragma dynimport runtime·LoadLibraryA LoadLibraryA "kernel32.dll"
#pragma dynimport runtime·ResumeThread ResumeThread "kernel32.dll" #pragma dynimport runtime·ResumeThread ResumeThread "kernel32.dll"
#pragma dynimport runtime·SetConsoleCtrlHandler SetConsoleCtrlHandler "kernel32.dll" #pragma dynimport runtime·SetConsoleCtrlHandler SetConsoleCtrlHandler "kernel32.dll"
#pragma dynimport runtime·SetEvent SetEvent "kernel32.dll" #pragma dynimport runtime·SetEvent SetEvent "kernel32.dll"
@ -55,6 +56,7 @@ extern void *runtime·GetSystemInfo;
extern void *runtime·GetSystemTimeAsFileTime; extern void *runtime·GetSystemTimeAsFileTime;
extern void *runtime·GetThreadContext; extern void *runtime·GetThreadContext;
extern void *runtime·LoadLibrary; extern void *runtime·LoadLibrary;
extern void *runtime·LoadLibraryA;
extern void *runtime·ResumeThread; extern void *runtime·ResumeThread;
extern void *runtime·SetConsoleCtrlHandler; extern void *runtime·SetConsoleCtrlHandler;
extern void *runtime·SetEvent; extern void *runtime·SetEvent;
@ -78,6 +80,9 @@ getproccount(void)
void void
runtime·osinit(void) runtime·osinit(void)
{ {
void *kernel32;
void *SetProcessPriorityBoost;
// -1 = current process, -2 = current thread // -1 = current process, -2 = current thread
runtime·stdcall(runtime·DuplicateHandle, 7, runtime·stdcall(runtime·DuplicateHandle, 7,
(uintptr)-1, (uintptr)-2, (uintptr)-1, &m->thread, (uintptr)-1, (uintptr)-2, (uintptr)-1, &m->thread,
@ -85,6 +90,17 @@ runtime·osinit(void)
runtime·stdcall(runtime·SetConsoleCtrlHandler, 2, runtime·ctrlhandler, (uintptr)1); runtime·stdcall(runtime·SetConsoleCtrlHandler, 2, runtime·ctrlhandler, (uintptr)1);
runtime·stdcall(runtime·timeBeginPeriod, 1, (uintptr)1); runtime·stdcall(runtime·timeBeginPeriod, 1, (uintptr)1);
runtime·ncpu = getproccount(); runtime·ncpu = getproccount();
kernel32 = runtime·stdcall(runtime·LoadLibraryA, 1, "kernel32.dll");
if(kernel32 != nil) {
// Windows dynamic priority boosting assumes that a process has different types
// of dedicated threads -- GUI, IO, computational, etc. Go processes use
// equivalent threads that all do a mix of GUI, IO, computations, etc.
// In such context dynamic priority boosting does nothing but harm, so we turn it off.
SetProcessPriorityBoost = runtime·stdcall(runtime·GetProcAddress, 2, kernel32, "SetProcessPriorityBoost");
if(SetProcessPriorityBoost != nil) // supported since Windows XP
runtime·stdcall(SetProcessPriorityBoost, 2, (uintptr)-1, (uintptr)1);
}
} }
void void