mirror of
https://github.com/golang/go
synced 2024-11-19 23:14:47 -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:
parent
7d4ea6cc9e
commit
a574822f80
@ -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))
|
||||||
|
@ -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.
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user