OSDN Git Service

* autoload.cc (GetSystemTimes): Define.
authorcorinna <corinna>
Mon, 8 Jun 2009 20:04:36 +0000 (20:04 +0000)
committercorinna <corinna>
Mon, 8 Jun 2009 20:04:36 +0000 (20:04 +0000)
* fhandler_proc.cc (format_proc_uptime): Use GetSystemInfo to retrieve
processor count.  Use GetSystemTimes when available to retrieve system
idle time.  Improve debug output.
(format_proc_stat): Use GetSystemInfo to retrieve processor
count.  Improve debug output.  Ignore if SystemPerformanceInformation
returns error.  Explain why.

winsup/cygwin/ChangeLog
winsup/cygwin/autoload.cc
winsup/cygwin/fhandler_proc.cc

index b1fd664..7ee9f9e 100644 (file)
@@ -1,5 +1,15 @@
 2009-06-08  Corinna Vinschen  <corinna@vinschen.de>
 
+       * autoload.cc (GetSystemTimes): Define.
+       * fhandler_proc.cc (format_proc_uptime): Use GetSystemInfo to retrieve
+       processor count.  Use GetSystemTimes when available to retrieve system
+       idle time.  Improve debug output.
+       (format_proc_stat): Use GetSystemInfo to retrieve processor
+       count.  Improve debug output.  Ignore if SystemPerformanceInformation
+       returns error.  Explain why.
+
+2009-06-08  Corinna Vinschen  <corinna@vinschen.de>
+
        * fork.cc (frok::parent): Remove ancient code erroneously flushing
        stdout descriptor.
 
index f014192..046d31f 100644 (file)
@@ -412,6 +412,7 @@ LoadDLLfuncEx (FindFirstVolumeA, 8, kernel32, 1)
 LoadDLLfuncEx (FindNextVolumeA, 12, kernel32, 1)
 LoadDLLfuncEx (FindVolumeClose, 4, kernel32, 1)
 LoadDLLfuncEx (GetConsoleWindow, 0, kernel32, 1)
+LoadDLLfuncEx (GetSystemTimes, 12, kernel32, 1)
 LoadDLLfuncEx (GetSystemWindowsDirectoryW, 8, kernel32, 1)
 LoadDLLfuncEx (GetVolumeNameForVolumeMountPointA, 12, kernel32, 1)
 LoadDLLfuncEx (GetSystemDEPPolicy, 0, kernel32, 1)
index 4e516e5..8801655 100644 (file)
@@ -420,29 +420,33 @@ static _off64_t
 format_proc_uptime (void *, char *&destbuf)
 {
   unsigned long long uptime = 0ULL, idle_time = 0ULL;
-
   NTSTATUS ret;
-  SYSTEM_BASIC_INFORMATION sbi;
+  SYSTEM_INFO si;
   SYSTEM_TIME_OF_DAY_INFORMATION stodi;
   SYSTEM_PERFORMANCE_INFORMATION spi;
+  FILETIME idletime;
 
-  ret = NtQuerySystemInformation (SystemBasicInformation, (PVOID) &sbi,
-                                 sizeof sbi, NULL);
-  if (!NT_SUCCESS (ret))
-    {
-      debug_printf ("NtQuerySystemInformation: ret %d", ret);
-      sbi.NumberProcessors = 1;
-    }
+  GetSystemInfo (&si);
 
   ret = NtQuerySystemInformation (SystemTimeOfDayInformation, &stodi,
                                  sizeof stodi, NULL);
   if (NT_SUCCESS (ret))
     uptime = (stodi.CurrentTime.QuadPart - stodi.BootTime.QuadPart) / 100000ULL;
-
-  ret = NtQuerySystemInformation (SystemPerformanceInformation, &spi,
-                                 sizeof spi, NULL);
-  if (NT_SUCCESS (ret))
-    idle_time = (spi.IdleTime.QuadPart / sbi.NumberProcessors) / 100000ULL;
+  else
+    debug_printf ("NtQuerySystemInformation(SystemTimeOfDayInformation), "
+                 "status %p", ret);
+
+  /* Can't use NtQuerySystemInformation on 64 bit systems, so we just use
+     the offical Win32 function and fall back to NtQuerySystemInformation
+     on older systems. */
+  if (GetSystemTimes (&idletime, NULL, NULL))
+    idle_time = ((unsigned long long) idletime.dwHighDateTime << 32)
+               | idletime.dwLowDateTime;
+  else if (NT_SUCCESS (NtQuerySystemInformation (SystemPerformanceInformation,
+                                                &spi, sizeof spi, NULL)))
+    idle_time = spi.IdleTime.QuadPart;
+  idle_time /= si.dwNumberOfProcessors;
+  idle_time /= 100000ULL;
 
   destbuf = (char *) crealloc_abort (destbuf, 80);
   return __small_sprintf (destbuf, "%U.%02u %U.%02u\n",
@@ -459,28 +463,24 @@ format_proc_stat (void *, char *&destbuf)
   NTSTATUS ret;
   SYSTEM_PERFORMANCE_INFORMATION spi;
   SYSTEM_TIME_OF_DAY_INFORMATION stodi;
-  SYSTEM_BASIC_INFORMATION sbi;
+  SYSTEM_INFO si;
   tmp_pathbuf tp;
 
   char *buf = tp.c_get ();
   char *eobuf = buf;
 
-  if ((ret = NtQuerySystemInformation (SystemBasicInformation,
-                                      (PVOID) &sbi, sizeof sbi, NULL))
-      != STATUS_SUCCESS)
-    {
-      debug_printf ("NtQuerySystemInformation: ret %d", ret);
-      sbi.NumberProcessors = 1;
-    }
+  GetSystemInfo (&si);
 
-  SYSTEM_PROCESSOR_TIMES spt[sbi.NumberProcessors];
+  SYSTEM_PROCESSOR_TIMES spt[si.dwNumberOfProcessors];
   ret = NtQuerySystemInformation (SystemProcessorTimes, (PVOID) spt,
-                                 sizeof spt[0] * sbi.NumberProcessors, NULL);
-  interrupt_count = 0;
-  if (ret == STATUS_SUCCESS)
+                                 sizeof spt[0] * si.dwNumberOfProcessors, NULL);
+  if (!NT_SUCCESS (ret))
+    debug_printf ("NtQuerySystemInformation(SystemProcessorTimes), "
+                 "status %p", ret);
+  else
     {
       unsigned long long user_time = 0ULL, kernel_time = 0ULL, idle_time = 0ULL;
-      for (int i = 0; i < sbi.NumberProcessors; i++)
+      for (unsigned long i = 0; i < si.dwNumberOfProcessors; i++)
        {
          kernel_time += (spt[i].KernelTime.QuadPart - spt[i].IdleTime.QuadPart)
                         * HZ / 10000000ULL;
@@ -491,7 +491,7 @@ format_proc_stat (void *, char *&destbuf)
       eobuf += __small_sprintf (eobuf, "cpu %U %U %U %U\n",
                                user_time, 0ULL, kernel_time, idle_time);
       user_time = 0ULL, kernel_time = 0ULL, idle_time = 0ULL;
-      for (int i = 0; i < sbi.NumberProcessors; i++)
+      for (unsigned long i = 0; i < si.dwNumberOfProcessors; i++)
        {
          interrupt_count += spt[i].InterruptCount;
          kernel_time = (spt[i].KernelTime.QuadPart - spt[i].IdleTime.QuadPart) * HZ / 10000000ULL;
@@ -501,18 +501,29 @@ format_proc_stat (void *, char *&destbuf)
                                    user_time, 0ULL, kernel_time, idle_time);
        }
 
+      /* This fails on WOW64 with STATUS_INFO_LENGTH_MISMATCH because the
+         SYSTEM_PERFORMANCE_INFORMATION struct is bigger.  This datastructure
+        was always undocumented, but on 64 bit systems we don't know its
+        layout and content at all.  So we just let it fail and set the
+        entire structure to 0. */
       ret = NtQuerySystemInformation (SystemPerformanceInformation,
                                      (PVOID) &spi, sizeof spi, NULL);
+      if (!NT_SUCCESS (ret))
+       {
+         debug_printf ("NtQuerySystemInformation(SystemPerformanceInformation)"
+                       ", status %p", ret);
+         memset (&spi, 0, sizeof spi);
+       }
+      ret = NtQuerySystemInformation (SystemTimeOfDayInformation,
+                                     (PVOID) &stodi,
+                                     sizeof stodi, NULL);
+      if (!NT_SUCCESS (ret))
+       debug_printf ("NtQuerySystemInformation(SystemTimeOfDayInformation), "
+                     "status %p", ret);
     }
-  if (ret == STATUS_SUCCESS)
-    ret = NtQuerySystemInformation (SystemTimeOfDayInformation,
-                                   (PVOID) &stodi,
-                                   sizeof stodi, NULL);
-  if (ret != STATUS_SUCCESS)
-    {
-      debug_printf ("NtQuerySystemInformation: ret %d", ret);
-      return 0;
-    }
+  if (!NT_SUCCESS (ret))
+    return 0;
+
   pages_in = spi.PagesRead;
   pages_out = spi.PagefilePagesWritten + spi.MappedFilePagesWritten;
   /*
@@ -989,7 +1000,7 @@ format_proc_partitions (void *, char *&destbuf)
   status = NtOpenDirectoryObject (&dirhdl, DIRECTORY_QUERY, &attr);
   if (!NT_SUCCESS (status))
     {
-      debug_printf ("NtOpenDirectoryObject %x", status);
+      debug_printf ("NtOpenDirectoryObject, status %p", status);
       return 0;
     }
 
@@ -1031,7 +1042,7 @@ format_proc_partitions (void *, char *&destbuf)
                               FILE_SHARE_VALID_FLAGS, 0);
          if (!NT_SUCCESS (status))
            {
-             debug_printf ("NtOpenFile(%s) %x", devname, status);
+             debug_printf ("NtOpenFile(%s), status %p", devname, status);
              continue;
            }
        }