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