Blame src/benchmark.c

Packit 549fdc
/*
Packit 549fdc
 * Copyright (C) 2011-2012 Free Software Foundation, Inc.
Packit 549fdc
 *
Packit 549fdc
 * This file is part of GnuTLS.
Packit 549fdc
 *
Packit 549fdc
 * GnuTLS is free software: you can redistribute it and/or modify
Packit 549fdc
 * it under the terms of the GNU General Public License as published by
Packit 549fdc
 * the Free Software Foundation, either version 3 of the License, or
Packit 549fdc
 * (at your option) any later version.
Packit 549fdc
 *
Packit 549fdc
 * GnuTLS is distributed in the hope that it will be useful,
Packit 549fdc
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 549fdc
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit 549fdc
 * GNU General Public License for more details.
Packit 549fdc
 *
Packit 549fdc
 * You should have received a copy of the GNU General Public License
Packit 549fdc
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
Packit 549fdc
 */
Packit 549fdc
Packit 549fdc
#include <config.h>
Packit 549fdc
#include <stdio.h>
Packit 549fdc
#include <string.h>
Packit 549fdc
#include <signal.h>
Packit 549fdc
#include <sys/time.h>
Packit 549fdc
#include <time.h>
Packit 549fdc
#include <unistd.h>
Packit 549fdc
#include "benchmark.h"
Packit 549fdc
Packit 549fdc
#define BSECS 5
Packit 549fdc
Packit 549fdc
volatile int benchmark_must_finish = 0;
Packit 549fdc
Packit 549fdc
#if defined(_WIN32)
Packit 549fdc
#include <windows.h>
Packit 549fdc
static DWORD WINAPI alarm_handler(LPVOID lpParameter)
Packit 549fdc
{
Packit 549fdc
	HANDLE wtimer = *((HANDLE *) lpParameter);
Packit 549fdc
	WaitForSingleObject(wtimer, INFINITE);
Packit 549fdc
	benchmark_must_finish = 1;
Packit 549fdc
	return 0;
Packit 549fdc
}
Packit 549fdc
#else
Packit 549fdc
static void alarm_handler(int signo)
Packit 549fdc
{
Packit 549fdc
	benchmark_must_finish = 1;
Packit 549fdc
}
Packit 549fdc
#endif
Packit 549fdc
Packit 549fdc
static void
Packit 549fdc
value2human(unsigned long bytes, double time, double *data, double *speed,
Packit 549fdc
	    char *metric)
Packit 549fdc
{
Packit 549fdc
	if (bytes > 1000 && bytes < 1000 * 1000) {
Packit 549fdc
		*data = ((double) bytes) / 1000;
Packit 549fdc
		*speed = *data / time;
Packit 549fdc
		strcpy(metric, "KB");
Packit 549fdc
		return;
Packit 549fdc
	} else if (bytes >= 1000 * 1000 && bytes < 1000 * 1000 * 1000) {
Packit 549fdc
		*data = ((double) bytes) / (1000 * 1000);
Packit 549fdc
		*speed = *data / time;
Packit 549fdc
		strcpy(metric, "MB");
Packit 549fdc
		return;
Packit 549fdc
	} else if (bytes >= 1000 * 1000 * 1000) {
Packit 549fdc
		*data = ((double) bytes) / (1000 * 1000 * 1000);
Packit 549fdc
		*speed = *data / time;
Packit 549fdc
		strcpy(metric, "GB");
Packit 549fdc
		return;
Packit 549fdc
	} else {
Packit 549fdc
		*data = (double) bytes;
Packit 549fdc
		*speed = *data / time;
Packit 549fdc
		strcpy(metric, "bytes");
Packit 549fdc
		return;
Packit 549fdc
	}
Packit 549fdc
}
Packit 549fdc
Packit 549fdc
void start_benchmark(struct benchmark_st *st)
Packit 549fdc
{
Packit 549fdc
	memset(st, 0, sizeof(*st));
Packit 549fdc
#ifndef _WIN32
Packit 549fdc
	st->old_handler = signal(SIGALRM, alarm_handler);
Packit 549fdc
#endif
Packit 549fdc
	gettime(&st->start);
Packit 549fdc
	benchmark_must_finish = 0;
Packit 549fdc
Packit 549fdc
#if defined(_WIN32)
Packit 549fdc
	st->wtimer = CreateWaitableTimer(NULL, TRUE, NULL);
Packit 549fdc
	if (st->wtimer == NULL) {
Packit 549fdc
		fprintf(stderr, "error: CreateWaitableTimer %u\n",
Packit 549fdc
			GetLastError());
Packit 549fdc
		exit(1);
Packit 549fdc
	}
Packit 549fdc
	st->wthread =
Packit 549fdc
	    CreateThread(NULL, 0, alarm_handler, &st->wtimer, 0, NULL);
Packit 549fdc
	if (st->wthread == NULL) {
Packit 549fdc
		fprintf(stderr, "error: CreateThread %u\n",
Packit 549fdc
			GetLastError());
Packit 549fdc
		exit(1);
Packit 549fdc
	}
Packit 549fdc
	st->alarm_timeout.QuadPart = (BSECS) * 10000000;
Packit 549fdc
	if (SetWaitableTimer
Packit 549fdc
	    (st->wtimer, &st->alarm_timeout, 0, NULL, NULL, FALSE) == 0) {
Packit 549fdc
		fprintf(stderr, "error: SetWaitableTimer %u\n",
Packit 549fdc
			GetLastError());
Packit 549fdc
		exit(1);
Packit 549fdc
	}
Packit 549fdc
#else
Packit 549fdc
	alarm(BSECS);
Packit 549fdc
#endif
Packit 549fdc
Packit 549fdc
}
Packit 549fdc
Packit 549fdc
/* returns the elapsed time */
Packit 549fdc
double stop_benchmark(struct benchmark_st *st, const char *metric,
Packit 549fdc
		      int quiet)
Packit 549fdc
{
Packit 549fdc
	double secs;
Packit 549fdc
	unsigned long lsecs;
Packit 549fdc
	struct timespec stop;
Packit 549fdc
	double dspeed, ddata;
Packit 549fdc
	char imetric[16];
Packit 549fdc
Packit 549fdc
#if defined(_WIN32)
Packit 549fdc
	if (st->wtimer != NULL)
Packit 549fdc
		CloseHandle(st->wtimer);
Packit 549fdc
	if (st->wthread != NULL)
Packit 549fdc
		CloseHandle(st->wthread);
Packit 549fdc
#else
Packit 549fdc
	signal(SIGALRM, st->old_handler);
Packit 549fdc
#endif
Packit 549fdc
Packit 549fdc
	gettime(&stop);
Packit 549fdc
Packit 549fdc
	lsecs = (stop.tv_sec * 1000 + stop.tv_nsec / (1000 * 1000) -
Packit 549fdc
		 (st->start.tv_sec * 1000 +
Packit 549fdc
		  st->start.tv_nsec / (1000 * 1000)));
Packit 549fdc
	secs = lsecs;
Packit 549fdc
	secs /= 1000;
Packit 549fdc
Packit 549fdc
	if (metric == NULL) {	/* assume bytes/sec */
Packit 549fdc
		value2human(st->size, secs, &ddata, &dspeed, imetric);
Packit 549fdc
		if (quiet == 0)
Packit 549fdc
			printf("  Processed %.2f %s in %.2f secs: ", ddata,
Packit 549fdc
			       imetric, secs);
Packit 549fdc
		printf("%.2f %s/sec\n", dspeed, imetric);
Packit 549fdc
	} else {
Packit 549fdc
		ddata = (double) st->size;
Packit 549fdc
		dspeed = ddata / secs;
Packit 549fdc
		if (quiet == 0)
Packit 549fdc
			printf("  Processed %.2f %s in %.2f secs: ", ddata,
Packit 549fdc
			       metric, secs);
Packit 549fdc
		printf("%.2f %s/sec\n", dspeed, metric);
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	return secs;
Packit 549fdc
}