const long SWAPS = 6;
in C++, or
integer*8, parameter :: SWAPS = 7;
in Fortran.
The shift of 6 to 7 above is not an error; default indexing in
Fortran starts at 1, not 0.
So the function used (called getr here) has to be a C function, since it accesses a C structure. On most machines, when invoked from a Fortran subroutine, an underscore needs to be appended to the name getr in the C routine below. Interlanguage calling conventions will be covered in more detail later in the course. It is an important aspect of the computer science end of scientific computing, and only recently have Fortran/C/C++ interoperability become a formal part of the language standards.
The getr() function that I use is:
#include <sys/times.h>
#include <sys/types.h>
#include <sys/resource.h>
void getr(double *utime,
double *stime,
long counts[15])
{
/*-------------------------------------------------------------
>> Read the system time and resource usage from getrusage(),
>> and return it in a format suitable for using in a Fortran
>> routine. The fields in the array resources have the
>> interpretations that match the corresponding ones in the
>> structure rusage of /sys/resource.h:
>> maxrss = maximum resident size so far
>> ixrss = integral shared memory size
>> idrss = integral unshared data
>> isrss = integral unshared stack
>> minflt = page reclaims
>> majflt = page faults
>> nswap = swaps
>> inblock = block input operations
>> oublock = block output operations
>> msgsnd = IPC messages sent
>> msgrcv = IPC messages received
>> nsignals = signals received
>> nvcsw = voluntary context switches
>> nivcsw = involuntary context switches
>> The returned array has two additional slots for
>> possible future extensions.
-------------------------------------------------------------*/
struct rusage resources;
struct timeval rutime;
struct timeval rstime;
int who = RUSAGE_SELF;
int ierr;
int i;
ierr = getrusage (who, &resources);
/* ---------------------------------------- */
/* In case of error, return garbage values: */
/* ---------------------------------------- */
if (ierr != 0)
{ *utime = -1.0;
*stime = -1.0;
for (i = 0; i < 15; i++) counts[i] = -1;
return; }
/* ----------------------------------- */
/* Unpack structure to return as array */
/* ----------------------------------- */
*utime = (double) resources.ru_utime.tv_sec
+ 1.0e-6 * (double) resources.ru_utime.tv_usec;
*stime = (double) resources.ru_stime.tv_sec
+ 1.0e-6 * (double) resources.ru_stime.tv_usec;
counts[0] = resources.ru_maxrss; /* maximum resident set size */
counts[1] = resources.ru_ixrss; /* integral shared memory size */
counts[2] = resources.ru_idrss; /* integral unshared data size */
counts[3] = resources.ru_isrss; /* integral unshared stack size */
counts[4] = resources.ru_minflt; /* page reclaims */
counts[5] = resources.ru_majflt; /* page faults */
counts[6] = resources.ru_nswap; /* swaps */
counts[7] = resources.ru_inblock; /* block input operations */
counts[8] = resources.ru_oublock; /* block output operations */
counts[9] = resources.ru_msgsnd; /* messages sent */
counts[10] = resources.ru_msgrcv; /* messages received */
counts[11] = resources.ru_nsignals; /* signals received */
counts[12] = resources.ru_nvcsw; /* voluntary context switches */
counts[13] = resources.ru_nivcsw; /* involuntary context switches */
return; }
The the PAPI Project; or a similar universal API may become the tool of the future for accessing this kind of information. But the future is never here; it is still in the future.