From: Paul Gofman pgofman@codeweavers.com
--- dlls/kernel32/kernel32.spec | 4 +- dlls/kernel32/tests/time.c | 68 +++++++++++++++++++++++++++++++++ dlls/kernelbase/kernelbase.spec | 4 +- dlls/kernelbase/sync.c | 26 +++++++++++++ include/realtimeapiset.h | 2 +- 5 files changed, 99 insertions(+), 5 deletions(-)
diff --git a/dlls/kernel32/kernel32.spec b/dlls/kernel32/kernel32.spec index c7fe7d7724e..5e4bfa5b4fd 100644 --- a/dlls/kernel32/kernel32.spec +++ b/dlls/kernel32/kernel32.spec @@ -1190,8 +1190,8 @@ @ stdcall -import QueryDosDeviceW(wstr ptr long) @ stdcall -import QueryFullProcessImageNameA(ptr long ptr ptr) @ stdcall -import QueryFullProcessImageNameW(ptr long ptr ptr) -# @ stub QueryIdleProcessorCycleTime -# @ stub QueryIdleProcessorCycleTimeEx +@ stdcall -import QueryIdleProcessorCycleTime(ptr ptr) +@ stdcall -import QueryIdleProcessorCycleTimeEx(long ptr ptr) @ stdcall QueryInformationJobObject(long long ptr long ptr) @ stdcall -import QueryMemoryResourceNotification(ptr ptr) @ stub QueryNumberOfEventLogRecords diff --git a/dlls/kernel32/tests/time.c b/dlls/kernel32/tests/time.c index 11feac72db0..55cecc696fb 100644 --- a/dlls/kernel32/tests/time.c +++ b/dlls/kernel32/tests/time.c @@ -1140,6 +1140,73 @@ static void test_QueryUnbiasedInterruptTime(void) else win_skip( "RtlQueryUnbiasedInterruptTime not supported\n" ); }
+static void test_processor_idle_cycle_time(void) +{ + unsigned int cpu_count = NtCurrentTeb()->Peb->NumberOfProcessors; + ULONG64 buffer[64]; + ULONG size; + DWORD err; + BOOL bret; + + SetLastError( 0xdeadbeef ); + size = 0; + bret = QueryIdleProcessorCycleTime( &size, NULL ); + err = GetLastError(); + ok( bret == TRUE && err == 0xdeadbeef, "got %d, %ld.\n", bret, err ); + ok( size == cpu_count * sizeof(ULONG64), "got %lu.\n", size ); + + size = 4; + memset( buffer, 0xcc, sizeof(buffer) ); + SetLastError( 0xdeadbeef ); + bret = QueryIdleProcessorCycleTime( &size, NULL ); + err = GetLastError(); + ok( bret == TRUE && err == 0xdeadbeef, "got %d, %ld.\n", bret, err ); + ok( size == 4, "got %lu.\n", size ); + ok( buffer[0] == 0xcccccccccccccccc, "got %#I64x.\n", buffer[0] ); + + size = sizeof(buffer); + SetLastError( 0xdeadbeef ); + bret = QueryIdleProcessorCycleTime( &size, NULL ); + err = GetLastError(); + ok( bret == TRUE && err == 0xdeadbeef, "got %d, %ld.\n", bret, err ); + ok( size == sizeof(buffer), "got %lu.\n", size ); + + size = sizeof(buffer); + SetLastError( 0xdeadbeef ); + bret = QueryIdleProcessorCycleTime( &size, buffer ); + err = GetLastError(); + ok( bret == TRUE && err == 0xdeadbeef, "got %d, %ld.\n", bret, err ); + ok( size == cpu_count * sizeof(ULONG64), "got %lu.\n", size ); + + SetLastError( 0xdeadbeef ); + size = 0; + bret = QueryIdleProcessorCycleTimeEx( 0, &size, NULL ); + err = GetLastError(); + ok( bret == TRUE && err == 0xdeadbeef, "got %d, %ld.\n", bret, err ); + ok( size == cpu_count * sizeof(ULONG64), "got %lu.\n", size ); + + size = 4; + SetLastError( 0xdeadbeef ); + bret = QueryIdleProcessorCycleTimeEx( 0, &size, NULL ); + err = GetLastError(); + ok( bret == TRUE && err == 0xdeadbeef, "got %d, %ld.\n", bret, err ); + ok( size == 4, "got %lu.\n", size ); + + size = sizeof(buffer); + SetLastError( 0xdeadbeef ); + bret = QueryIdleProcessorCycleTimeEx( 0, &size, NULL ); + err = GetLastError(); + ok( bret == TRUE && err == 0xdeadbeef, "got %d, %ld.\n", bret, err ); + ok( size == sizeof(buffer), "got %lu.\n", size ); + + size = sizeof(buffer); + SetLastError( 0xdeadbeef ); + bret = QueryIdleProcessorCycleTimeEx( 0, &size, buffer ); + err = GetLastError(); + ok( bret == TRUE && err == 0xdeadbeef, "got %d, %ld.\n", bret, err ); + ok( size == cpu_count * sizeof(ULONG64), "got %lu.\n", size ); +} + START_TEST(time) { HMODULE hKernel = GetModuleHandleA("kernel32"); @@ -1171,4 +1238,5 @@ START_TEST(time) test_GetTimeZoneInformationForYear(); test_GetTickCount(); test_QueryUnbiasedInterruptTime(); + test_processor_idle_cycle_time(); } diff --git a/dlls/kernelbase/kernelbase.spec b/dlls/kernelbase/kernelbase.spec index a133380a27a..5a84ceea604 100644 --- a/dlls/kernelbase/kernelbase.spec +++ b/dlls/kernelbase/kernelbase.spec @@ -1233,8 +1233,8 @@ @ stdcall QueryFullProcessImageNameA(ptr long ptr ptr) @ stdcall QueryFullProcessImageNameW(ptr long ptr ptr) @ stdcall QueryIoRingCapabilities(ptr) -# @ stub QueryIdleProcessorCycleTime -# @ stub QueryIdleProcessorCycleTimeEx +@ stdcall QueryIdleProcessorCycleTime(ptr ptr) +@ stdcall QueryIdleProcessorCycleTimeEx(long ptr ptr) @ stdcall QueryInterruptTime(ptr) @ stdcall QueryInterruptTimePrecise(ptr) @ stdcall QueryMemoryResourceNotification(ptr ptr) diff --git a/dlls/kernelbase/sync.c b/dlls/kernelbase/sync.c index b2086207caa..1d935b02ddf 100644 --- a/dlls/kernelbase/sync.c +++ b/dlls/kernelbase/sync.c @@ -245,6 +245,32 @@ void WINAPI DECLSPEC_HOTPATCH QueryUnbiasedInterruptTimePrecise( ULONGLONG *time }
+/*********************************************************************** + * QueryIdleProcessorCycleTime (kernelbase.@) + */ +BOOL WINAPI QueryIdleProcessorCycleTime( ULONG *size, ULONG64 *times ) +{ + ULONG ret_size; + NTSTATUS status = NtQuerySystemInformation( SystemProcessorIdleCycleTimeInformation, times, *size, &ret_size ); + + if (!*size || !status) *size = ret_size; + return TRUE; +} + + +/*********************************************************************** + * QueryIdleProcessorCycleTimeEx (kernelbase.@) + */ +BOOL WINAPI QueryIdleProcessorCycleTimeEx( USHORT group_id, ULONG *size, ULONG64 *times ) +{ + ULONG ret_size; + NTSTATUS status = NtQuerySystemInformationEx( SystemProcessorIdleCycleTimeInformation, &group_id, sizeof(group_id), + times, *size, &ret_size ); + if (!*size || !status) *size = ret_size; + return TRUE; +} + + /*********************************************************************** * Waits ***********************************************************************/ diff --git a/include/realtimeapiset.h b/include/realtimeapiset.h index 124a7987c8c..200244916e5 100644 --- a/include/realtimeapiset.h +++ b/include/realtimeapiset.h @@ -26,7 +26,7 @@ extern "C" { WINBASEAPI HRESULT WINAPI ConvertAuxiliaryCounterToPerformanceCounter(ULONGLONG,ULONGLONG*,ULONGLONG*); WINBASEAPI HRESULT WINAPI ConvertPerformanceCounterToAuxiliaryCounter(ULONGLONG,ULONGLONG*,ULONGLONG*); WINBASEAPI HRESULT WINAPI QueryAuxiliaryCounterFrequency(ULONGLONG*); -WINBASEAPI BOOL WINAPI QueryIdleProcessorCycleTime(ULONG*,PULONG64*); +WINBASEAPI BOOL WINAPI QueryIdleProcessorCycleTime(ULONG*,ULONG64*); WINBASEAPI BOOL WINAPI QueryIdleProcessorCycleTimeEx(USHORT,ULONG*,ULONG64*); WINBASEAPI VOID WINAPI QueryInterruptTime(ULONGLONG*); WINBASEAPI VOID WINAPI QueryInterruptTimePrecise(ULONGLONG*);