Blame src/benchmark.c

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