|
91 | 91 | #include <shlobj.h> |
92 | 92 |
|
93 | 93 | #include <malloc.h> |
| 94 | +#include <powerbase.h> |
94 | 95 | #include <signal.h> |
95 | 96 | #include <direct.h> |
96 | 97 | #include <errno.h> |
@@ -1876,8 +1877,65 @@ void os::win32::print_windows_version(outputStream* st) { |
1876 | 1877 | st->cr(); |
1877 | 1878 | } |
1878 | 1879 |
|
| 1880 | +// Processor Power Information; missing from Windows headers |
| 1881 | +typedef struct _PROCESSOR_POWER_INFORMATION { |
| 1882 | + ULONG Number; |
| 1883 | + ULONG MaxMhz; // max specified clock frequency of the system processor |
| 1884 | + ULONG CurrentMhz; // max specified processor clock frequency mult. by current processor throttle |
| 1885 | + ULONG MhzLimit; // max specified processor clock frequency mult. by current processor thermal throttle limit |
| 1886 | + ULONG MaxIdleState; |
| 1887 | + ULONG CurrentIdleState; |
| 1888 | +} PROCESSOR_POWER_INFORMATION; |
| 1889 | + |
1879 | 1890 | void os::pd_print_cpu_info(outputStream* st, char* buf, size_t buflen) { |
1880 | | - // Nothing to do for now. |
| 1891 | + int proc_count = os::processor_count(); |
| 1892 | + // handle potential early cases where processor count is not yet set |
| 1893 | + if (proc_count < 1) { |
| 1894 | + SYSTEM_INFO si; |
| 1895 | + GetSystemInfo(&si); |
| 1896 | + proc_count = si.dwNumberOfProcessors; |
| 1897 | + } |
| 1898 | + |
| 1899 | + size_t sz_check = sizeof(PROCESSOR_POWER_INFORMATION) * (size_t)proc_count; |
| 1900 | + NTSTATUS status = ::CallNtPowerInformation(ProcessorInformation, NULL, 0, buf, (ULONG) buflen); |
| 1901 | + int max_mhz = -1, current_mhz = -1, mhz_limit = -1; |
| 1902 | + bool same_vals_for_all_cpus = true; |
| 1903 | + |
| 1904 | + if (status == ERROR_SUCCESS) { |
| 1905 | + PROCESSOR_POWER_INFORMATION* pppi = (PROCESSOR_POWER_INFORMATION*) buf; |
| 1906 | + for (int i = 0; i < proc_count; i++) { |
| 1907 | + if (i == 0) { |
| 1908 | + max_mhz = (int) pppi->MaxMhz; |
| 1909 | + current_mhz = (int) pppi->CurrentMhz; |
| 1910 | + mhz_limit = (int) pppi->MhzLimit; |
| 1911 | + } else { |
| 1912 | + if (max_mhz != (int) pppi->MaxMhz || |
| 1913 | + current_mhz != (int) pppi->CurrentMhz || |
| 1914 | + mhz_limit != (int) pppi->MhzLimit) { |
| 1915 | + same_vals_for_all_cpus = false; |
| 1916 | + break; |
| 1917 | + } |
| 1918 | + } |
| 1919 | + // avoid iteration in case buf is too small to hold all proc infos |
| 1920 | + if (sz_check > buflen) break; |
| 1921 | + pppi++; |
| 1922 | + } |
| 1923 | + |
| 1924 | + if (same_vals_for_all_cpus && max_mhz != -1) { |
| 1925 | + st->print_cr("Processor Information for all %d processors :", proc_count); |
| 1926 | + st->print_cr(" Max Mhz: %d, Current Mhz: %d, Mhz Limit: %d", max_mhz, current_mhz, mhz_limit); |
| 1927 | + return; |
| 1928 | + } |
| 1929 | + // differing values, iterate again |
| 1930 | + pppi = (PROCESSOR_POWER_INFORMATION*) buf; |
| 1931 | + for (int i = 0; i < proc_count; i++) { |
| 1932 | + st->print_cr("Processor Information for processor %d", (int) pppi->Number); |
| 1933 | + st->print_cr(" Max Mhz: %d, Current Mhz: %d, Mhz Limit: %d", |
| 1934 | + (int) pppi->MaxMhz, (int) pppi->CurrentMhz, (int) pppi->MhzLimit); |
| 1935 | + if (sz_check > buflen) break; |
| 1936 | + pppi++; |
| 1937 | + } |
| 1938 | + } |
1881 | 1939 | } |
1882 | 1940 |
|
1883 | 1941 | void os::get_summary_cpu_info(char* buf, size_t buflen) { |
|
0 commit comments