You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							239 lines
						
					
					
						
							8.4 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							239 lines
						
					
					
						
							8.4 KiB
						
					
					
				
								/**
							 | 
						|
								  @file
							 | 
						|
								
							 | 
						|
								  @ingroup util
							 | 
						|
								
							 | 
						|
								  @brief CPU statistics.
							 | 
						|
								
							 | 
						|
								  @copyright@parblock
							 | 
						|
								  Copyright (c) 1994-1998 The Regents of the Univ. of California.
							 | 
						|
								  All rights reserved.
							 | 
						|
								
							 | 
						|
								  Permission is hereby granted, without written agreement and without license
							 | 
						|
								  or royalty fees, to use, copy, modify, and distribute this software and its
							 | 
						|
								  documentation for any purpose, provided that the above copyright notice and
							 | 
						|
								  the following two paragraphs appear in all copies of this software.
							 | 
						|
								
							 | 
						|
								  IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
							 | 
						|
								  DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
							 | 
						|
								  OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
							 | 
						|
								  CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
							 | 
						|
								
							 | 
						|
								  THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
							 | 
						|
								  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
							 | 
						|
								  FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS ON AN
							 | 
						|
								  "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO PROVIDE
							 | 
						|
								  MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
							 | 
						|
								  @endparblock
							 | 
						|
								
							 | 
						|
								  @copyright@parblock
							 | 
						|
								  Copyright (c) 1999-2015, Regents of the University of Colorado
							 | 
						|
								
							 | 
						|
								  All rights reserved.
							 | 
						|
								
							 | 
						|
								  Redistribution and use in source and binary forms, with or without
							 | 
						|
								  modification, are permitted provided that the following conditions
							 | 
						|
								  are met:
							 | 
						|
								
							 | 
						|
								  Redistributions of source code must retain the above copyright
							 | 
						|
								  notice, this list of conditions and the following disclaimer.
							 | 
						|
								
							 | 
						|
								  Redistributions in binary form must reproduce the above copyright
							 | 
						|
								  notice, this list of conditions and the following disclaimer in the
							 | 
						|
								  documentation and/or other materials provided with the distribution.
							 | 
						|
								
							 | 
						|
								  Neither the name of the University of Colorado nor the names of its
							 | 
						|
								  contributors may be used to endorse or promote products derived from
							 | 
						|
								  this software without specific prior written permission.
							 | 
						|
								
							 | 
						|
								  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
							 | 
						|
								  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
							 | 
						|
								  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
							 | 
						|
								  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
							 | 
						|
								  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
							 | 
						|
								  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
							 | 
						|
								  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
							 | 
						|
								  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
							 | 
						|
								  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
							 | 
						|
								  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
							 | 
						|
								  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
							 | 
						|
								  POSSIBILITY OF SUCH DAMAGE.
							 | 
						|
								  @endparblock
							 | 
						|
								
							 | 
						|
								*/
							 | 
						|
								
							 | 
						|
								#define _BSD_SOURCE
							 | 
						|
								#include "util.h"
							 | 
						|
								
							 | 
						|
								#if HAVE_SYS_TIME_H == 1
							 | 
						|
								#include <sys/time.h>
							 | 
						|
								#endif
							 | 
						|
								#if HAVE_SYS_RESOURCE_H == 1
							 | 
						|
								#include <sys/resource.h>
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
								#ifdef BSD
							 | 
						|
								#if defined(_IBMR2)
							 | 
						|
								#define etext _etext
							 | 
						|
								#define edata _edata
							 | 
						|
								#define end _end
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
								extern int end, etext, edata;
							 | 
						|
								
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
								#ifdef _WIN32
							 | 
						|
								#include <winsock2.h>
							 | 
						|
								#include <psapi.h>
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
								/**
							 | 
						|
								   @brief Prints CPU statistics.
							 | 
						|
								
							 | 
						|
								   The amount of detail printed depends on the host operating system.
							 | 
						|
								
							 | 
						|
								*/
							 | 
						|
								void
							 | 
						|
								util_print_cpu_stats(FILE *fp)
							 | 
						|
								{
							 | 
						|
								#if HAVE_GETRUSAGE == 1 && HAVE_GETRLIMIT == 1
							 | 
						|
								    struct rusage rusage;
							 | 
						|
								    double user, system, scale;
							 | 
						|
								    long text, data;
							 | 
						|
								    struct rlimit rlp;
							 | 
						|
								    long vm_limit, vm_soft_limit;
							 | 
						|
								    char hostname[257];
							 | 
						|
								#ifdef BSD
							 | 
						|
								    long vm_text, vm_init_data, vm_uninit_data, vm_sbrk_data;
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
								    /* Get the hostname */
							 | 
						|
								    (void) gethostname(hostname, sizeof(hostname));
							 | 
						|
								    hostname[sizeof(hostname)-1] = '\0';	/* just in case */
							 | 
						|
								
							 | 
						|
								#ifdef BSD
							 | 
						|
								    /* Get the virtual memory sizes */
							 | 
						|
								    vm_text = (long) (((long) (&etext)) / 1024.0 + 0.5);
							 | 
						|
								    vm_init_data = (long) (((long) (&edata) - (long) (&etext)) / 1024.0 + 0.5);
							 | 
						|
								    vm_uninit_data = (long) (((long) (&end) - (long) (&edata)) / 1024.0 + 0.5);
							 | 
						|
								    vm_sbrk_data = (long) (((long) sbrk(0) - (long) (&end)) / 1024.0 + 0.5);
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
								    /* Get virtual memory limits */
							 | 
						|
								    (void) getrlimit(RLIMIT_DATA, &rlp);
							 | 
						|
								    vm_limit = (long) (rlp.rlim_max / 1024.0 + 0.5);
							 | 
						|
								    vm_soft_limit = (long) (rlp.rlim_cur / 1024.0 + 0.5);
							 | 
						|
								
							 | 
						|
								    /* Get usage stats */
							 | 
						|
								    (void) getrusage(RUSAGE_SELF, &rusage);
							 | 
						|
								    user = rusage.ru_utime.tv_sec + rusage.ru_utime.tv_usec * 1e-6;
							 | 
						|
								    system = rusage.ru_stime.tv_sec + rusage.ru_stime.tv_usec * 1e-6;
							 | 
						|
								    scale = (user + system)*100.0;
							 | 
						|
								    if (scale == 0.0) scale = 0.001;
							 | 
						|
								    text = (int) (rusage.ru_ixrss / scale + 0.5);
							 | 
						|
								    data = (int) ((rusage.ru_idrss + rusage.ru_isrss) / scale + 0.5);
							 | 
						|
								
							 | 
						|
								#elif defined(_WIN32)
							 | 
						|
								    char hostname[257];
							 | 
						|
								    WSADATA wsaData;
							 | 
						|
								    FILETIME creationTime, exitTime, kernelTime, userTime;
							 | 
						|
								    double user, system;
							 | 
						|
								    MEMORYSTATUSEX statex;
							 | 
						|
								    size_t vm_limit;
							 | 
						|
								    PROCESS_MEMORY_COUNTERS pmc;
							 | 
						|
								    size_t peak_working_set;
							 | 
						|
								    long page_faults;
							 | 
						|
								
							 | 
						|
								    /* Get the hostname */
							 | 
						|
								    WSAStartup(MAKEWORD(2, 2), &wsaData);
							 | 
						|
								    (void) gethostname(hostname, sizeof(hostname));
							 | 
						|
								    hostname[sizeof(hostname)-1] = '\0';	/* just in case */
							 | 
						|
								    WSACleanup();
							 | 
						|
								
							 | 
						|
								    /* Get usage stats */
							 | 
						|
								    if (GetProcessTimes(GetCurrentProcess(), &creationTime, &exitTime,
							 | 
						|
											&kernelTime, &userTime)) {
							 | 
						|
									ULARGE_INTEGER integerSystemTime, integerUserTime;
							 | 
						|
									integerUserTime.u.LowPart = userTime.dwLowDateTime;
							 | 
						|
									integerUserTime.u.HighPart = userTime.dwHighDateTime;
							 | 
						|
									user = (double) integerUserTime.QuadPart * 1e-7;
							 | 
						|
									integerSystemTime.u.LowPart = kernelTime.dwLowDateTime;
							 | 
						|
									integerSystemTime.u.HighPart = kernelTime.dwHighDateTime;
							 | 
						|
									system = (double) integerSystemTime.QuadPart * 1e-7;
							 | 
						|
								    } else {
							 | 
						|
									user = system = 0.0;
							 | 
						|
								    }
							 | 
						|
								    statex.dwLength = sizeof(statex);
							 | 
						|
								    if (GlobalMemoryStatusEx(&statex)) {
							 | 
						|
									vm_limit = (size_t) (statex.ullTotalVirtual / 1024.0 + 0.5);
							 | 
						|
								    } else {
							 | 
						|
									vm_limit = 0;
							 | 
						|
								    }
							 | 
						|
								    if (GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc))) {
							 | 
						|
									peak_working_set = (size_t) (pmc.PeakWorkingSetSize / 1024.0 + 0.5);
							 | 
						|
									page_faults = (long) pmc.PageFaultCount;
							 | 
						|
								    } else {
							 | 
						|
									peak_working_set = 0;
							 | 
						|
									page_faults = 0;
							 | 
						|
								    }
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
								#if (HAVE_GETRUSAGE == 1 && HAVE_GETRLIMIT == 1) || defined(_WIN32)
							 | 
						|
								    (void) fprintf(fp, "Runtime Statistics\n");
							 | 
						|
								    (void) fprintf(fp, "------------------\n");
							 | 
						|
								    (void) fprintf(fp, "Machine name: %s\n", hostname);
							 | 
						|
								    (void) fprintf(fp, "User time   %6.1f seconds\n", user);
							 | 
						|
								    (void) fprintf(fp, "System time %6.1f seconds\n\n", system);
							 | 
						|
								
							 | 
						|
								#if HAVE_GETRUSAGE == 1 && HAVE_GETRLIMIT == 1
							 | 
						|
								    (void) fprintf(fp, "Average resident text size       = %5ldK\n", text);
							 | 
						|
								    (void) fprintf(fp, "Average resident data+stack size = %5ldK\n", data);
							 | 
						|
								    (void) fprintf(fp, "Maximum resident size            = %5ldK\n\n",
							 | 
						|
									rusage.ru_maxrss);
							 | 
						|
								#if defined(BSD)
							 | 
						|
								    (void) fprintf(fp, "Virtual text size                = %5ldK\n",
							 | 
						|
									vm_text);
							 | 
						|
								    (void) fprintf(fp, "Virtual data size                = %5ldK\n",
							 | 
						|
									vm_init_data + vm_uninit_data + vm_sbrk_data);
							 | 
						|
								    (void) fprintf(fp, "    data size initialized        = %5ldK\n",
							 | 
						|
									vm_init_data);
							 | 
						|
								    (void) fprintf(fp, "    data size uninitialized      = %5ldK\n",
							 | 
						|
									vm_uninit_data);
							 | 
						|
								    (void) fprintf(fp, "    data size sbrk               = %5ldK\n",
							 | 
						|
									vm_sbrk_data);
							 | 
						|
								#endif
							 | 
						|
								    (void) fprintf(fp, "Virtual memory limit             = ");
							 | 
						|
								    if (rlp.rlim_cur == RLIM_INFINITY)
							 | 
						|
								        (void) fprintf(fp, "unlimited");
							 | 
						|
								    else
							 | 
						|
								        (void) fprintf(fp, "%5ldK", vm_soft_limit);
							 | 
						|
								    if (rlp.rlim_max == RLIM_INFINITY)
							 | 
						|
								        (void) fprintf(fp, " (unlimited)\n");
							 | 
						|
								    else
							 | 
						|
								        (void) fprintf(fp, " (%ldK)\n\n", vm_limit);
							 | 
						|
								
							 | 
						|
								    (void) fprintf(fp, "Major page faults = %ld\n", rusage.ru_majflt);
							 | 
						|
								    (void) fprintf(fp, "Minor page faults = %ld\n", rusage.ru_minflt);
							 | 
						|
								    (void) fprintf(fp, "Swaps = %ld\n", rusage.ru_nswap);
							 | 
						|
								    (void) fprintf(fp, "Input blocks = %ld\n", rusage.ru_inblock);
							 | 
						|
								    (void) fprintf(fp, "Output blocks = %ld\n", rusage.ru_oublock);
							 | 
						|
								    (void) fprintf(fp, "Context switch (voluntary) = %ld\n", rusage.ru_nvcsw);
							 | 
						|
								    (void) fprintf(fp, "Context switch (involuntary) = %ld\n", rusage.ru_nivcsw);
							 | 
						|
								#else
							 | 
						|
								    (void) fprintf(fp, "Maximum resident size            = ");
							 | 
						|
								    if (peak_working_set == 0)
							 | 
						|
									(void) fprintf(fp, "unavailable\n");
							 | 
						|
								    else
							 | 
						|
									(void) fprintf(fp, "%" PRIszt "K\n", peak_working_set);
							 | 
						|
								    (void) fprintf(fp, "Virtual memory limit             = ");
							 | 
						|
								    if (vm_limit == 0)
							 | 
						|
									(void) fprintf(fp, "unavailable\n");
							 | 
						|
								    else
							 | 
						|
									(void) fprintf(fp, "%5" PRIszt "K\n", vm_limit);
							 | 
						|
								    (void) fprintf(fp, "Page faults       = %ld\n", page_faults);
							 | 
						|
								#endif
							 | 
						|
								#else
							 | 
						|
								    (void) fprintf(fp, "Usage statistics not available\n");
							 | 
						|
								#endif
							 | 
						|
								}
							 |