diff --git a/patches/kernel32-K32GetPerformanceInfo/0001-kernel32-Make-K32GetPerformanceInfo-faster.patch b/patches/kernel32-K32GetPerformanceInfo/0001-kernel32-Make-K32GetPerformanceInfo-faster.patch new file mode 100644 index 00000000..b163eb3e --- /dev/null +++ b/patches/kernel32-K32GetPerformanceInfo/0001-kernel32-Make-K32GetPerformanceInfo-faster.patch @@ -0,0 +1,155 @@ +From 9685685419231b0a3f8a2e454e4c963564629332 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Sun, 19 Feb 2017 05:38:40 +0100 +Subject: kernel32: Make K32GetPerformanceInfo faster. + +--- + dlls/kernel32/cpu.c | 68 ++++++++++++++++++++--------------------------------- + server/process.c | 18 ++++++++++++++ + server/protocol.def | 9 +++++++ + 3 files changed, 52 insertions(+), 43 deletions(-) + +diff --git a/dlls/kernel32/cpu.c b/dlls/kernel32/cpu.c +index 5fb806746a0..01cb469b8db 100644 +--- a/dlls/kernel32/cpu.c ++++ b/dlls/kernel32/cpu.c +@@ -216,14 +216,8 @@ BOOL WINAPI IsProcessorFeaturePresent ( + */ + BOOL WINAPI K32GetPerformanceInfo(PPERFORMANCE_INFORMATION info, DWORD size) + { +- union +- { +- SYSTEM_PERFORMANCE_INFORMATION performance; +- SYSTEM_PROCESS_INFORMATION process; +- SYSTEM_BASIC_INFORMATION basic; +- } *sysinfo; +- SYSTEM_PROCESS_INFORMATION *spi; +- DWORD process_info_size; ++ SYSTEM_PERFORMANCE_INFORMATION performance; ++ SYSTEM_BASIC_INFORMATION basic; + NTSTATUS status; + + TRACE( "(%p, %d)\n", info, size ); +@@ -237,53 +231,41 @@ BOOL WINAPI K32GetPerformanceInfo(PPERFORMANCE_INFORMATION info, DWORD size) + memset( info, 0, sizeof(*info) ); + info->cb = sizeof(*info); + +- /* fields from SYSTEM_PROCESS_INFORMATION */ +- NtQuerySystemInformation( SystemProcessInformation, NULL, 0, &process_info_size ); +- for (;;) ++ SERVER_START_REQ( get_system_info ) + { +- sysinfo = HeapAlloc( GetProcessHeap(), 0, max(process_info_size, sizeof(*sysinfo)) ); +- if (!sysinfo) ++ status = wine_server_call( req ); ++ if (!status) + { +- SetLastError( ERROR_OUTOFMEMORY ); +- return FALSE; ++ info->ProcessCount = reply->processes; ++ info->HandleCount = reply->handles; ++ info->ThreadCount = reply->threads; + } +- status = NtQuerySystemInformation( SystemProcessInformation, &sysinfo->process, +- process_info_size, &process_info_size ); +- if (!status) break; +- if (status != STATUS_INFO_LENGTH_MISMATCH) +- goto err; +- HeapFree( GetProcessHeap(), 0, sysinfo ); +- } +- for (spi = &sysinfo->process;; spi = (SYSTEM_PROCESS_INFORMATION *)(((PCHAR)spi) + spi->NextEntryOffset)) +- { +- info->ProcessCount++; +- info->HandleCount += spi->HandleCount; +- info->ThreadCount += spi->dwThreadCount; +- if (spi->NextEntryOffset == 0) break; + } ++ SERVER_END_REQ; ++ ++ if (status) goto err; + + /* fields from SYSTEM_PERFORMANCE_INFORMATION */ +- status = NtQuerySystemInformation( SystemPerformanceInformation, &sysinfo->performance, +- sizeof(sysinfo->performance), NULL ); ++ status = NtQuerySystemInformation( SystemPerformanceInformation, &performance, ++ sizeof(performance), NULL ); + if (status) goto err; +- info->CommitTotal = sysinfo->performance.TotalCommittedPages; +- info->CommitLimit = sysinfo->performance.TotalCommitLimit; +- info->CommitPeak = sysinfo->performance.PeakCommitment; +- info->PhysicalAvailable = sysinfo->performance.AvailablePages; +- info->KernelTotal = sysinfo->performance.PagedPoolUsage + +- sysinfo->performance.NonPagedPoolUsage; +- info->KernelPaged = sysinfo->performance.PagedPoolUsage; +- info->KernelNonpaged = sysinfo->performance.NonPagedPoolUsage; ++ info->CommitTotal = performance.TotalCommittedPages; ++ info->CommitLimit = performance.TotalCommitLimit; ++ info->CommitPeak = performance.PeakCommitment; ++ info->PhysicalAvailable = performance.AvailablePages; ++ info->KernelTotal = performance.PagedPoolUsage + ++ performance.NonPagedPoolUsage; ++ info->KernelPaged = performance.PagedPoolUsage; ++ info->KernelNonpaged = performance.NonPagedPoolUsage; + + /* fields from SYSTEM_BASIC_INFORMATION */ +- status = NtQuerySystemInformation( SystemBasicInformation, &sysinfo->basic, +- sizeof(sysinfo->basic), NULL ); ++ status = NtQuerySystemInformation( SystemBasicInformation, &basic, ++ sizeof(basic), NULL ); + if (status) goto err; +- info->PhysicalTotal = sysinfo->basic.MmNumberOfPhysicalPages; +- info->PageSize = sysinfo->basic.PageSize; ++ info->PhysicalTotal = basic.MmNumberOfPhysicalPages; ++ info->PageSize = basic.PageSize; + + err: +- HeapFree( GetProcessHeap(), 0, sysinfo ); + if (status) + { + SetLastError( RtlNtStatusToDosError( status ) ); +diff --git a/server/process.c b/server/process.c +index eaf61eaea99..a59be6cfad7 100644 +--- a/server/process.c ++++ b/server/process.c +@@ -1754,3 +1754,21 @@ DECL_HANDLER(set_job_completion_port) + + release_object( job ); + } ++ ++/* Retrieve process, thread and handle count */ ++DECL_HANDLER(get_system_info) ++{ ++ struct process *process; ++ ++ reply->processes = 0; ++ reply->threads = 0; ++ reply->handles = 0; ++ ++ LIST_FOR_EACH_ENTRY( process, &process_list, struct process, entry ) ++ { ++ if (!process->running_threads) continue; ++ reply->processes++; ++ reply->threads += process->running_threads; ++ reply->handles += get_handle_table_count( process ); ++ } ++} +diff --git a/server/protocol.def b/server/protocol.def +index c26b24edc5f..85137ab3b52 100644 +--- a/server/protocol.def ++++ b/server/protocol.def +@@ -3866,3 +3866,12 @@ struct handle_info + obj_handle_t handle; /* handle to the job */ + int status; /* process exit code */ + @END ++ ++ ++/* Return system information values */ ++@REQ(get_system_info) ++@REPLY ++ unsigned int processes; /* number of processes */ ++ unsigned int threads; /* number of threads */ ++ unsigned int handles; /* number of handles */ ++@END +-- +2.11.0 + diff --git a/patches/kernel32-K32GetPerformanceInfo/definition b/patches/kernel32-K32GetPerformanceInfo/definition new file mode 100644 index 00000000..7c05e9ab --- /dev/null +++ b/patches/kernel32-K32GetPerformanceInfo/definition @@ -0,0 +1 @@ +Fixes: Use separate wineserver call for kernel32.K32GetPerformanceInfo diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index 4c46d24b..f556ba86 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -180,6 +180,7 @@ patch_enable_all () enable_kernel32_GetCurrentPackageFamilyName="$1" enable_kernel32_GetPackageFullName="$1" enable_kernel32_GetShortPathName="$1" + enable_kernel32_K32GetPerformanceInfo="$1" enable_kernel32_LocaleNameToLCID="$1" enable_kernel32_Locale_Definitions="$1" enable_kernel32_Misalign_Workaround="$1" @@ -751,6 +752,9 @@ patch_enable () kernel32-GetShortPathName) enable_kernel32_GetShortPathName="$2" ;; + kernel32-K32GetPerformanceInfo) + enable_kernel32_K32GetPerformanceInfo="$2" + ;; kernel32-LocaleNameToLCID) enable_kernel32_LocaleNameToLCID="$2" ;; @@ -4455,6 +4459,18 @@ if test "$enable_kernel32_GetShortPathName" -eq 1; then ) >> "$patchlist" fi +# Patchset kernel32-K32GetPerformanceInfo +# | +# | Modified files: +# | * dlls/kernel32/cpu.c, server/process.c, server/protocol.def +# | +if test "$enable_kernel32_K32GetPerformanceInfo" -eq 1; then + patch_apply kernel32-K32GetPerformanceInfo/0001-kernel32-Make-K32GetPerformanceInfo-faster.patch + ( + printf '%s\n' '+ { "Michael Müller", "kernel32: Make K32GetPerformanceInfo faster.", 1 },'; + ) >> "$patchlist" +fi + # Patchset kernel32-LocaleNameToLCID # | # | This patchset fixes the following Wine bugs: