Alexandre Julliard : ntdll: Support SystemPerformanceInformation on non-Linux platforms.

Alexandre Julliard julliard at winehq.org
Tue Nov 19 16:35:21 CST 2019


Module: wine
Branch: master
Commit: dad14ab8331922171393d6ef75861303c8bc8d50
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=dad14ab8331922171393d6ef75861303c8bc8d50

Author: Alexandre Julliard <julliard at 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;




More information about the wine-cvs mailing list