/*
 * getrusage04 - accuracy of getrusage() with RUSAGE_THREAD
 *
 * This program is used for testing the following upstream commit:
 * 761b1d26df542fd5eb348837351e4d2f3bc7bffe.
 *
 * getrusage() returns cpu resource usage with accuracy of 10ms
 * when RUSAGE_THREAD is specified to the argument who. Meanwhile,
 * accuracy is 1ms when RUSAGE_SELF is specified. This bad accuracy
 * of getrusage() caused a big impact on some application which is
 * critical to accuracy of cpu usage. The upstream fix removed
 * casts to clock_t in task_u/stime(), to keep granularity of
 * cputime_t over the calculation.
 *
 * Note that the accuracy on powerpc and s390x systems is always
 * 10ms when either RUSAGE_THREAD or RUSAGE_SELF specified, so
 * this test won't be executed on those platforms.
 *
 * Copyright (C) 2011  Red Hat, Inc.
 * Copyright (C) 2013  Cyril Hrubis <chrubis@suse.cz>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of version 2 of the GNU General Public
 * License as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it would be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *
 * Further, this software is distributed without any warranty that it
 * is free of the rightful claim of any third person regarding
 * infringement or the like.  Any license provided herein, whether
 * implied or otherwise, applies only to this software file.  Patent
 * licenses, if any, provided herein do not apply to combinations of
 * this program with other software, or any other product whatsoever.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 */

#define _GNU_SOURCE
#include <sys/types.h>
#include <sys/resource.h>
#include <sys/time.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#include "test.h"
#include "safe_macros.h"
#include "lapi/posix_clocks.h"

char *TCID = "getrusage04";
int TST_TOTAL = 1;

#define RECORD_MAX    20
#define FACTOR_MAX    10

#ifndef RUSAGE_THREAD
#define RUSAGE_THREAD 1
#endif

static long BIAS_MAX;

static int opt_factor;
static char *factor_str;
static long factor_nr = 1;

option_t child_options[] = {
	{"m:", &opt_factor, &factor_str},
	{NULL, NULL, NULL}
};

static void fusage(void);
static void busyloop(long wait);
static void setup(void);
static void cleanup(void);

int main(int argc, char *argv[])
{
	struct rusage usage;
	unsigned long ulast, udelta, slast, sdelta;
	int i, lc;
	const char *msg;
	char msg_string[BUFSIZ];

	msg = parse_opts(argc, argv, child_options, fusage);
	if (msg != NULL)
		tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);

#if (__powerpc__) || (__powerpc64__) || (__s390__) || (__s390x__)
	tst_brkm(TCONF, NULL, "This test is not designed for current system");
#endif

	setup();

	if (opt_factor)
		factor_nr = SAFE_STRTOL(cleanup, factor_str, 0, FACTOR_MAX);

	tst_resm(TINFO, "Using %ld as multiply factor for max [us]time "
		 "increment (1000+%ldus)!", factor_nr, BIAS_MAX * factor_nr);

	for (lc = 0; TEST_LOOPING(lc); lc++) {
		tst_count = 0;
		i = 0;
		SAFE_GETRUSAGE(cleanup, RUSAGE_THREAD, &usage);
		tst_resm(TINFO, "utime:%12luus; stime:%12luus",
			 usage.ru_utime.tv_usec, usage.ru_stime.tv_usec);
		ulast = usage.ru_utime.tv_usec;
		slast = usage.ru_stime.tv_usec;

		while (i < RECORD_MAX) {
			SAFE_GETRUSAGE(cleanup, RUSAGE_THREAD, &usage);
			udelta = usage.ru_utime.tv_usec - ulast;
			sdelta = usage.ru_stime.tv_usec - slast;
			if (udelta > 0 || sdelta > 0) {
				i++;
				tst_resm(TINFO, "utime:%12luus; stime:%12luus",
					 usage.ru_utime.tv_usec,
					 usage.ru_stime.tv_usec);
				if (udelta > 1000 + (BIAS_MAX * factor_nr)) {
					sprintf(msg_string,
						"utime increased > %ldus:",
						1000 + BIAS_MAX * factor_nr);
					tst_brkm(TFAIL, cleanup, msg_string,
						 " delta = %luus", udelta);
				}
				if (sdelta > 1000 + (BIAS_MAX * factor_nr)) {
					sprintf(msg_string,
						"stime increased > %ldus:",
						1000 + BIAS_MAX * factor_nr);
					tst_brkm(TFAIL, cleanup, msg_string,
						 " delta = %luus", sdelta);
				}
			}
			ulast = usage.ru_utime.tv_usec;
			slast = usage.ru_stime.tv_usec;
			busyloop(100000);
		}
	}

	tst_resm(TPASS, "Test Passed");

	cleanup();
	tst_exit();
}

static void fusage(void)
{
	printf("  -m n    use n as multiply factor for max [us]time "
	       "increment (1000+(1000*n)us),\n          default value is 1\n");
}

static void busyloop(long wait)
{
	while (wait--) ;
}

/*
 * The resolution of getrusage timers currently depends on CONFIG_HZ settings,
 * as they are measured in jiffies.
 *
 * The problem is that there is no reasonable API to get either getrusage
 * timers resolution or duration of jiffie.
 *
 * Here we use clock_getres() with linux specific CLOCK_REALTIME_COARSE (added
 * in 2.6.32) which is also based on jiffies. This timer has the same
 * granularity as getrusage but it's not guaranteed and it may change in the
 * future.
 *
 * The default value for resolution was choosen to be 4ms as it corresponds to
 * CONFIG_HZ=250 which seems to be default value.
 */
static unsigned long guess_timer_resolution(void)
{
	struct timespec res;

	if (clock_getres(CLOCK_REALTIME_COARSE, &res)) {
		tst_resm(TINFO,
		        "CLOCK_REALTIME_COARSE not supported, using 4000 us");
		return 4000;
	}

	if (res.tv_nsec < 1000000 || res.tv_nsec > 10000000) {
		tst_resm(TINFO, "Unexpected CLOCK_REALTIME_COARSE resolution,"
		        " using 4000 us");
		return 4000;
	}

	tst_resm(TINFO, "Expected timers granularity is %li us",
	         res.tv_nsec / 1000);

	return res.tv_nsec / 1000;
}

static void setup(void)
{
	tst_sig(NOFORK, DEF_HANDLER, cleanup);

	if (tst_is_virt(VIRT_XEN))
		tst_brkm(TCONF, NULL, "This testcase is not supported on Xen.");

	BIAS_MAX = guess_timer_resolution();

	TEST_PAUSE;
}

static void cleanup(void)
{
}
