* 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.
This commit is contained in:
		| @@ -1,3 +1,13 @@ | |||||||
|  | 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> | 2009-06-08  Corinna Vinschen  <corinna@vinschen.de> | ||||||
|  |  | ||||||
| 	* fork.cc (frok::parent): Remove ancient code erroneously flushing | 	* fork.cc (frok::parent): Remove ancient code erroneously flushing | ||||||
|   | |||||||
| @@ -412,6 +412,7 @@ LoadDLLfuncEx (FindFirstVolumeA, 8, kernel32, 1) | |||||||
| LoadDLLfuncEx (FindNextVolumeA, 12, kernel32, 1) | LoadDLLfuncEx (FindNextVolumeA, 12, kernel32, 1) | ||||||
| LoadDLLfuncEx (FindVolumeClose, 4, kernel32, 1) | LoadDLLfuncEx (FindVolumeClose, 4, kernel32, 1) | ||||||
| LoadDLLfuncEx (GetConsoleWindow, 0, kernel32, 1) | LoadDLLfuncEx (GetConsoleWindow, 0, kernel32, 1) | ||||||
|  | LoadDLLfuncEx (GetSystemTimes, 12, kernel32, 1) | ||||||
| LoadDLLfuncEx (GetSystemWindowsDirectoryW, 8, kernel32, 1) | LoadDLLfuncEx (GetSystemWindowsDirectoryW, 8, kernel32, 1) | ||||||
| LoadDLLfuncEx (GetVolumeNameForVolumeMountPointA, 12, kernel32, 1) | LoadDLLfuncEx (GetVolumeNameForVolumeMountPointA, 12, kernel32, 1) | ||||||
| LoadDLLfuncEx (GetSystemDEPPolicy, 0, kernel32, 1) | LoadDLLfuncEx (GetSystemDEPPolicy, 0, kernel32, 1) | ||||||
|   | |||||||
| @@ -420,29 +420,33 @@ static _off64_t | |||||||
| format_proc_uptime (void *, char *&destbuf) | format_proc_uptime (void *, char *&destbuf) | ||||||
| { | { | ||||||
|   unsigned long long uptime = 0ULL, idle_time = 0ULL; |   unsigned long long uptime = 0ULL, idle_time = 0ULL; | ||||||
|  |  | ||||||
|   NTSTATUS ret; |   NTSTATUS ret; | ||||||
|   SYSTEM_BASIC_INFORMATION sbi; |   SYSTEM_INFO si; | ||||||
|   SYSTEM_TIME_OF_DAY_INFORMATION stodi; |   SYSTEM_TIME_OF_DAY_INFORMATION stodi; | ||||||
|   SYSTEM_PERFORMANCE_INFORMATION spi; |   SYSTEM_PERFORMANCE_INFORMATION spi; | ||||||
|  |   FILETIME idletime; | ||||||
|  |  | ||||||
|   ret = NtQuerySystemInformation (SystemBasicInformation, (PVOID) &sbi, |   GetSystemInfo (&si); | ||||||
| 				  sizeof sbi, NULL); |  | ||||||
|   if (!NT_SUCCESS (ret)) |  | ||||||
|     { |  | ||||||
|       debug_printf ("NtQuerySystemInformation: ret %d", ret); |  | ||||||
|       sbi.NumberProcessors = 1; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|   ret = NtQuerySystemInformation (SystemTimeOfDayInformation, &stodi, |   ret = NtQuerySystemInformation (SystemTimeOfDayInformation, &stodi, | ||||||
| 				  sizeof stodi, NULL); | 				  sizeof stodi, NULL); | ||||||
|   if (NT_SUCCESS (ret)) |   if (NT_SUCCESS (ret)) | ||||||
|     uptime = (stodi.CurrentTime.QuadPart - stodi.BootTime.QuadPart) / 100000ULL; |     uptime = (stodi.CurrentTime.QuadPart - stodi.BootTime.QuadPart) / 100000ULL; | ||||||
|  |   else | ||||||
|  |     debug_printf ("NtQuerySystemInformation(SystemTimeOfDayInformation), " | ||||||
|  | 		  "status %p", ret); | ||||||
|  |  | ||||||
|   ret = NtQuerySystemInformation (SystemPerformanceInformation, &spi, |   /* Can't use NtQuerySystemInformation on 64 bit systems, so we just use | ||||||
| 				  sizeof spi, NULL); |      the offical Win32 function and fall back to NtQuerySystemInformation | ||||||
|   if (NT_SUCCESS (ret)) |      on older systems. */ | ||||||
|     idle_time = (spi.IdleTime.QuadPart / sbi.NumberProcessors) / 100000ULL; |   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); |   destbuf = (char *) crealloc_abort (destbuf, 80); | ||||||
|   return __small_sprintf (destbuf, "%U.%02u %U.%02u\n", |   return __small_sprintf (destbuf, "%U.%02u %U.%02u\n", | ||||||
| @@ -459,28 +463,24 @@ format_proc_stat (void *, char *&destbuf) | |||||||
|   NTSTATUS ret; |   NTSTATUS ret; | ||||||
|   SYSTEM_PERFORMANCE_INFORMATION spi; |   SYSTEM_PERFORMANCE_INFORMATION spi; | ||||||
|   SYSTEM_TIME_OF_DAY_INFORMATION stodi; |   SYSTEM_TIME_OF_DAY_INFORMATION stodi; | ||||||
|   SYSTEM_BASIC_INFORMATION sbi; |   SYSTEM_INFO si; | ||||||
|   tmp_pathbuf tp; |   tmp_pathbuf tp; | ||||||
|  |  | ||||||
|   char *buf = tp.c_get (); |   char *buf = tp.c_get (); | ||||||
|   char *eobuf = buf; |   char *eobuf = buf; | ||||||
|  |  | ||||||
|   if ((ret = NtQuerySystemInformation (SystemBasicInformation, |   GetSystemInfo (&si); | ||||||
| 				       (PVOID) &sbi, sizeof sbi, NULL)) |  | ||||||
|       != STATUS_SUCCESS) |  | ||||||
|     { |  | ||||||
|       debug_printf ("NtQuerySystemInformation: ret %d", ret); |  | ||||||
|       sbi.NumberProcessors = 1; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|   SYSTEM_PROCESSOR_TIMES spt[sbi.NumberProcessors]; |   SYSTEM_PROCESSOR_TIMES spt[si.dwNumberOfProcessors]; | ||||||
|   ret = NtQuerySystemInformation (SystemProcessorTimes, (PVOID) spt, |   ret = NtQuerySystemInformation (SystemProcessorTimes, (PVOID) spt, | ||||||
| 				  sizeof spt[0] * sbi.NumberProcessors, NULL); | 				  sizeof spt[0] * si.dwNumberOfProcessors, NULL); | ||||||
|   interrupt_count = 0; |   if (!NT_SUCCESS (ret)) | ||||||
|   if (ret == STATUS_SUCCESS) |     debug_printf ("NtQuerySystemInformation(SystemProcessorTimes), " | ||||||
|  | 		  "status %p", ret); | ||||||
|  |   else | ||||||
|     { |     { | ||||||
|       unsigned long long user_time = 0ULL, kernel_time = 0ULL, idle_time = 0ULL; |       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) | 	  kernel_time += (spt[i].KernelTime.QuadPart - spt[i].IdleTime.QuadPart) | ||||||
| 			 * HZ / 10000000ULL; | 			 * HZ / 10000000ULL; | ||||||
| @@ -491,7 +491,7 @@ format_proc_stat (void *, char *&destbuf) | |||||||
|       eobuf += __small_sprintf (eobuf, "cpu %U %U %U %U\n", |       eobuf += __small_sprintf (eobuf, "cpu %U %U %U %U\n", | ||||||
| 				user_time, 0ULL, kernel_time, idle_time); | 				user_time, 0ULL, kernel_time, idle_time); | ||||||
|       user_time = 0ULL, kernel_time = 0ULL, idle_time = 0ULL; |       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; | 	  interrupt_count += spt[i].InterruptCount; | ||||||
| 	  kernel_time = (spt[i].KernelTime.QuadPart - spt[i].IdleTime.QuadPart) * HZ / 10000000ULL; | 	  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); | 				    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, |       ret = NtQuerySystemInformation (SystemPerformanceInformation, | ||||||
| 				      (PVOID) &spi, sizeof spi, NULL); | 				      (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) |   if (!NT_SUCCESS (ret)) | ||||||
|     ret = NtQuerySystemInformation (SystemTimeOfDayInformation, |     return 0; | ||||||
| 				    (PVOID) &stodi, |  | ||||||
| 				    sizeof stodi, NULL); |  | ||||||
|   if (ret != STATUS_SUCCESS) |  | ||||||
|     { |  | ||||||
|       debug_printf ("NtQuerySystemInformation: ret %d", ret); |  | ||||||
|       return 0; |  | ||||||
|     } |  | ||||||
|   pages_in = spi.PagesRead; |   pages_in = spi.PagesRead; | ||||||
|   pages_out = spi.PagefilePagesWritten + spi.MappedFilePagesWritten; |   pages_out = spi.PagefilePagesWritten + spi.MappedFilePagesWritten; | ||||||
|   /* |   /* | ||||||
| @@ -989,7 +1000,7 @@ format_proc_partitions (void *, char *&destbuf) | |||||||
|   status = NtOpenDirectoryObject (&dirhdl, DIRECTORY_QUERY, &attr); |   status = NtOpenDirectoryObject (&dirhdl, DIRECTORY_QUERY, &attr); | ||||||
|   if (!NT_SUCCESS (status)) |   if (!NT_SUCCESS (status)) | ||||||
|     { |     { | ||||||
|       debug_printf ("NtOpenDirectoryObject %x", status); |       debug_printf ("NtOpenDirectoryObject, status %p", status); | ||||||
|       return 0; |       return 0; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -1031,7 +1042,7 @@ format_proc_partitions (void *, char *&destbuf) | |||||||
| 			       FILE_SHARE_VALID_FLAGS, 0); | 			       FILE_SHARE_VALID_FLAGS, 0); | ||||||
| 	  if (!NT_SUCCESS (status)) | 	  if (!NT_SUCCESS (status)) | ||||||
| 	    { | 	    { | ||||||
| 	      debug_printf ("NtOpenFile(%s) %x", devname, status); | 	      debug_printf ("NtOpenFile(%s), status %p", devname, status); | ||||||
| 	      continue; | 	      continue; | ||||||
| 	    } | 	    } | ||||||
| 	} | 	} | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user