162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci#include <malloc.h>
362306a36Sopenharmony_ci#include <stdlib.h>
462306a36Sopenharmony_ci#include <string.h>
562306a36Sopenharmony_ci#include <time.h>
662306a36Sopenharmony_ci#include "utils.h"
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#define SIZE 256
962306a36Sopenharmony_ci#define ITERATIONS 1000
1062306a36Sopenharmony_ci#define ITERATIONS_BENCH 100000
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ciint test_strlen(const void *s);
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci/* test all offsets and lengths */
1562306a36Sopenharmony_cistatic void test_one(char *s)
1662306a36Sopenharmony_ci{
1762306a36Sopenharmony_ci	unsigned long offset;
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci	for (offset = 0; offset < SIZE; offset++) {
2062306a36Sopenharmony_ci		int x, y;
2162306a36Sopenharmony_ci		unsigned long i;
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ci		y = strlen(s + offset);
2462306a36Sopenharmony_ci		x = test_strlen(s + offset);
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ci		if (x != y) {
2762306a36Sopenharmony_ci			printf("strlen() returned %d, should have returned %d (%p offset %ld)\n", x, y, s, offset);
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ci			for (i = offset; i < SIZE; i++)
3062306a36Sopenharmony_ci				printf("%02x ", s[i]);
3162306a36Sopenharmony_ci			printf("\n");
3262306a36Sopenharmony_ci		}
3362306a36Sopenharmony_ci	}
3462306a36Sopenharmony_ci}
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_cistatic void bench_test(char *s)
3762306a36Sopenharmony_ci{
3862306a36Sopenharmony_ci	struct timespec ts_start, ts_end;
3962306a36Sopenharmony_ci	int i;
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ci	clock_gettime(CLOCK_MONOTONIC, &ts_start);
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_ci	for (i = 0; i < ITERATIONS_BENCH; i++)
4462306a36Sopenharmony_ci		test_strlen(s);
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_ci	clock_gettime(CLOCK_MONOTONIC, &ts_end);
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ci	printf("len %3.3d : time = %.6f\n", test_strlen(s), ts_end.tv_sec - ts_start.tv_sec + (ts_end.tv_nsec - ts_start.tv_nsec) / 1e9);
4962306a36Sopenharmony_ci}
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_cistatic int testcase(void)
5262306a36Sopenharmony_ci{
5362306a36Sopenharmony_ci	char *s;
5462306a36Sopenharmony_ci	unsigned long i;
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ci	s = memalign(128, SIZE);
5762306a36Sopenharmony_ci	if (!s) {
5862306a36Sopenharmony_ci		perror("memalign");
5962306a36Sopenharmony_ci		exit(1);
6062306a36Sopenharmony_ci	}
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_ci	srandom(1);
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_ci	memset(s, 0, SIZE);
6562306a36Sopenharmony_ci	for (i = 0; i < SIZE; i++) {
6662306a36Sopenharmony_ci		char c;
6762306a36Sopenharmony_ci
6862306a36Sopenharmony_ci		do {
6962306a36Sopenharmony_ci			c = random() & 0x7f;
7062306a36Sopenharmony_ci		} while (!c);
7162306a36Sopenharmony_ci		s[i] = c;
7262306a36Sopenharmony_ci		test_one(s);
7362306a36Sopenharmony_ci	}
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_ci	for (i = 0; i < ITERATIONS; i++) {
7662306a36Sopenharmony_ci		unsigned long j;
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_ci		for (j = 0; j < SIZE; j++) {
7962306a36Sopenharmony_ci			char c;
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_ci			do {
8262306a36Sopenharmony_ci				c = random() & 0x7f;
8362306a36Sopenharmony_ci			} while (!c);
8462306a36Sopenharmony_ci			s[j] = c;
8562306a36Sopenharmony_ci		}
8662306a36Sopenharmony_ci		for (j = 0; j < sizeof(long); j++) {
8762306a36Sopenharmony_ci			s[SIZE - 1 - j] = 0;
8862306a36Sopenharmony_ci			test_one(s);
8962306a36Sopenharmony_ci		}
9062306a36Sopenharmony_ci	}
9162306a36Sopenharmony_ci
9262306a36Sopenharmony_ci	for (i = 0; i < SIZE; i++) {
9362306a36Sopenharmony_ci		char c;
9462306a36Sopenharmony_ci
9562306a36Sopenharmony_ci		do {
9662306a36Sopenharmony_ci			c = random() & 0x7f;
9762306a36Sopenharmony_ci		} while (!c);
9862306a36Sopenharmony_ci		s[i] = c;
9962306a36Sopenharmony_ci	}
10062306a36Sopenharmony_ci
10162306a36Sopenharmony_ci	bench_test(s);
10262306a36Sopenharmony_ci
10362306a36Sopenharmony_ci	s[16] = 0;
10462306a36Sopenharmony_ci	bench_test(s);
10562306a36Sopenharmony_ci
10662306a36Sopenharmony_ci	s[8] = 0;
10762306a36Sopenharmony_ci	bench_test(s);
10862306a36Sopenharmony_ci
10962306a36Sopenharmony_ci	s[4] = 0;
11062306a36Sopenharmony_ci	bench_test(s);
11162306a36Sopenharmony_ci
11262306a36Sopenharmony_ci	s[3] = 0;
11362306a36Sopenharmony_ci	bench_test(s);
11462306a36Sopenharmony_ci
11562306a36Sopenharmony_ci	s[2] = 0;
11662306a36Sopenharmony_ci	bench_test(s);
11762306a36Sopenharmony_ci
11862306a36Sopenharmony_ci	s[1] = 0;
11962306a36Sopenharmony_ci	bench_test(s);
12062306a36Sopenharmony_ci
12162306a36Sopenharmony_ci	return 0;
12262306a36Sopenharmony_ci}
12362306a36Sopenharmony_ci
12462306a36Sopenharmony_ciint main(void)
12562306a36Sopenharmony_ci{
12662306a36Sopenharmony_ci	return test_harness(testcase, "strlen");
12762306a36Sopenharmony_ci}
128