brintos

brintos / linux-shallow public Read only

0
0
Text · 4.3 KiB · edb5aca Raw
179 lines · c
1/* Measure nanosleep timer latency2 *              by: john stultz (john.stultz@linaro.org)3 *		(C) Copyright Linaro 20134 *              Licensed under the GPLv25 *6 *  To build:7 *	$ gcc nsleep-lat.c -o nsleep-lat -lrt8 *9 *   This program is free software: you can redistribute it and/or modify10 *   it under the terms of the GNU General Public License as published by11 *   the Free Software Foundation, either version 2 of the License, or12 *   (at your option) any later version.13 *14 *   This program is distributed in the hope that it will be useful,15 *   but WITHOUT ANY WARRANTY; without even the implied warranty of16 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the17 *   GNU General Public License for more details.18 */19 20#include <stdio.h>21#include <stdlib.h>22#include <time.h>23#include <sys/time.h>24#include <sys/timex.h>25#include <string.h>26#include <signal.h>27#include "../kselftest.h"28 29#define NSEC_PER_SEC 1000000000ULL30 31#define UNRESONABLE_LATENCY 40000000 /* 40ms in nanosecs */32 33 34#define CLOCK_REALTIME			035#define CLOCK_MONOTONIC			136#define CLOCK_PROCESS_CPUTIME_ID	237#define CLOCK_THREAD_CPUTIME_ID		338#define CLOCK_MONOTONIC_RAW		439#define CLOCK_REALTIME_COARSE		540#define CLOCK_MONOTONIC_COARSE		641#define CLOCK_BOOTTIME			742#define CLOCK_REALTIME_ALARM		843#define CLOCK_BOOTTIME_ALARM		944#define CLOCK_HWSPECIFIC		1045#define CLOCK_TAI			1146#define NR_CLOCKIDS			1247 48#define UNSUPPORTED 0xf00f49 50char *clockstring(int clockid)51{52	switch (clockid) {53	case CLOCK_REALTIME:54		return "CLOCK_REALTIME";55	case CLOCK_MONOTONIC:56		return "CLOCK_MONOTONIC";57	case CLOCK_PROCESS_CPUTIME_ID:58		return "CLOCK_PROCESS_CPUTIME_ID";59	case CLOCK_THREAD_CPUTIME_ID:60		return "CLOCK_THREAD_CPUTIME_ID";61	case CLOCK_MONOTONIC_RAW:62		return "CLOCK_MONOTONIC_RAW";63	case CLOCK_REALTIME_COARSE:64		return "CLOCK_REALTIME_COARSE";65	case CLOCK_MONOTONIC_COARSE:66		return "CLOCK_MONOTONIC_COARSE";67	case CLOCK_BOOTTIME:68		return "CLOCK_BOOTTIME";69	case CLOCK_REALTIME_ALARM:70		return "CLOCK_REALTIME_ALARM";71	case CLOCK_BOOTTIME_ALARM:72		return "CLOCK_BOOTTIME_ALARM";73	case CLOCK_TAI:74		return "CLOCK_TAI";75	};76	return "UNKNOWN_CLOCKID";77}78 79struct timespec timespec_add(struct timespec ts, unsigned long long ns)80{81	ts.tv_nsec += ns;82	while (ts.tv_nsec >= NSEC_PER_SEC) {83		ts.tv_nsec -= NSEC_PER_SEC;84		ts.tv_sec++;85	}86	return ts;87}88 89 90long long timespec_sub(struct timespec a, struct timespec b)91{92	long long ret = NSEC_PER_SEC * b.tv_sec + b.tv_nsec;93 94	ret -= NSEC_PER_SEC * a.tv_sec + a.tv_nsec;95	return ret;96}97 98int nanosleep_lat_test(int clockid, long long ns)99{100	struct timespec start, end, target;101	long long latency = 0;102	int i, count;103 104	target.tv_sec = ns/NSEC_PER_SEC;105	target.tv_nsec = ns%NSEC_PER_SEC;106 107	if (clock_gettime(clockid, &start))108		return UNSUPPORTED;109	if (clock_nanosleep(clockid, 0, &target, NULL))110		return UNSUPPORTED;111 112	count = 10;113 114	/* First check relative latency */115	clock_gettime(clockid, &start);116	for (i = 0; i < count; i++)117		clock_nanosleep(clockid, 0, &target, NULL);118	clock_gettime(clockid, &end);119 120	if (((timespec_sub(start, end)/count)-ns) > UNRESONABLE_LATENCY) {121		ksft_print_msg("Large rel latency: %lld ns :", (timespec_sub(start, end)/count)-ns);122		return -1;123	}124 125	/* Next check absolute latency */126	for (i = 0; i < count; i++) {127		clock_gettime(clockid, &start);128		target = timespec_add(start, ns);129		clock_nanosleep(clockid, TIMER_ABSTIME, &target, NULL);130		clock_gettime(clockid, &end);131		latency += timespec_sub(target, end);132	}133 134	if (latency/count > UNRESONABLE_LATENCY) {135		ksft_print_msg("Large abs latency: %lld ns :", latency/count);136		return -1;137	}138 139	return 0;140}141 142#define SKIPPED_CLOCK_COUNT 3143 144int main(int argc, char **argv)145{146	long long length;147	int clockid, ret;148 149	ksft_print_header();150	ksft_set_plan(NR_CLOCKIDS - CLOCK_REALTIME - SKIPPED_CLOCK_COUNT);151 152	for (clockid = CLOCK_REALTIME; clockid < NR_CLOCKIDS; clockid++) {153 154		/* Skip cputime clockids since nanosleep won't increment cputime */155		if (clockid == CLOCK_PROCESS_CPUTIME_ID ||156				clockid == CLOCK_THREAD_CPUTIME_ID ||157				clockid == CLOCK_HWSPECIFIC)158			continue;159 160		length = 10;161		while (length <= (NSEC_PER_SEC * 10)) {162			ret = nanosleep_lat_test(clockid, length);163			if (ret)164				break;165			length *= 100;166 167		}168 169		if (ret == UNSUPPORTED) {170			ksft_test_result_skip("%s\n", clockstring(clockid));171		} else {172			ksft_test_result(ret >= 0, "%s\n",173					 clockstring(clockid));174		}175	}176 177	ksft_finished();178}179