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