1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * tools/testing/selftests/kvm/lib/test_util.c
4  *
5  * Copyright (C) 2020, Google LLC.
6  */
7 #include <stdlib.h>
8 #include <ctype.h>
9 #include <limits.h>
10 #include <assert.h>
11 #include "test_util.h"
12 
13 /*
14  * Parses "[0-9]+[kmgt]?".
15  */
16 size_t parse_size(const char *size)
17 {
18 	size_t base;
19 	char *scale;
20 	int shift = 0;
21 
22 	TEST_ASSERT(size && isdigit(size[0]), "Need at least one digit in '%s'", size);
23 
24 	base = strtoull(size, &scale, 0);
25 
26 	TEST_ASSERT(base != ULLONG_MAX, "Overflow parsing size!");
27 
28 	switch (tolower(*scale)) {
29 	case 't':
30 		shift = 40;
31 		break;
32 	case 'g':
33 		shift = 30;
34 		break;
35 	case 'm':
36 		shift = 20;
37 		break;
38 	case 'k':
39 		shift = 10;
40 		break;
41 	case 'b':
42 	case '\0':
43 		shift = 0;
44 		break;
45 	default:
46 		TEST_ASSERT(false, "Unknown size letter %c", *scale);
47 	}
48 
49 	TEST_ASSERT((base << shift) >> shift == base, "Overflow scaling size!");
50 
51 	return base << shift;
52 }
53 
54 int64_t timespec_to_ns(struct timespec ts)
55 {
56 	return (int64_t)ts.tv_nsec + 1000000000LL * (int64_t)ts.tv_sec;
57 }
58 
59 struct timespec timespec_add_ns(struct timespec ts, int64_t ns)
60 {
61 	struct timespec res;
62 
63 	res.tv_nsec = ts.tv_nsec + ns;
64 	res.tv_sec = ts.tv_sec + res.tv_nsec / 1000000000LL;
65 	res.tv_nsec %= 1000000000LL;
66 
67 	return res;
68 }
69 
70 struct timespec timespec_add(struct timespec ts1, struct timespec ts2)
71 {
72 	int64_t ns1 = timespec_to_ns(ts1);
73 	int64_t ns2 = timespec_to_ns(ts2);
74 	return timespec_add_ns((struct timespec){0}, ns1 + ns2);
75 }
76 
77 struct timespec timespec_sub(struct timespec ts1, struct timespec ts2)
78 {
79 	int64_t ns1 = timespec_to_ns(ts1);
80 	int64_t ns2 = timespec_to_ns(ts2);
81 	return timespec_add_ns((struct timespec){0}, ns1 - ns2);
82 }
83 
84 void print_skip(const char *fmt, ...)
85 {
86 	va_list ap;
87 
88 	assert(fmt);
89 	va_start(ap, fmt);
90 	vprintf(fmt, ap);
91 	va_end(ap);
92 	puts(", skipping test");
93 }
94