This is the mail archive of the cygwin-patches mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix /proc/meminfo and /proc/swaps for >4GB


As promised, this patch ports the /proc/meminfo code to use sysinfo(2),
and fixes the case where RAM or swap space totals more than 4GB.  It
also fixes the /proc/swaps code for paging files larger than 4GB.

For example:

$ cat /proc/meminfo
            total:         used:         free:
Mem:     4293058560    1828151296    2464907264
Swap:   12884901888      14680064   12870221824
MemTotal:        4192440 kB
MemFree:         2407136 kB
MemShared:             0 kB
HighTotal:             0 kB
HighFree:              0 kB
LowTotal:        4192440 kB
LowFree:         2407136 kB
SwapTotal:      12582912 kB
SwapFree:       12568576 kB

$ cat /proc/swaps
Filename				Type		Size	Used	Priority
/cygdrive/c/pagefile.sys                file            8388608 8192
0
/cygdrive/d/pagefile.sys                file            4194304 6144
0

Patch attached.


Yaakov

2011-05-06  Yaakov Selkowitz  <yselkowitz@...>

	* fhandler_proc.cc (format_proc_meminfo): Rewrite to use sysinfo().
	Support RAM and swap space larger than 4GB.
	(format_proc_swaps): Support paging files larger than 4GB.

Index: fhandler_proc.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/fhandler_proc.cc,v
retrieving revision 1.102
diff -u -r1.102 fhandler_proc.cc
--- fhandler_proc.cc	19 Apr 2011 08:39:38 -0000	1.102
+++ fhandler_proc.cc	6 May 2011 04:24:33 -0000
@@ -24,6 +24,7 @@
 #include "tls_pbuf.h"
 #include <sys/utsname.h>
 #include <sys/param.h>
+#include <sys/sysinfo.h>
 #include "ntdll.h"
 #include <winioctl.h>
 #include <wchar.h>
@@ -402,63 +403,28 @@
 static _off64_t
 format_proc_meminfo (void *, char *&destbuf)
 {
-  unsigned long mem_total = 0UL, mem_free = 0UL, swap_total = 0UL,
-		swap_free = 0UL;
-  MEMORYSTATUS memory_status;
-  GlobalMemoryStatus (&memory_status);
-  mem_total = memory_status.dwTotalPhys;
-  mem_free = memory_status.dwAvailPhys;
-  PSYSTEM_PAGEFILE_INFORMATION spi = NULL;
-  ULONG size = 512;
-  NTSTATUS ret = STATUS_SUCCESS;
+  unsigned long long mem_total, mem_free, swap_total, swap_free;
+  struct sysinfo info;
+
+  sysinfo (&info);
+  mem_total = (unsigned long long) info.totalram * info.mem_unit;
+  mem_free = (unsigned long long) info.freeram * info.mem_unit;
+  swap_total = (unsigned long long) info.totalswap * info.mem_unit;
+  swap_free = (unsigned long long) info.freeswap * info.mem_unit;
 
-  spi = (PSYSTEM_PAGEFILE_INFORMATION) malloc (size);
-  if (spi)
-    {
-      ret = NtQuerySystemInformation (SystemPagefileInformation, (PVOID) spi,
-				      size, &size);
-      if (ret == STATUS_INFO_LENGTH_MISMATCH)
-	{
-	  free (spi);
-	  spi = (PSYSTEM_PAGEFILE_INFORMATION) malloc (size);
-	  if (spi)
-	    ret = NtQuerySystemInformation (SystemPagefileInformation,
-					    (PVOID) spi, size, &size);
-	}
-    }
-  if (!spi || ret || (!ret && GetLastError () == ERROR_PROC_NOT_FOUND))
-    {
-      swap_total = memory_status.dwTotalPageFile - mem_total;
-      swap_free = memory_status.dwAvailPageFile - mem_total;
-    }
-  else
-    {
-      PSYSTEM_PAGEFILE_INFORMATION spp = spi;
-      do
-	{
-	  swap_total += spp->CurrentSize * getsystempagesize ();
-	  swap_free += (spp->CurrentSize - spp->TotalUsed)
-		       * getsystempagesize ();
-	}
-      while (spp->NextEntryOffset
-	     && (spp = (PSYSTEM_PAGEFILE_INFORMATION)
-			   ((char *) spp + spp->NextEntryOffset)));
-    }
-  if (spi)
-    free (spi);
   destbuf = (char *) crealloc_abort (destbuf, 512);
-  return __small_sprintf (destbuf, "         total:      used:      free:\n"
-				   "Mem:  %10lu %10lu %10lu\n"
-				   "Swap: %10lu %10lu %10lu\n"
-				   "MemTotal:     %10lu kB\n"
-				   "MemFree:      %10lu kB\n"
+  return sprintf (destbuf, "            total:         used:         free:\n"
+				   "Mem:  %13llu %13llu %13llu\n"
+				   "Swap: %13llu %13llu %13llu\n"
+				   "MemTotal:     %10llu kB\n"
+				   "MemFree:      %10llu kB\n"
 				   "MemShared:             0 kB\n"
 				   "HighTotal:             0 kB\n"
 				   "HighFree:              0 kB\n"
-				   "LowTotal:     %10lu kB\n"
-				   "LowFree:      %10lu kB\n"
-				   "SwapTotal:    %10lu kB\n"
-				   "SwapFree:     %10lu kB\n",
+				   "LowTotal:     %10llu kB\n"
+				   "LowFree:      %10llu kB\n"
+				   "SwapTotal:    %10llu kB\n"
+				   "SwapFree:     %10llu kB\n",
 				   mem_total, mem_total - mem_free, mem_free,
 				   swap_total, swap_total - swap_free, swap_free,
 				   mem_total >> 10, mem_free >> 10,
@@ -1298,7 +1264,7 @@
 static _off64_t
 format_proc_swaps (void *, char *&destbuf)
 {
-  unsigned long total = 0UL, used = 0UL;
+  unsigned long long total = 0ULL, used = 0ULL;
   char *filename = NULL;
   ssize_t filename_len;
   PSYSTEM_PAGEFILE_INFORMATION spi = NULL;
@@ -1332,14 +1298,14 @@
       PSYSTEM_PAGEFILE_INFORMATION spp = spi;
       do
 	{
-	  total = spp->CurrentSize * getsystempagesize ();
-	  used = spp->TotalUsed * getsystempagesize ();
+	  total = (unsigned long long) spp->CurrentSize * getsystempagesize ();
+	  used = (unsigned long long) spp->TotalUsed * getsystempagesize ();
 
 	  filename_len = cygwin_conv_path (CCP_WIN_W_TO_POSIX, spp->FileName.Buffer, filename, 0);
 	  filename = (char *) malloc (filename_len);
 	  cygwin_conv_path (CCP_WIN_W_TO_POSIX, spp->FileName.Buffer, filename, filename_len);
 
-	  bufptr += sprintf (bufptr, "%-40s%-16s%-8ld%-8ld%-8d\n",
+	  bufptr += sprintf (bufptr, "%-40s%-16s%-8llu%-8llu%-8d\n",
 	                     filename, "file", total >> 10, used >> 10, 0);
 	}
       while (spp->NextEntryOffset

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]