*BSD News Article 73174


Return to BSD News archive

Path: euryale.cc.adfa.oz.au!newshost.anu.edu.au!harbinger.cc.monash.edu.au!news.mira.net.au!inquo!news.uoregon.edu!hunter.premier.net!news.mathworks.com!newsfeed.internetmci.com!panix!not-for-mail
From: pcg@panix.com (Paul Gallagher)
Newsgroups: comp.unix.bsd.freebsd.misc
Subject: Help! negative values from getrusage - time goes backwards
Date: 8 Jul 1996 21:31:06 -0400
Organization: PANIX Public Access Internet and Unix, NYC
Lines: 101
Message-ID: <4rscoq$3tf@panix2.panix.com>
NNTP-Posting-Host: panix2.panix.com

The getrusage system call sometimes returns values for the CPU time
used that go backwards. I'm running FreeBSD 2.1.0 on a Pentium.

My professor thinks it might be a problem in the assembly code
for microtime in kern_clock.c inside the kernel.

Paul
pcg@panix.com

The code is:


#include <sys/time.h> /* for getrusage */
#include <sys/resource.h> /* for getrusage */
#include <unistd.h>

int getrusage( int, struct rusage *);
int printf();

char * status;

long iterations = 100;

struct rusage *rusage;

void calculate(char *name, struct rusage *bef, struct rusage *aft, 
long iter){

	long	smsec2;
	long	ssec1;
	long	ssec2;
	long	umsec2;
	long	usec1;
	long	usec2;
	long    smsec1;
	long    umsec1;
	long u1, u2, s1, s2;

	struct rusage before = *bef;
	struct rusage after = *aft;
	long usertime, systemtime;
	printf("\n");
	ssec1 = after.ru_stime.tv_sec;
	ssec2  =  before.ru_stime.tv_sec;
	smsec1 = after.ru_stime.tv_usec;
	smsec2 = before.ru_stime.tv_usec;
	usec1 = after.ru_utime.tv_sec;
	usec2  =  before.ru_utime.tv_sec;
	umsec1 = after.ru_utime.tv_usec;
	umsec2 = before.ru_utime.tv_usec;
	printf("system seconds (after, iterations) = %ld \n", ssec1);
	printf("system seconds (before) = %ld \n", ssec2);
	printf("system microseconds (after, iterations) = %ld \n", smsec1);
	printf("system microseconds (before) = %ld \n", smsec2);
	printf("user seconds (after, iterations) = %ld \n", usec1);
	printf("user microseconds (after, iterations) = %ld \n", umsec1);
	printf("user seconds (before) = %ld \n", usec2);
	printf("user microseconds (before) = %ld \n", umsec2);
	u1 = 1000000*after.ru_utime.tv_sec +  after.ru_utime.tv_usec;
	u2 = 1000000*before.ru_utime.tv_sec +  before.ru_utime.tv_usec;
	s1 = 1000000*after.ru_stime.tv_sec +  after.ru_stime.tv_usec;
	s2 = 1000000*before.ru_stime.tv_sec +  before.ru_stime.tv_usec;
	usertime = u1 - u2;
	systemtime = s1 - s2;
	printf("measurement: %s  %ld  %ld  %ld \n", name, iterations, usertime, systemtime);

	printf("\n");

}

int main() {

	int pid;
	long i;
	struct rusage before;
	struct rusage after;

	if (getrusage(RUSAGE_SELF, &before) < 0) {
		perror("getrusage");
		exit(1);
	}
	i = iterations;
	while (i>0) {
		pid = vfork();
		if (pid != 0) { /* parent */
			if (wait(&status) == -1) exit(1);
		}
		else {
			_exit(1);
		}
		i--;
	}
	if (getrusage(RUSAGE_SELF, &after) < 0) {
		perror("getrusage");
		exit(1);
	}
	calculate("vfork", &before, &after, iterations);

	return 0;
}