First version
[3rdparty/ote_partner/tlk.git] / app / stringtests / string_tests.c
1 /*
2  * Copyright (c) 2008 Travis Geiselbrecht
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining
5  * a copy of this software and associated documentation files
6  * (the "Software"), to deal in the Software without restriction,
7  * including without limitation the rights to use, copy, modify, merge,
8  * publish, distribute, sublicense, and/or sell copies of the Software,
9  * and to permit persons to whom the Software is furnished to do so,
10  * subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be
13  * included in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22  */
23 #include <debug.h>
24 #include <string.h>
25 #include <malloc.h>
26 #include <app.h>
27 #include <platform.h>
28 #include <kernel/thread.h>
29
30 static uint8_t *src;
31 static uint8_t *dst;
32
33 static uint8_t *src2;
34 static uint8_t *dst2;
35
36 #define BUFFER_SIZE (1024*1024)
37 #define ITERATIONS 16
38
39 extern void *mymemcpy(void *dst, const void *src, size_t len);
40 extern void *mymemset(void *dst, int c, size_t len);
41
42 static void *null_memcpy(void *dst, const void *src, size_t len)
43 {
44         return dst;
45 }
46
47 static lk_time_t bench_memcpy_routine(void *memcpy_routine(void *, const void *, size_t), size_t srcalign, size_t dstalign)
48 {
49         int i;
50         lk_time_t t0;
51
52         t0 = current_time();
53         for (i=0; i < ITERATIONS; i++) {
54                 memcpy_routine(dst + dstalign, src + srcalign, BUFFER_SIZE);
55         }
56         return current_time() - t0;
57 }
58
59 static void bench_memcpy(void)
60 {
61         lk_time_t null, libc, mine;
62         size_t srcalign, dstalign;
63         
64         printf("memcpy speed test\n");
65         thread_sleep(200); // let the debug string clear the serial port
66
67         for (srcalign = 0; srcalign < 64; ) {
68                 for (dstalign = 0; dstalign < 64; ) {
69
70                         null = bench_memcpy_routine(&null_memcpy, srcalign, dstalign);
71                         libc = bench_memcpy_routine(&memcpy, srcalign, dstalign);
72                         mine = bench_memcpy_routine(&mymemcpy, srcalign, dstalign);
73
74                         printf("srcalign %lu, dstalign %lu\n", srcalign, dstalign);
75                         printf("   null memcpy %u msecs\n", null);
76                         printf("   libc memcpy %u msecs, %llu bytes/sec\n", libc, BUFFER_SIZE * ITERATIONS * 1000ULL / libc);
77                         printf("   my   memcpy %u msecs, %llu bytes/sec\n", mine, BUFFER_SIZE * ITERATIONS * 1000ULL / mine);
78
79                         if (dstalign == 0)
80                                 dstalign = 1;
81                         else 
82                                 dstalign <<= 1;
83                 }
84                 if (srcalign == 0)
85                         srcalign = 1;
86                 else 
87                         srcalign <<= 1;
88         }
89 }
90
91 static void fillbuf(void *ptr, size_t len, uint32_t seed)
92 {
93         size_t i;
94
95         for (i = 0; i < len; i++) {
96                 ((char *)ptr)[i] = seed;
97                 seed *= 0x1234567;
98         }
99 }
100
101 static void validate_memcpy(void)
102 {
103         size_t srcalign, dstalign, size;
104         const size_t maxsize = 256;
105
106         printf("testing memcpy for correctness\n");
107
108         /*
109          * do the simple tests to make sure that memcpy doesn't color outside
110          * the lines for all alignment cases
111          */
112         for (srcalign = 0; srcalign < 64; srcalign++) {
113                 for (dstalign = 0; dstalign < 64; dstalign++) {
114 //                      printf("srcalign %zu, dstalign %zu\n", srcalign, dstalign);
115                         for (size = 0; size < maxsize; size++) {
116
117 //                              printf("srcalign %zu, dstalign %zu, size %zu\n", srcalign, dstalign, size);
118
119                                 fillbuf(src, maxsize * 2, 567);
120                                 fillbuf(src2, maxsize * 2, 567);
121                                 fillbuf(dst, maxsize * 2, 123514);
122                                 fillbuf(dst2, maxsize * 2, 123514);
123
124                                 memcpy(dst + dstalign, src + srcalign, size);
125                                 mymemcpy(dst2 + dstalign, src2 + srcalign, size);
126
127                                 int comp = memcmp(dst, dst2, maxsize * 2);
128                                 if (comp != 0) {
129                                         printf("error! srcalign %zu, dstalign %zu, size %zu\n", srcalign, dstalign, size);
130                                 }
131                         }
132                 }
133         }
134 }
135
136 static lk_time_t bench_memset_routine(void *memset_routine(void *, int, size_t), size_t dstalign)
137 {
138         int i;
139         lk_time_t t0;
140
141         t0 = current_time();
142         for (i=0; i < ITERATIONS; i++) {
143                 memset_routine(dst + dstalign, 0, BUFFER_SIZE);
144         }
145         return current_time() - t0;
146 }
147
148 static void bench_memset(void)
149 {
150         lk_time_t libc, mine;
151         size_t dstalign;
152         
153         printf("memset speed test\n");
154         thread_sleep(200); // let the debug string clear the serial port
155
156         for (dstalign = 0; dstalign < 64; dstalign++) {
157
158                 libc = bench_memset_routine(&memset, dstalign);
159                 mine = bench_memset_routine(&mymemset, dstalign);
160
161                 printf("dstalign %lu\n", dstalign);
162                 printf("   libc memset %u msecs, %llu bytes/sec\n", libc, BUFFER_SIZE * ITERATIONS * 1000ULL / libc);
163                 printf("   my   memset %u msecs, %llu bytes/sec\n", mine, BUFFER_SIZE * ITERATIONS * 1000ULL / mine);
164         }
165 }
166
167 static void validate_memset(void)
168 {
169         size_t dstalign, size;
170         int c;
171         const size_t maxsize = 256;
172
173         printf("testing memset for correctness\n");
174
175         for (dstalign = 0; dstalign < 64; dstalign++) {
176                 printf("align %zd\n", dstalign);
177                 for (size = 0; size < maxsize; size++) {
178                         for (c = 0; c < 256; c++) {
179
180                                 fillbuf(dst, maxsize * 2, 123514);
181                                 fillbuf(dst2, maxsize * 2, 123514);
182
183                                 memset(dst + dstalign, c, size);
184                                 mymemset(dst2 + dstalign, c, size);
185
186                                 int comp = memcmp(dst, dst2, maxsize * 2);
187                                 if (comp != 0) {
188                                         printf("error! align %zu, c %d, size %zu\n", dstalign, c, size);
189                                 }
190                         }
191                 }
192         }
193 }
194
195 #if defined(WITH_LIB_CONSOLE)
196 #include <lib/console.h>
197
198 static int string_tests(int argc, cmd_args *argv)
199 {
200         src = memalign(64, BUFFER_SIZE + 256);
201         dst = memalign(64, BUFFER_SIZE + 256);
202         src2 = memalign(64, BUFFER_SIZE + 256);
203         dst2 = memalign(64, BUFFER_SIZE + 256);
204
205         printf("src %p, dst %p\n", src, dst);
206         printf("src2 %p, dst2 %p\n", src2, dst2);
207
208         if (argc < 3) {
209                 printf("not enough arguments:\n");
210 usage:
211                 printf("%s validate <routine>\n", argv[0].str);
212                 printf("%s bench <routine>\n", argv[0].str);
213                 goto out;
214         }
215
216         if (!strcmp(argv[1].str, "validate")) {
217                 if (!strcmp(argv[2].str, "memcpy")) {
218                         validate_memcpy();
219                 } else if (!strcmp(argv[2].str, "memset")) {
220                         validate_memset();
221                 }
222         } else if (!strcmp(argv[1].str, "bench")) {
223                 if (!strcmp(argv[2].str, "memcpy")) {
224                         bench_memcpy();
225                 } else if (!strcmp(argv[2].str, "memset")) {
226                         bench_memset();
227                 }
228         } else {
229                 goto usage;
230         }
231
232 out:
233         free(src);
234         free(dst);
235         free(src2);
236         free(dst2);
237
238         return 0;
239 }
240
241 STATIC_COMMAND_START
242 { "string", NULL, &string_tests },
243 STATIC_COMMAND_END(stringtests);
244
245 #endif
246
247 APP_START(stringtests)
248 APP_END
249