Module: wine Branch: master Commit: dad14ab8331922171393d6ef75861303c8bc8d50 URL: https://source.winehq.org/git/wine.git/?a=commit;h=dad14ab8331922171393d6ef7...
Author: Alexandre Julliard julliard@winehq.org Date: Mon Nov 18 14:55:00 2019 +0100
ntdll: Support SystemPerformanceInformation on non-Linux platforms.
Based on the GlobalMemoryStatusEx implementation.
---
dlls/ntdll/nt.c | 197 ++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 147 insertions(+), 50 deletions(-)
diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c index b6daa226b3..c9b278d3fc 100644 --- a/dlls/ntdll/nt.c +++ b/dlls/ntdll/nt.c @@ -50,6 +50,19 @@ #endif #include <time.h>
+#ifdef sun +/* FIXME: Unfortunately swapctl can't be used with largefile.... */ +# undef _FILE_OFFSET_BITS +# define _FILE_OFFSET_BITS 32 +# ifdef HAVE_SYS_RESOURCE_H +# include <sys/resource.h> +# endif +# ifdef HAVE_SYS_STAT_H +# include <sys/stat.h> +# endif +# include <sys/swap.h> +#endif + #define NONAMELESSUNION #include "ntstatus.h" #define WIN32_NO_STATUS @@ -2347,6 +2360,139 @@ static NTSTATUS get_firmware_info(SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti, ULONG
#endif
+static void get_performance_info( SYSTEM_PERFORMANCE_INFORMATION *info ) +{ + unsigned long long totalram = 0, freeram = 0, totalswap = 0, freeswap = 0; + FILE *fp; + + memset( info, 0, sizeof(*info) ); + + if ((fp = fopen("/proc/uptime", "r"))) + { + double uptime, idle_time; + + fscanf(fp, "%lf %lf", &uptime, &idle_time); + fclose(fp); + info->IdleTime.QuadPart = 10000000 * idle_time; + } + else + { + static ULONGLONG idle; + /* many programs expect IdleTime to change so fake change */ + info->IdleTime.QuadPart = ++idle; + } + +#ifdef linux + if ((fp = fopen("/proc/meminfo", "r"))) + { + unsigned long long value; + char line[64]; + + while (fgets(line, sizeof(line), fp)) + { + if(sscanf(line, "MemTotal: %llu kB", &value) == 1) + totalram += value * 1024; + else if(sscanf(line, "MemFree: %llu kB", &value) == 1) + freeram += value * 1024; + else if(sscanf(line, "SwapTotal: %llu kB", &value) == 1) + totalswap += value * 1024; + else if(sscanf(line, "SwapFree: %llu kB", &value) == 1) + freeswap += value * 1024; + else if (sscanf(line, "Buffers: %llu", &value)) + freeram += value * 1024; + else if (sscanf(line, "Cached: %llu", &value)) + freeram += value * 1024; + } + fclose(fp); + } +#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) || \ + defined(__OpenBSD__) || defined(__DragonFly__) || defined(__APPLE__) + { +#ifdef __APPLE__ + unsigned int val; +#else + unsigned long val; +#endif + int mib[2]; + size_t size_sys; + + mib[0] = CTL_HW; +#ifdef HW_MEMSIZE + { + uint64_t val64; + mib[1] = HW_MEMSIZE; + size_sys = sizeof(val64); + if (!sysctl(mib, 2, &val64, &size_sys, NULL, 0) && size_sys == sizeof(val64)) totalram = val64; + } +#endif + +#ifdef HAVE_MACH_MACH_H + { + host_name_port_t host = mach_host_self(); + mach_msg_type_number_t count; +#ifdef HOST_VM_INFO64_COUNT + vm_statistics64_data_t vm_stat; + + count = HOST_VM_INFO64_COUNT; + if (host_statistics64(host, HOST_VM_INFO64, (host_info64_t)&vm_stat, &count) == KERN_SUCCESS) + freeram = (vm_stat.free_count + vm_stat.inactive_count) * (ULONGLONG)page_size; +#endif + if (!totalram) + { + host_basic_info_data_t info; + count = HOST_BASIC_INFO_COUNT; + if (host_info(host, HOST_BASIC_INFO, (host_info_t)&info, &count) == KERN_SUCCESS) + totalram = info.max_mem; + } + mach_port_deallocate(mach_task_self(), host); + } +#endif + + if (!totalram) + { + mib[1] = HW_PHYSMEM; + size_sys = sizeof(val); + if (!sysctl(mib, 2, &val, &size_sys, NULL, 0) && size_sys == sizeof(val)) totalram = val; + } + if (!freeram) + { + mib[1] = HW_USERMEM; + size_sys = sizeof(val); + if (!sysctl(mib, 2, &val, &size_sys, NULL, 0) && size_sys == sizeof(val)) freeram = val; + } +#ifdef VM_SWAPUSAGE + { + struct xsw_usage swap; + mib[0] = CTL_VM; + mib[1] = VM_SWAPUSAGE; + size_sys = sizeof(swap); + if (!sysctl(mib, 2, &swap, &size_sys, NULL, 0) && size_sys == sizeof(swap)) + { + totalswap = swap.xsu_total; + freeswap = swap.xsu_avail; + } + } +#endif + } +#elif defined( sun ) + { + struct anoninfo swapinf; + int rval; + totalram = sysconf(_SC_PHYS_PAGES) * (ULONGLONG)page_size; + freeram = sysconf(_SC_AVPHYS_PAGES) * (ULONGLONG)page_size; + rval = swapctl(SC_AINFO, &swapinf); + if (rval > -1) + { + totalswap = swapinf.ani_max * (ULONGLONG)page_size; + freeswap = swapinf.ani_free * (ULONGLONG)page_size; + } + } +#endif + info->AvailablePages = freeram / page_size; + info->TotalCommittedPages = (totalram + totalswap - freeram - freeswap) / page_size; + info->TotalCommitLimit = (totalram + totalswap) / page_size; +} + /*********************************************************************** * RtlIsProcessorFeaturePresent [NTDLL.@] */ @@ -2415,59 +2561,10 @@ NTSTATUS WINAPI NtQuerySystemInformation( { SYSTEM_PERFORMANCE_INFORMATION spi; static BOOL fixme_written = FALSE; - FILE *fp;
- memset(&spi, 0 , sizeof(spi)); + get_performance_info( &spi ); len = sizeof(spi);
- spi.Reserved3 = 0x7fffffff; /* Available paged pool memory? */ - - if ((fp = fopen("/proc/uptime", "r"))) - { - double uptime, idle_time; - - fscanf(fp, "%lf %lf", &uptime, &idle_time); - fclose(fp); - spi.IdleTime.QuadPart = 10000000 * idle_time; - } - else - { - static ULONGLONG idle; - /* many programs expect IdleTime to change so fake change */ - spi.IdleTime.QuadPart = ++idle; - } - - if ((fp = fopen("/proc/meminfo", "r"))) - { - unsigned long long totalram = 0, freeram = 0, totalswap = 0, freeswap = 0; - char line[64]; - while (fgets(line, sizeof(line), fp)) - { - if(sscanf(line, "MemTotal: %llu kB", &totalram) == 1) - { - totalram *= 1024; - } - else if(sscanf(line, "MemFree: %llu kB", &freeram) == 1) - { - freeram *= 1024; - } - else if(sscanf(line, "SwapTotal: %llu kB", &totalswap) == 1) - { - totalswap *= 1024; - } - else if(sscanf(line, "SwapFree: %llu kB", &freeswap) == 1) - { - freeswap *= 1024; - break; - } - } - fclose(fp); - - spi.AvailablePages = freeram / page_size; - spi.TotalCommittedPages = (totalram + totalswap - freeram - freeswap) / page_size; - spi.TotalCommitLimit = (totalram + totalswap) / page_size; - } - if (Length >= len) { if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION;