hide random home http://www.cuug.ab.ca:8001/~zimmerm/ts.c.html (Einblicke ins Internet, 10/1995)

/*
Hi, could all of you out there with hot boxes please run this benchmark
and fill in the following description of the machine to the best of
your ability?  I think just posting the results will quickly converge
on the full set of machines...

	Vendor:
	Processor:
	Mhz:
	Scalarness:
	Onboard cache:
	Ecache:
	# of processors:
	OS version:
	Results:

Example:

	Vendor:		Sun
	Processor:	SPARC
	Mhz:		33
	Scalarness:	single
	Onboard cache:	none
	Ecache:		128K copy back I+D VAC
	# of cpus:	1
	OS version:	SunOS 4.1.1
	Results:	198 usecs
			(100000 context switches in 19.79 secs,
			5.05/millisec 198 microsec/switch)
Thanks.
*/

/*
 * Context switch timer.  Includes some overhead for some system calls.
 *
 * Results so far:
 *
 * 106     66Mhz snake HP-UX 9.x
 * 128     40Mhz viking SunOS 4.1.3
 * 210     33Mhz 486 386BSD 0.1
 * 212     50Mhz RIOS AIX 3.2
 *
 * New results to lm@sun.com, please
 *
 * Compile: cc -O -o ctxsig ctxsig.c
 *
 * Notes: on SunOS 4.x, it is 3 ssystem calls in the basic loop:
 *	kill, sigpause, sigcleanup
 */

#include <sys/types.h>
#include <signal.h>

#define N	50000

pid_t other;
unsigned caught;

void handler() { caught++; }

main()
{
	struct sigaction sa;
	sigset_t set;

	sa.sa_handler = handler;
	sigemptyset(&sa.sa_mask);
	sa.sa_flags = 0;
	sigaction(SIGUSR1, &sa, 0);
	sigemptyset(&set);
	sigaddset(&set, SIGUSR1);
	sigprocmask(SIG_BLOCK, &set, 0);
	sigemptyset(&set);

	if (!(other = fork())) {
		other = getppid();
		while (caught < N && (kill(other, SIGUSR1) != -1))
			sigsuspend(&set);
		kill(other, SIGUSR1);
	} else {
		start();
		while (caught < N && (kill(other, SIGUSR1) != -1))
			sigsuspend(&set);
		kill(other, SIGUSR1);
		stop();
		ptime(caught * 2);
		wait(0);
	}
}

/*
 * utilities for timing
 */
#include "stdio.h"
#include "sys/types.h"
#include "sys/time.h"

static struct timeval t1, t2;

start() {
	gettimeofday(&t1, (struct timezone *) 0);
}

stop() {
	gettimeofday(&t2, (struct timezone *) 0);
}

ptime(calls) {
	ptransfer(calls, &t1, &t2);
}

ptransfer(unsigned calls, struct timeval *t0, struct timeval *t1)
{
	struct timeval td;
	double   ms, bs;

	tvsub(&td, t1, t0);
	ms = 1000.0 * td.tv_sec + td.tv_usec / 1000.0;
#define	nz(x)	((x) == 0 ? 1 : (x))
	printf("%.0f context switches in %.2f secs, %.2f/millisec %.0f microsec/switch\n",
	    (double)calls, ms / 1000.0, (double)calls/ms, (ms * 1000) / calls);
}

tvsub(tdiff, t1, t0)
	struct timeval *tdiff, *t1, *t0;
{

	tdiff->tv_sec = t1->tv_sec - t0->tv_sec;
	if ( t0->tv_usec > t1->tv_usec ) {
		tdiff->tv_sec--; 
		tdiff->tv_usec = (1000000 - t0->tv_usec) + t1->tv_usec;
	} else
		tdiff->tv_usec = t1->tv_usec - t0->tv_usec;
	
}
/*
---
Larry McVoy			(415) 336-7627			 lm@sun.com
*/