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