brintos

brintos / linux-shallow public Read only

0
0
Text · 2.5 KiB · 74365a5 Raw
120 lines · c
1// SPDX-License-Identifier: GPL-2.02 3#include <subcmd/parse-options.h>4#include <stdio.h>5#include <time.h>6#include <strings.h>7#include <linux/time64.h>8#include "debug.h"9#include "clockid.h"10#include "record.h"11 12struct clockid_map {13	const char *name;14	int clockid;15};16 17#define CLOCKID_MAP(n, c)	\18	{ .name = n, .clockid = (c), }19 20#define CLOCKID_END	{ .name = NULL, }21 22 23/*24 * Add the missing ones, we need to build on many distros...25 */26#ifndef CLOCK_MONOTONIC_RAW27#define CLOCK_MONOTONIC_RAW 428#endif29#ifndef CLOCK_BOOTTIME30#define CLOCK_BOOTTIME 731#endif32#ifndef CLOCK_TAI33#define CLOCK_TAI 1134#endif35 36static const struct clockid_map clockids[] = {37	/* available for all events, NMI safe */38	CLOCKID_MAP("monotonic", CLOCK_MONOTONIC),39	CLOCKID_MAP("monotonic_raw", CLOCK_MONOTONIC_RAW),40 41	/* available for some events */42	CLOCKID_MAP("realtime", CLOCK_REALTIME),43	CLOCKID_MAP("boottime", CLOCK_BOOTTIME),44	CLOCKID_MAP("tai", CLOCK_TAI),45 46	/* available for the lazy */47	CLOCKID_MAP("mono", CLOCK_MONOTONIC),48	CLOCKID_MAP("raw", CLOCK_MONOTONIC_RAW),49	CLOCKID_MAP("real", CLOCK_REALTIME),50	CLOCKID_MAP("boot", CLOCK_BOOTTIME),51 52	CLOCKID_END,53};54 55static int get_clockid_res(clockid_t clk_id, u64 *res_ns)56{57	struct timespec res;58 59	*res_ns = 0;60	if (!clock_getres(clk_id, &res))61		*res_ns = res.tv_nsec + res.tv_sec * NSEC_PER_SEC;62	else63		pr_warning("WARNING: Failed to determine specified clock resolution.\n");64 65	return 0;66}67 68int parse_clockid(const struct option *opt, const char *str, int unset)69{70	struct record_opts *opts = (struct record_opts *)opt->value;71	const struct clockid_map *cm;72	const char *ostr = str;73 74	if (unset) {75		opts->use_clockid = 0;76		return 0;77	}78 79	/* no arg passed */80	if (!str)81		return 0;82 83	/* no setting it twice */84	if (opts->use_clockid)85		return -1;86 87	opts->use_clockid = true;88 89	/* if its a number, we're done */90	if (sscanf(str, "%d", &opts->clockid) == 1)91		return get_clockid_res(opts->clockid, &opts->clockid_res_ns);92 93	/* allow a "CLOCK_" prefix to the name */94	if (!strncasecmp(str, "CLOCK_", 6))95		str += 6;96 97	for (cm = clockids; cm->name; cm++) {98		if (!strcasecmp(str, cm->name)) {99			opts->clockid = cm->clockid;100			return get_clockid_res(opts->clockid,101					       &opts->clockid_res_ns);102		}103	}104 105	opts->use_clockid = false;106	ui__warning("unknown clockid %s, check man page\n", ostr);107	return -1;108}109 110const char *clockid_name(clockid_t clk_id)111{112	const struct clockid_map *cm;113 114	for (cm = clockids; cm->name; cm++) {115		if (cm->clockid == clk_id)116			return cm->name;117	}118	return "(not found)";119}120