aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristophe Leroy <christophe.leroy@c-s.fr>2018-08-01 05:01:12 -0400
committerMichael Ellerman <mpe@ellerman.id.au>2018-08-07 07:49:30 -0400
commitf0abbfd89fed4abd8301b35fbf65a26d85b16e7f (patch)
tree408b80cf6f30bac7f4723a8ce30a3bc5ae5e215c
parent1bb07b593adc1934a526eb04acfe8bf786decfd2 (diff)
selftests/powerpc: Add test for strlen()
This patch adds a test for strlen() string.c contains a copy of strlen() from lib/string.c The test first tests the correctness of strlen() by comparing the result with libc strlen(). It tests all cases of alignment. It them tests the duration of an aligned strlen() on a 4 bytes string, on a 16 bytes string and on a 256 bytes string. Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr> [mpe: Drop change log from copy of string.c] Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
-rw-r--r--tools/testing/selftests/powerpc/stringloops/Makefile4
-rw-r--r--tools/testing/selftests/powerpc/stringloops/string.c21
-rw-r--r--tools/testing/selftests/powerpc/stringloops/strlen.c127
3 files changed, 151 insertions, 1 deletions
diff --git a/tools/testing/selftests/powerpc/stringloops/Makefile b/tools/testing/selftests/powerpc/stringloops/Makefile
index b682be18dc66..31499587b483 100644
--- a/tools/testing/selftests/powerpc/stringloops/Makefile
+++ b/tools/testing/selftests/powerpc/stringloops/Makefile
@@ -6,7 +6,7 @@ EXTRA_SOURCES := ../harness.c
6 6
7build_32bit = $(shell if ($(CC) $(CFLAGS) -m32 -o /dev/null memcmp.c >/dev/null 2>&1) then echo "1"; fi) 7build_32bit = $(shell if ($(CC) $(CFLAGS) -m32 -o /dev/null memcmp.c >/dev/null 2>&1) then echo "1"; fi)
8 8
9TEST_GEN_PROGS := memcmp_64 9TEST_GEN_PROGS := memcmp_64 strlen
10 10
11$(OUTPUT)/memcmp_64: memcmp.c 11$(OUTPUT)/memcmp_64: memcmp.c
12$(OUTPUT)/memcmp_64: CFLAGS += -m64 -maltivec 12$(OUTPUT)/memcmp_64: CFLAGS += -m64 -maltivec
@@ -18,6 +18,8 @@ $(OUTPUT)/memcmp_32: CFLAGS += -m32
18TEST_GEN_PROGS += memcmp_32 18TEST_GEN_PROGS += memcmp_32
19endif 19endif
20 20
21$(OUTPUT)/strlen: strlen.c string.c
22
21ASFLAGS = $(CFLAGS) 23ASFLAGS = $(CFLAGS)
22 24
23include ../../lib.mk 25include ../../lib.mk
diff --git a/tools/testing/selftests/powerpc/stringloops/string.c b/tools/testing/selftests/powerpc/stringloops/string.c
new file mode 100644
index 000000000000..45e7775415c7
--- /dev/null
+++ b/tools/testing/selftests/powerpc/stringloops/string.c
@@ -0,0 +1,21 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copied from linux/lib/string.c
4 *
5 * Copyright (C) 1991, 1992 Linus Torvalds
6 */
7
8#include <stddef.h>
9
10/**
11 * strlen - Find the length of a string
12 * @s: The string to be sized
13 */
14size_t test_strlen(const char *s)
15{
16 const char *sc;
17
18 for (sc = s; *sc != '\0'; ++sc)
19 /* nothing */;
20 return sc - s;
21}
diff --git a/tools/testing/selftests/powerpc/stringloops/strlen.c b/tools/testing/selftests/powerpc/stringloops/strlen.c
new file mode 100644
index 000000000000..9055ebc484d0
--- /dev/null
+++ b/tools/testing/selftests/powerpc/stringloops/strlen.c
@@ -0,0 +1,127 @@
1// SPDX-License-Identifier: GPL-2.0
2#include <malloc.h>
3#include <stdlib.h>
4#include <string.h>
5#include <time.h>
6#include "utils.h"
7
8#define SIZE 256
9#define ITERATIONS 1000
10#define ITERATIONS_BENCH 100000
11
12int test_strlen(const void *s);
13
14/* test all offsets and lengths */
15static void test_one(char *s)
16{
17 unsigned long offset;
18
19 for (offset = 0; offset < SIZE; offset++) {
20 int x, y;
21 unsigned long i;
22
23 y = strlen(s + offset);
24 x = test_strlen(s + offset);
25
26 if (x != y) {
27 printf("strlen() returned %d, should have returned %d (%p offset %ld)\n", x, y, s, offset);
28
29 for (i = offset; i < SIZE; i++)
30 printf("%02x ", s[i]);
31 printf("\n");
32 }
33 }
34}
35
36static void bench_test(char *s)
37{
38 struct timespec ts_start, ts_end;
39 int i;
40
41 clock_gettime(CLOCK_MONOTONIC, &ts_start);
42
43 for (i = 0; i < ITERATIONS_BENCH; i++)
44 test_strlen(s);
45
46 clock_gettime(CLOCK_MONOTONIC, &ts_end);
47
48 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);
49}
50
51static int testcase(void)
52{
53 char *s;
54 unsigned long i;
55
56 s = memalign(128, SIZE);
57 if (!s) {
58 perror("memalign");
59 exit(1);
60 }
61
62 srandom(1);
63
64 memset(s, 0, SIZE);
65 for (i = 0; i < SIZE; i++) {
66 char c;
67
68 do {
69 c = random() & 0x7f;
70 } while (!c);
71 s[i] = c;
72 test_one(s);
73 }
74
75 for (i = 0; i < ITERATIONS; i++) {
76 unsigned long j;
77
78 for (j = 0; j < SIZE; j++) {
79 char c;
80
81 do {
82 c = random() & 0x7f;
83 } while (!c);
84 s[j] = c;
85 }
86 for (j = 0; j < sizeof(long); j++) {
87 s[SIZE - 1 - j] = 0;
88 test_one(s);
89 }
90 }
91
92 for (i = 0; i < SIZE; i++) {
93 char c;
94
95 do {
96 c = random() & 0x7f;
97 } while (!c);
98 s[i] = c;
99 }
100
101 bench_test(s);
102
103 s[16] = 0;
104 bench_test(s);
105
106 s[8] = 0;
107 bench_test(s);
108
109 s[4] = 0;
110 bench_test(s);
111
112 s[3] = 0;
113 bench_test(s);
114
115 s[2] = 0;
116 bench_test(s);
117
118 s[1] = 0;
119 bench_test(s);
120
121 return 0;
122}
123
124int main(void)
125{
126 return test_harness(testcase, "strlen");
127}