18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci#include <linux/compiler.h> 38c2ecf20Sopenharmony_ci#include <linux/time64.h> 48c2ecf20Sopenharmony_ci#include <inttypes.h> 58c2ecf20Sopenharmony_ci#include <string.h> 68c2ecf20Sopenharmony_ci#include "time-utils.h" 78c2ecf20Sopenharmony_ci#include "evlist.h" 88c2ecf20Sopenharmony_ci#include "session.h" 98c2ecf20Sopenharmony_ci#include "debug.h" 108c2ecf20Sopenharmony_ci#include "tests.h" 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_cistatic bool test__parse_nsec_time(const char *str, u64 expected) 138c2ecf20Sopenharmony_ci{ 148c2ecf20Sopenharmony_ci u64 ptime; 158c2ecf20Sopenharmony_ci int err; 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci pr_debug("\nparse_nsec_time(\"%s\")\n", str); 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci err = parse_nsec_time(str, &ptime); 208c2ecf20Sopenharmony_ci if (err) { 218c2ecf20Sopenharmony_ci pr_debug("error %d\n", err); 228c2ecf20Sopenharmony_ci return false; 238c2ecf20Sopenharmony_ci } 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_ci if (ptime != expected) { 268c2ecf20Sopenharmony_ci pr_debug("Failed. ptime %" PRIu64 " expected %" PRIu64 "\n", 278c2ecf20Sopenharmony_ci ptime, expected); 288c2ecf20Sopenharmony_ci return false; 298c2ecf20Sopenharmony_ci } 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci pr_debug("%" PRIu64 "\n", ptime); 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ci return true; 348c2ecf20Sopenharmony_ci} 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_cistatic bool test__perf_time__parse_str(const char *ostr, u64 start, u64 end) 378c2ecf20Sopenharmony_ci{ 388c2ecf20Sopenharmony_ci struct perf_time_interval ptime; 398c2ecf20Sopenharmony_ci int err; 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_ci pr_debug("\nperf_time__parse_str(\"%s\")\n", ostr); 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci err = perf_time__parse_str(&ptime, ostr); 448c2ecf20Sopenharmony_ci if (err) { 458c2ecf20Sopenharmony_ci pr_debug("Error %d\n", err); 468c2ecf20Sopenharmony_ci return false; 478c2ecf20Sopenharmony_ci } 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ci if (ptime.start != start || ptime.end != end) { 508c2ecf20Sopenharmony_ci pr_debug("Failed. Expected %" PRIu64 " to %" PRIu64 "\n", 518c2ecf20Sopenharmony_ci start, end); 528c2ecf20Sopenharmony_ci return false; 538c2ecf20Sopenharmony_ci } 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ci return true; 568c2ecf20Sopenharmony_ci} 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_ci#define TEST_MAX 64 598c2ecf20Sopenharmony_ci 608c2ecf20Sopenharmony_cistruct test_data { 618c2ecf20Sopenharmony_ci const char *str; 628c2ecf20Sopenharmony_ci u64 first; 638c2ecf20Sopenharmony_ci u64 last; 648c2ecf20Sopenharmony_ci struct perf_time_interval ptime[TEST_MAX]; 658c2ecf20Sopenharmony_ci int num; 668c2ecf20Sopenharmony_ci u64 skip[TEST_MAX]; 678c2ecf20Sopenharmony_ci u64 noskip[TEST_MAX]; 688c2ecf20Sopenharmony_ci}; 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_cistatic bool test__perf_time__parse_for_ranges(struct test_data *d) 718c2ecf20Sopenharmony_ci{ 728c2ecf20Sopenharmony_ci struct evlist evlist = { 738c2ecf20Sopenharmony_ci .first_sample_time = d->first, 748c2ecf20Sopenharmony_ci .last_sample_time = d->last, 758c2ecf20Sopenharmony_ci }; 768c2ecf20Sopenharmony_ci struct perf_session session = { .evlist = &evlist }; 778c2ecf20Sopenharmony_ci struct perf_time_interval *ptime = NULL; 788c2ecf20Sopenharmony_ci int range_size, range_num; 798c2ecf20Sopenharmony_ci bool pass = false; 808c2ecf20Sopenharmony_ci int i, err; 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_ci pr_debug("\nperf_time__parse_for_ranges(\"%s\")\n", d->str); 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_ci if (strchr(d->str, '%')) 858c2ecf20Sopenharmony_ci pr_debug("first_sample_time %" PRIu64 " last_sample_time %" PRIu64 "\n", 868c2ecf20Sopenharmony_ci d->first, d->last); 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_ci err = perf_time__parse_for_ranges(d->str, &session, &ptime, &range_size, 898c2ecf20Sopenharmony_ci &range_num); 908c2ecf20Sopenharmony_ci if (err) { 918c2ecf20Sopenharmony_ci pr_debug("error %d\n", err); 928c2ecf20Sopenharmony_ci goto out; 938c2ecf20Sopenharmony_ci } 948c2ecf20Sopenharmony_ci 958c2ecf20Sopenharmony_ci if (range_size < d->num || range_num != d->num) { 968c2ecf20Sopenharmony_ci pr_debug("bad size: range_size %d range_num %d expected num %d\n", 978c2ecf20Sopenharmony_ci range_size, range_num, d->num); 988c2ecf20Sopenharmony_ci goto out; 998c2ecf20Sopenharmony_ci } 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_ci for (i = 0; i < d->num; i++) { 1028c2ecf20Sopenharmony_ci if (ptime[i].start != d->ptime[i].start || 1038c2ecf20Sopenharmony_ci ptime[i].end != d->ptime[i].end) { 1048c2ecf20Sopenharmony_ci pr_debug("bad range %d expected %" PRIu64 " to %" PRIu64 "\n", 1058c2ecf20Sopenharmony_ci i, d->ptime[i].start, d->ptime[i].end); 1068c2ecf20Sopenharmony_ci goto out; 1078c2ecf20Sopenharmony_ci } 1088c2ecf20Sopenharmony_ci } 1098c2ecf20Sopenharmony_ci 1108c2ecf20Sopenharmony_ci if (perf_time__ranges_skip_sample(ptime, d->num, 0)) { 1118c2ecf20Sopenharmony_ci pr_debug("failed to keep 0\n"); 1128c2ecf20Sopenharmony_ci goto out; 1138c2ecf20Sopenharmony_ci } 1148c2ecf20Sopenharmony_ci 1158c2ecf20Sopenharmony_ci for (i = 0; i < TEST_MAX; i++) { 1168c2ecf20Sopenharmony_ci if (d->skip[i] && 1178c2ecf20Sopenharmony_ci !perf_time__ranges_skip_sample(ptime, d->num, d->skip[i])) { 1188c2ecf20Sopenharmony_ci pr_debug("failed to skip %" PRIu64 "\n", d->skip[i]); 1198c2ecf20Sopenharmony_ci goto out; 1208c2ecf20Sopenharmony_ci } 1218c2ecf20Sopenharmony_ci if (d->noskip[i] && 1228c2ecf20Sopenharmony_ci perf_time__ranges_skip_sample(ptime, d->num, d->noskip[i])) { 1238c2ecf20Sopenharmony_ci pr_debug("failed to keep %" PRIu64 "\n", d->noskip[i]); 1248c2ecf20Sopenharmony_ci goto out; 1258c2ecf20Sopenharmony_ci } 1268c2ecf20Sopenharmony_ci } 1278c2ecf20Sopenharmony_ci 1288c2ecf20Sopenharmony_ci pass = true; 1298c2ecf20Sopenharmony_ciout: 1308c2ecf20Sopenharmony_ci free(ptime); 1318c2ecf20Sopenharmony_ci return pass; 1328c2ecf20Sopenharmony_ci} 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_ciint test__time_utils(struct test *t __maybe_unused, int subtest __maybe_unused) 1358c2ecf20Sopenharmony_ci{ 1368c2ecf20Sopenharmony_ci bool pass = true; 1378c2ecf20Sopenharmony_ci 1388c2ecf20Sopenharmony_ci pass &= test__parse_nsec_time("0", 0); 1398c2ecf20Sopenharmony_ci pass &= test__parse_nsec_time("1", 1000000000ULL); 1408c2ecf20Sopenharmony_ci pass &= test__parse_nsec_time("0.000000001", 1); 1418c2ecf20Sopenharmony_ci pass &= test__parse_nsec_time("1.000000001", 1000000001ULL); 1428c2ecf20Sopenharmony_ci pass &= test__parse_nsec_time("123456.123456", 123456123456000ULL); 1438c2ecf20Sopenharmony_ci pass &= test__parse_nsec_time("1234567.123456789", 1234567123456789ULL); 1448c2ecf20Sopenharmony_ci pass &= test__parse_nsec_time("18446744073.709551615", 1458c2ecf20Sopenharmony_ci 0xFFFFFFFFFFFFFFFFULL); 1468c2ecf20Sopenharmony_ci 1478c2ecf20Sopenharmony_ci pass &= test__perf_time__parse_str("1234567.123456789,1234567.123456789", 1488c2ecf20Sopenharmony_ci 1234567123456789ULL, 1234567123456789ULL); 1498c2ecf20Sopenharmony_ci pass &= test__perf_time__parse_str("1234567.123456789,1234567.123456790", 1508c2ecf20Sopenharmony_ci 1234567123456789ULL, 1234567123456790ULL); 1518c2ecf20Sopenharmony_ci pass &= test__perf_time__parse_str("1234567.123456789,", 1528c2ecf20Sopenharmony_ci 1234567123456789ULL, 0); 1538c2ecf20Sopenharmony_ci pass &= test__perf_time__parse_str(",1234567.123456789", 1548c2ecf20Sopenharmony_ci 0, 1234567123456789ULL); 1558c2ecf20Sopenharmony_ci pass &= test__perf_time__parse_str("0,1234567.123456789", 1568c2ecf20Sopenharmony_ci 0, 1234567123456789ULL); 1578c2ecf20Sopenharmony_ci 1588c2ecf20Sopenharmony_ci { 1598c2ecf20Sopenharmony_ci u64 b = 1234567123456789ULL; 1608c2ecf20Sopenharmony_ci struct test_data d = { 1618c2ecf20Sopenharmony_ci .str = "1234567.123456789,1234567.123456790", 1628c2ecf20Sopenharmony_ci .ptime = { {b, b + 1}, }, 1638c2ecf20Sopenharmony_ci .num = 1, 1648c2ecf20Sopenharmony_ci .skip = { b - 1, b + 2, }, 1658c2ecf20Sopenharmony_ci .noskip = { b, b + 1, }, 1668c2ecf20Sopenharmony_ci }; 1678c2ecf20Sopenharmony_ci 1688c2ecf20Sopenharmony_ci pass &= test__perf_time__parse_for_ranges(&d); 1698c2ecf20Sopenharmony_ci } 1708c2ecf20Sopenharmony_ci 1718c2ecf20Sopenharmony_ci { 1728c2ecf20Sopenharmony_ci u64 b = 1234567123456789ULL; 1738c2ecf20Sopenharmony_ci u64 c = 7654321987654321ULL; 1748c2ecf20Sopenharmony_ci u64 e = 8000000000000000ULL; 1758c2ecf20Sopenharmony_ci struct test_data d = { 1768c2ecf20Sopenharmony_ci .str = "1234567.123456789,1234567.123456790 " 1778c2ecf20Sopenharmony_ci "7654321.987654321,7654321.987654444 " 1788c2ecf20Sopenharmony_ci "8000000,8000000.000000005", 1798c2ecf20Sopenharmony_ci .ptime = { {b, b + 1}, {c, c + 123}, {e, e + 5}, }, 1808c2ecf20Sopenharmony_ci .num = 3, 1818c2ecf20Sopenharmony_ci .skip = { b - 1, b + 2, c - 1, c + 124, e - 1, e + 6 }, 1828c2ecf20Sopenharmony_ci .noskip = { b, b + 1, c, c + 123, e, e + 5 }, 1838c2ecf20Sopenharmony_ci }; 1848c2ecf20Sopenharmony_ci 1858c2ecf20Sopenharmony_ci pass &= test__perf_time__parse_for_ranges(&d); 1868c2ecf20Sopenharmony_ci } 1878c2ecf20Sopenharmony_ci 1888c2ecf20Sopenharmony_ci { 1898c2ecf20Sopenharmony_ci u64 b = 7654321ULL * NSEC_PER_SEC; 1908c2ecf20Sopenharmony_ci struct test_data d = { 1918c2ecf20Sopenharmony_ci .str = "10%/1", 1928c2ecf20Sopenharmony_ci .first = b, 1938c2ecf20Sopenharmony_ci .last = b + 100, 1948c2ecf20Sopenharmony_ci .ptime = { {b, b + 9}, }, 1958c2ecf20Sopenharmony_ci .num = 1, 1968c2ecf20Sopenharmony_ci .skip = { b - 1, b + 10, }, 1978c2ecf20Sopenharmony_ci .noskip = { b, b + 9, }, 1988c2ecf20Sopenharmony_ci }; 1998c2ecf20Sopenharmony_ci 2008c2ecf20Sopenharmony_ci pass &= test__perf_time__parse_for_ranges(&d); 2018c2ecf20Sopenharmony_ci } 2028c2ecf20Sopenharmony_ci 2038c2ecf20Sopenharmony_ci { 2048c2ecf20Sopenharmony_ci u64 b = 7654321ULL * NSEC_PER_SEC; 2058c2ecf20Sopenharmony_ci struct test_data d = { 2068c2ecf20Sopenharmony_ci .str = "10%/2", 2078c2ecf20Sopenharmony_ci .first = b, 2088c2ecf20Sopenharmony_ci .last = b + 100, 2098c2ecf20Sopenharmony_ci .ptime = { {b + 10, b + 19}, }, 2108c2ecf20Sopenharmony_ci .num = 1, 2118c2ecf20Sopenharmony_ci .skip = { b + 9, b + 20, }, 2128c2ecf20Sopenharmony_ci .noskip = { b + 10, b + 19, }, 2138c2ecf20Sopenharmony_ci }; 2148c2ecf20Sopenharmony_ci 2158c2ecf20Sopenharmony_ci pass &= test__perf_time__parse_for_ranges(&d); 2168c2ecf20Sopenharmony_ci } 2178c2ecf20Sopenharmony_ci 2188c2ecf20Sopenharmony_ci { 2198c2ecf20Sopenharmony_ci u64 b = 11223344ULL * NSEC_PER_SEC; 2208c2ecf20Sopenharmony_ci struct test_data d = { 2218c2ecf20Sopenharmony_ci .str = "10%/1,10%/2", 2228c2ecf20Sopenharmony_ci .first = b, 2238c2ecf20Sopenharmony_ci .last = b + 100, 2248c2ecf20Sopenharmony_ci .ptime = { {b, b + 9}, {b + 10, b + 19}, }, 2258c2ecf20Sopenharmony_ci .num = 2, 2268c2ecf20Sopenharmony_ci .skip = { b - 1, b + 20, }, 2278c2ecf20Sopenharmony_ci .noskip = { b, b + 8, b + 9, b + 10, b + 11, b + 12, b + 19, }, 2288c2ecf20Sopenharmony_ci }; 2298c2ecf20Sopenharmony_ci 2308c2ecf20Sopenharmony_ci pass &= test__perf_time__parse_for_ranges(&d); 2318c2ecf20Sopenharmony_ci } 2328c2ecf20Sopenharmony_ci 2338c2ecf20Sopenharmony_ci { 2348c2ecf20Sopenharmony_ci u64 b = 11223344ULL * NSEC_PER_SEC; 2358c2ecf20Sopenharmony_ci struct test_data d = { 2368c2ecf20Sopenharmony_ci .str = "10%/1,10%/3,10%/10", 2378c2ecf20Sopenharmony_ci .first = b, 2388c2ecf20Sopenharmony_ci .last = b + 100, 2398c2ecf20Sopenharmony_ci .ptime = { {b, b + 9}, {b + 20, b + 29}, { b + 90, b + 100}, }, 2408c2ecf20Sopenharmony_ci .num = 3, 2418c2ecf20Sopenharmony_ci .skip = { b - 1, b + 10, b + 19, b + 30, b + 89, b + 101 }, 2428c2ecf20Sopenharmony_ci .noskip = { b, b + 9, b + 20, b + 29, b + 90, b + 100}, 2438c2ecf20Sopenharmony_ci }; 2448c2ecf20Sopenharmony_ci 2458c2ecf20Sopenharmony_ci pass &= test__perf_time__parse_for_ranges(&d); 2468c2ecf20Sopenharmony_ci } 2478c2ecf20Sopenharmony_ci 2488c2ecf20Sopenharmony_ci pr_debug("\n"); 2498c2ecf20Sopenharmony_ci 2508c2ecf20Sopenharmony_ci return pass ? 0 : TEST_FAIL; 2518c2ecf20Sopenharmony_ci} 252