About the post: tl;dr: NtGdiCloseProcess has a system-wide global lock which is used quite often e.g. during a build of Chrome which spawns a lot of processes. This problem seems to be introduced between Windows 7 and Windows 10.
I thought that there would be a solution or a fix but it seems this is not yet fixed. "This problem has been reported to Microsoft and they are investigating."
> NtGdiCloseProcess has a system-wide global lock which is used quite often
"Holds" rather than "has", and importantly that system-wide lock must be held by things like SendMessageW (which sends a message and waits for its processing before returning) which is pretty critical for UI updates.
This is compounded by parallelised build processes as not only do they spawn lots of processes leading to lots of process destruction: it both fucks up the UI and completely serialises process destruction so your nice 24 process flights for faster processing end up taking multiple seconds to all shut down, and the more cores (and thus processes) you have the worse it is, and the worse your stutters.
> "Holds" rather than "has", and importantly that system-wide lock must be held by things like SendMessageW (which sends a message and waits for its processing before returning) which is pretty critical for UI updates.
Do you happen to know anything about it? I'm scratching my head how it's possible that process termination serializes with GUI... Maybe it hogs some lock on process descriptors which SendMessage also needs to grab for a moment to find the target process? I hope you didn't mean to say that every SendMessage call is completely serialized with each other.
> Do you happen to know anything about it? I'm scratching my head how it's possible that process termination serializes with GUI…
Not anything more than what's in the essay. But possibly some (pair of) utility function calls were added for e.g. a cleanup or notification to the OS between W7 and W10 which was not noticed at the time.
> I hope you didn't mean to say that every SendMessage call is completely serialized with each other.
It's my understanding that at least a subset of SendMessage is serialised in the kernel yes, and from the essay:
> functions like SendMessageW, apparently waiting on a kernel critical region[…], deep in the call stack in win32kbase.sys!EnterCrit (not shown)
As a Windows outsider, I'm puzzled why programs used as part of the Chrome build system (which I'd expect to only use console I/O) are using APIs that cause interactions with the GUI? By analogy, is this not like gcc redundantly setting up a connection to the Xserver each time it is run?
(I'm making an assumption that NtGdiCloseProcess is part of the GUI API (GDI == Graphics Device Interface) which is why it may interact with the GUI message passing.)
In the very early days of NT the GDI subsystem was in userland and you wouldn't have this problem. Unfortunately it was too slow for machines of the 90s and so GDI+user32 is very tightly integrated with the kernel.
Even to the point where it does neat things like callback user mode code from the kernel. Unwinding this without breaking things is nigh impossible at this point.
He seems to be one of the main contributors of https://github.com/google/UIforETW
Seems to be quite useful.
---
About the post: tl;dr: NtGdiCloseProcess has a system-wide global lock which is used quite often e.g. during a build of Chrome which spawns a lot of processes. This problem seems to be introduced between Windows 7 and Windows 10.
I thought that there would be a solution or a fix but it seems this is not yet fixed. "This problem has been reported to Microsoft and they are investigating."