brintos

brintos / linux-shallow public Read only

0
0
Text · 4.1 KiB · df1d035 Raw
170 lines · c
1/* Make sure timers don't return early2 *              by: john stultz (johnstul@us.ibm.com)3 *		    John Stultz (john.stultz@linaro.org)4 *              (C) Copyright IBM 20125 *              (C) Copyright Linaro 2013 20156 *              Licensed under the GPLv27 *8 *  To build:9 *	$ gcc nanosleep.c -o nanosleep -lrt10 *11 *   This program is free software: you can redistribute it and/or modify12 *   it under the terms of the GNU General Public License as published by13 *   the Free Software Foundation, either version 2 of the License, or14 *   (at your option) any later version.15 *16 *   This program is distributed in the hope that it will be useful,17 *   but WITHOUT ANY WARRANTY; without even the implied warranty of18 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the19 *   GNU General Public License for more details.20 */21 22#include <errno.h>23#include <stdio.h>24#include <stdlib.h>25#include <time.h>26#include <sys/time.h>27#include <sys/timex.h>28#include <string.h>29#include <signal.h>30#include "../kselftest.h"31 32#define NSEC_PER_SEC 1000000000ULL33 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 79/* returns 1 if a <= b, 0 otherwise */80static inline int in_order(struct timespec a, struct timespec b)81{82	if (a.tv_sec < b.tv_sec)83		return 1;84	if (a.tv_sec > b.tv_sec)85		return 0;86	if (a.tv_nsec > b.tv_nsec)87		return 0;88	return 1;89}90 91struct timespec timespec_add(struct timespec ts, unsigned long long ns)92{93	ts.tv_nsec += ns;94	while (ts.tv_nsec >= NSEC_PER_SEC) {95		ts.tv_nsec -= NSEC_PER_SEC;96		ts.tv_sec++;97	}98	return ts;99}100 101int nanosleep_test(int clockid, long long ns)102{103	struct timespec now, target, rel;104 105	/* First check abs time */106	if (clock_gettime(clockid, &now))107		return UNSUPPORTED;108	target = timespec_add(now, ns);109 110	if (clock_nanosleep(clockid, TIMER_ABSTIME, &target, NULL))111		return UNSUPPORTED;112	clock_gettime(clockid, &now);113 114	if (!in_order(target, now))115		return -1;116 117	/* Second check reltime */118	clock_gettime(clockid, &now);119	rel.tv_sec = 0;120	rel.tv_nsec = 0;121	rel = timespec_add(rel, ns);122	target = timespec_add(now, ns);123	clock_nanosleep(clockid, 0, &rel, NULL);124	clock_gettime(clockid, &now);125 126	if (!in_order(target, now))127		return -1;128	return 0;129}130 131int main(int argc, char **argv)132{133	long long length;134	int clockid, ret;135 136	ksft_print_header();137	ksft_set_plan(NR_CLOCKIDS);138 139	for (clockid = CLOCK_REALTIME; clockid < NR_CLOCKIDS; clockid++) {140 141		/* Skip cputime clockids since nanosleep won't increment cputime */142		if (clockid == CLOCK_PROCESS_CPUTIME_ID ||143				clockid == CLOCK_THREAD_CPUTIME_ID ||144				clockid == CLOCK_HWSPECIFIC) {145			ksft_test_result_skip("%-31s\n", clockstring(clockid));146			continue;147		}148 149		fflush(stdout);150 151		length = 10;152		while (length <= (NSEC_PER_SEC * 10)) {153			ret = nanosleep_test(clockid, length);154			if (ret == UNSUPPORTED) {155				ksft_test_result_skip("%-31s\n", clockstring(clockid));156				goto next;157			}158			if (ret < 0) {159				ksft_test_result_fail("%-31s\n", clockstring(clockid));160				ksft_exit_fail();161			}162			length *= 100;163		}164		ksft_test_result_pass("%-31s\n", clockstring(clockid));165next:166		ret = 0;167	}168	ksft_exit_pass();169}170