summaryrefslogblamecommitdiffstats
path: root/loop.c
blob: 923a120cccb4cf299b259afcd6ac281d371631c7 (plain) (tree)


























































































                                                                               

                                                                  



                                                               
#define _GNU_SOURCE /* for cpu sets */

#include <sys/time.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>

#include <sched.h>

static int migrate_to(int target_cpu)
{
	cpu_set_t cpu_set;

	CPU_ZERO(&cpu_set);
	CPU_SET(target_cpu, &cpu_set);
	return sched_setaffinity(0, sizeof(cpu_set_t), &cpu_set);
}

static int become_fifo_task(void)
{
	struct sched_param sp;
	sp.sched_priority = sched_get_priority_max(SCHED_FIFO);
	return sched_setscheduler(0, SCHED_FIFO, &sp);
}

static int suspend(double seconds)
{
	struct timespec delay;
	delay.tv_sec = (time_t) seconds;
	delay.tv_nsec = (long) ((seconds - delay.tv_sec) * 1E9);
	return nanosleep(&delay, NULL);
}

static double cputime(void)
{
	struct timespec ts;
	int err;
	err = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts);
	if (err != 0)
		perror("clock_gettime");
	return (ts.tv_sec + 1E-9 * ts.tv_nsec);
}

static double wctime(void)
{
	struct timeval tv;
	gettimeofday(&tv, NULL);
	return (tv.tv_sec + 1E-6 * tv.tv_usec);
}

static void waste_time(double seconds)
{
	double start = cputime();

	while (start + seconds > cputime())
		;
}


int main(int argc, char** argv)
{
	int i = 1, cpu;
	double start, end;
	double delay;

	if (argc != 3) {
		fprintf(stderr, "usage: loop <cpu> <loop length (seconds)>\n");
		return 1;
	} else {
		cpu   = atoi(argv[1]);
		delay = atof(argv[2]);
	}

	if (migrate_to(cpu) != 0) {
		perror("migrate_to");
		return 1;
	}

	if (delay <= 0) {
		fprintf(stderr, "bad delay: must exceed 0 seconds\n");
		return 1;
	}

	if (become_fifo_task() != 0)
		fprintf(stderr, "cold not become SCHED_FIFO task (%m)\n");

	while (1) {
		start = wctime();
		waste_time(delay);
		end   = wctime();
		printf("%5d on P%d: loop %d took %.2f seconds \n",
		       getpid(), cpu, i++, end - start);
		suspend(delay * 4); /* about 20% utilization */
	}
	return 0;
}