Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 #include <linux/compiler.h>
0003 #include <linux/time64.h>
0004 #include <inttypes.h>
0005 #include <string.h>
0006 #include "time-utils.h"
0007 #include "evlist.h"
0008 #include "session.h"
0009 #include "debug.h"
0010 #include "tests.h"
0011 
0012 static bool test__parse_nsec_time(const char *str, u64 expected)
0013 {
0014     u64 ptime;
0015     int err;
0016 
0017     pr_debug("\nparse_nsec_time(\"%s\")\n", str);
0018 
0019     err = parse_nsec_time(str, &ptime);
0020     if (err) {
0021         pr_debug("error %d\n", err);
0022         return false;
0023     }
0024 
0025     if (ptime != expected) {
0026         pr_debug("Failed. ptime %" PRIu64 " expected %" PRIu64 "\n",
0027              ptime, expected);
0028         return false;
0029     }
0030 
0031     pr_debug("%" PRIu64 "\n", ptime);
0032 
0033     return true;
0034 }
0035 
0036 static bool test__perf_time__parse_str(const char *ostr, u64 start, u64 end)
0037 {
0038     struct perf_time_interval ptime;
0039     int err;
0040 
0041     pr_debug("\nperf_time__parse_str(\"%s\")\n", ostr);
0042 
0043     err = perf_time__parse_str(&ptime, ostr);
0044     if (err) {
0045         pr_debug("Error %d\n", err);
0046         return false;
0047     }
0048 
0049     if (ptime.start != start || ptime.end != end) {
0050         pr_debug("Failed. Expected %" PRIu64 " to %" PRIu64 "\n",
0051              start, end);
0052         return false;
0053     }
0054 
0055     return true;
0056 }
0057 
0058 #define TEST_MAX 64
0059 
0060 struct test_data {
0061     const char *str;
0062     u64 first;
0063     u64 last;
0064     struct perf_time_interval ptime[TEST_MAX];
0065     int num;
0066     u64 skip[TEST_MAX];
0067     u64 noskip[TEST_MAX];
0068 };
0069 
0070 static bool test__perf_time__parse_for_ranges(struct test_data *d)
0071 {
0072     struct evlist evlist = {
0073         .first_sample_time = d->first,
0074         .last_sample_time = d->last,
0075     };
0076     struct perf_session session = { .evlist = &evlist };
0077     struct perf_time_interval *ptime = NULL;
0078     int range_size, range_num;
0079     bool pass = false;
0080     int i, err;
0081 
0082     pr_debug("\nperf_time__parse_for_ranges(\"%s\")\n", d->str);
0083 
0084     if (strchr(d->str, '%'))
0085         pr_debug("first_sample_time %" PRIu64 " last_sample_time %" PRIu64 "\n",
0086              d->first, d->last);
0087 
0088     err = perf_time__parse_for_ranges(d->str, &session, &ptime, &range_size,
0089                       &range_num);
0090     if (err) {
0091         pr_debug("error %d\n", err);
0092         goto out;
0093     }
0094 
0095     if (range_size < d->num || range_num != d->num) {
0096         pr_debug("bad size: range_size %d range_num %d expected num %d\n",
0097              range_size, range_num, d->num);
0098         goto out;
0099     }
0100 
0101     for (i = 0; i < d->num; i++) {
0102         if (ptime[i].start != d->ptime[i].start ||
0103             ptime[i].end != d->ptime[i].end) {
0104             pr_debug("bad range %d expected %" PRIu64 " to %" PRIu64 "\n",
0105                  i, d->ptime[i].start, d->ptime[i].end);
0106             goto out;
0107         }
0108     }
0109 
0110     if (perf_time__ranges_skip_sample(ptime, d->num, 0)) {
0111         pr_debug("failed to keep 0\n");
0112         goto out;
0113     }
0114 
0115     for (i = 0; i < TEST_MAX; i++) {
0116         if (d->skip[i] &&
0117             !perf_time__ranges_skip_sample(ptime, d->num, d->skip[i])) {
0118             pr_debug("failed to skip %" PRIu64 "\n", d->skip[i]);
0119             goto out;
0120         }
0121         if (d->noskip[i] &&
0122             perf_time__ranges_skip_sample(ptime, d->num, d->noskip[i])) {
0123             pr_debug("failed to keep %" PRIu64 "\n", d->noskip[i]);
0124             goto out;
0125         }
0126     }
0127 
0128     pass = true;
0129 out:
0130     free(ptime);
0131     return pass;
0132 }
0133 
0134 static int test__time_utils(struct test_suite *t __maybe_unused, int subtest __maybe_unused)
0135 {
0136     bool pass = true;
0137 
0138     pass &= test__parse_nsec_time("0", 0);
0139     pass &= test__parse_nsec_time("1", 1000000000ULL);
0140     pass &= test__parse_nsec_time("0.000000001", 1);
0141     pass &= test__parse_nsec_time("1.000000001", 1000000001ULL);
0142     pass &= test__parse_nsec_time("123456.123456", 123456123456000ULL);
0143     pass &= test__parse_nsec_time("1234567.123456789", 1234567123456789ULL);
0144     pass &= test__parse_nsec_time("18446744073.709551615",
0145                       0xFFFFFFFFFFFFFFFFULL);
0146 
0147     pass &= test__perf_time__parse_str("1234567.123456789,1234567.123456789",
0148                        1234567123456789ULL, 1234567123456789ULL);
0149     pass &= test__perf_time__parse_str("1234567.123456789,1234567.123456790",
0150                        1234567123456789ULL, 1234567123456790ULL);
0151     pass &= test__perf_time__parse_str("1234567.123456789,",
0152                        1234567123456789ULL, 0);
0153     pass &= test__perf_time__parse_str(",1234567.123456789",
0154                        0, 1234567123456789ULL);
0155     pass &= test__perf_time__parse_str("0,1234567.123456789",
0156                        0, 1234567123456789ULL);
0157 
0158     {
0159         u64 b = 1234567123456789ULL;
0160         struct test_data d = {
0161             .str   = "1234567.123456789,1234567.123456790",
0162             .ptime = { {b, b + 1}, },
0163             .num = 1,
0164             .skip = { b - 1, b + 2, },
0165             .noskip = { b, b + 1, },
0166         };
0167 
0168         pass &= test__perf_time__parse_for_ranges(&d);
0169     }
0170 
0171     {
0172         u64 b = 1234567123456789ULL;
0173         u64 c = 7654321987654321ULL;
0174         u64 e = 8000000000000000ULL;
0175         struct test_data d = {
0176             .str   = "1234567.123456789,1234567.123456790 "
0177                  "7654321.987654321,7654321.987654444 "
0178                  "8000000,8000000.000000005",
0179             .ptime = { {b, b + 1}, {c, c + 123}, {e, e + 5}, },
0180             .num = 3,
0181             .skip = { b - 1, b + 2, c - 1, c + 124, e - 1, e + 6 },
0182             .noskip = { b, b + 1, c, c + 123, e, e + 5 },
0183         };
0184 
0185         pass &= test__perf_time__parse_for_ranges(&d);
0186     }
0187 
0188     {
0189         u64 b = 7654321ULL * NSEC_PER_SEC;
0190         struct test_data d = {
0191             .str    = "10%/1",
0192             .first  = b,
0193             .last   = b + 100,
0194             .ptime  = { {b, b + 9}, },
0195             .num    = 1,
0196             .skip   = { b - 1, b + 10, },
0197             .noskip = { b, b + 9, },
0198         };
0199 
0200         pass &= test__perf_time__parse_for_ranges(&d);
0201     }
0202 
0203     {
0204         u64 b = 7654321ULL * NSEC_PER_SEC;
0205         struct test_data d = {
0206             .str    = "10%/2",
0207             .first  = b,
0208             .last   = b + 100,
0209             .ptime  = { {b + 10, b + 19}, },
0210             .num    = 1,
0211             .skip   = { b + 9, b + 20, },
0212             .noskip = { b + 10, b + 19, },
0213         };
0214 
0215         pass &= test__perf_time__parse_for_ranges(&d);
0216     }
0217 
0218     {
0219         u64 b = 11223344ULL * NSEC_PER_SEC;
0220         struct test_data d = {
0221             .str    = "10%/1,10%/2",
0222             .first  = b,
0223             .last   = b + 100,
0224             .ptime  = { {b, b + 9}, {b + 10, b + 19}, },
0225             .num    = 2,
0226             .skip   = { b - 1, b + 20, },
0227             .noskip = { b, b + 8, b + 9, b + 10, b + 11, b + 12, b + 19, },
0228         };
0229 
0230         pass &= test__perf_time__parse_for_ranges(&d);
0231     }
0232 
0233     {
0234         u64 b = 11223344ULL * NSEC_PER_SEC;
0235         struct test_data d = {
0236             .str    = "10%/1,10%/3,10%/10",
0237             .first  = b,
0238             .last   = b + 100,
0239             .ptime  = { {b, b + 9}, {b + 20, b + 29}, { b + 90, b + 100}, },
0240             .num    = 3,
0241             .skip   = { b - 1, b + 10, b + 19, b + 30, b + 89, b + 101 },
0242             .noskip = { b, b + 9, b + 20, b + 29, b + 90, b + 100},
0243         };
0244 
0245         pass &= test__perf_time__parse_for_ranges(&d);
0246     }
0247 
0248     pr_debug("\n");
0249 
0250     return pass ? 0 : TEST_FAIL;
0251 }
0252 
0253 DEFINE_SUITE("time utils", time_utils);