|
88 | 88 | #include <shlobj.h> |
89 | 89 |
|
90 | 90 | #include <malloc.h> |
| 91 | +#include <powerbase.h> |
91 | 92 | #include <signal.h> |
92 | 93 | #include <direct.h> |
93 | 94 | #include <errno.h> |
@@ -1925,8 +1926,65 @@ void os::win32::print_windows_version(outputStream* st) { |
1925 | 1926 | st->cr(); |
1926 | 1927 | } |
1927 | 1928 |
|
| 1929 | +// Processor Power Information; missing from Windows headers |
| 1930 | +typedef struct _PROCESSOR_POWER_INFORMATION { |
| 1931 | + ULONG Number; |
| 1932 | + ULONG MaxMhz; // max specified clock frequency of the system processor |
| 1933 | + ULONG CurrentMhz; // max specified processor clock frequency mult. by current processor throttle |
| 1934 | + ULONG MhzLimit; // max specified processor clock frequency mult. by current processor thermal throttle limit |
| 1935 | + ULONG MaxIdleState; |
| 1936 | + ULONG CurrentIdleState; |
| 1937 | +} PROCESSOR_POWER_INFORMATION; |
| 1938 | + |
1928 | 1939 | void os::pd_print_cpu_info(outputStream* st, char* buf, size_t buflen) { |
1929 | | - // Nothing to do for now. |
| 1940 | + int proc_count = os::processor_count(); |
| 1941 | + // handle potential early cases where processor count is not yet set |
| 1942 | + if (proc_count < 1) { |
| 1943 | + SYSTEM_INFO si; |
| 1944 | + GetSystemInfo(&si); |
| 1945 | + proc_count = si.dwNumberOfProcessors; |
| 1946 | + } |
| 1947 | + |
| 1948 | + size_t sz_check = sizeof(PROCESSOR_POWER_INFORMATION) * (size_t)proc_count; |
| 1949 | + NTSTATUS status = ::CallNtPowerInformation(ProcessorInformation, NULL, 0, buf, (ULONG) buflen); |
| 1950 | + int max_mhz = -1, current_mhz = -1, mhz_limit = -1; |
| 1951 | + bool same_vals_for_all_cpus = true; |
| 1952 | + |
| 1953 | + if (status == ERROR_SUCCESS) { |
| 1954 | + PROCESSOR_POWER_INFORMATION* pppi = (PROCESSOR_POWER_INFORMATION*) buf; |
| 1955 | + for (int i = 0; i < proc_count; i++) { |
| 1956 | + if (i == 0) { |
| 1957 | + max_mhz = (int) pppi->MaxMhz; |
| 1958 | + current_mhz = (int) pppi->CurrentMhz; |
| 1959 | + mhz_limit = (int) pppi->MhzLimit; |
| 1960 | + } else { |
| 1961 | + if (max_mhz != (int) pppi->MaxMhz || |
| 1962 | + current_mhz != (int) pppi->CurrentMhz || |
| 1963 | + mhz_limit != (int) pppi->MhzLimit) { |
| 1964 | + same_vals_for_all_cpus = false; |
| 1965 | + break; |
| 1966 | + } |
| 1967 | + } |
| 1968 | + // avoid iteration in case buf is too small to hold all proc infos |
| 1969 | + if (sz_check > buflen) break; |
| 1970 | + pppi++; |
| 1971 | + } |
| 1972 | + |
| 1973 | + if (same_vals_for_all_cpus && max_mhz != -1) { |
| 1974 | + st->print_cr("Processor Information for all %d processors :", proc_count); |
| 1975 | + st->print_cr(" Max Mhz: %d, Current Mhz: %d, Mhz Limit: %d", max_mhz, current_mhz, mhz_limit); |
| 1976 | + return; |
| 1977 | + } |
| 1978 | + // differing values, iterate again |
| 1979 | + pppi = (PROCESSOR_POWER_INFORMATION*) buf; |
| 1980 | + for (int i = 0; i < proc_count; i++) { |
| 1981 | + st->print_cr("Processor Information for processor %d", (int) pppi->Number); |
| 1982 | + st->print_cr(" Max Mhz: %d, Current Mhz: %d, Mhz Limit: %d", |
| 1983 | + (int) pppi->MaxMhz, (int) pppi->CurrentMhz, (int) pppi->MhzLimit); |
| 1984 | + if (sz_check > buflen) break; |
| 1985 | + pppi++; |
| 1986 | + } |
| 1987 | + } |
1930 | 1988 | } |
1931 | 1989 |
|
1932 | 1990 | void os::get_summary_cpu_info(char* buf, size_t buflen) { |
|
0 commit comments