1 /* Support for testing and measuring memcpy functions.
2 Copyright (C) 1999-2022 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
19 /* This fail contains the actual memcpy test functions. It is included
20 in test-memcpy.c and test-memcpy-large.c. They are split because
21 the tests take a long time to run and splitting them allows for
22 simpler parallel testing. */
25 #define MEMCPY_RESULT(dst, len) dst
26 #define MIN_PAGE_SIZE 131072
28 #define TEST_NAME "memcpy"
29 #define TIMEOUT (8 * 60)
30 #include "test-string.h"
32 char *simple_memcpy (char *, const char *, size_t);
33 char *builtin_memcpy (char *, const char *, size_t);
35 IMPL (simple_memcpy
, 0)
36 IMPL (builtin_memcpy
, 0)
39 simple_memcpy (char *dst
, const char *src
, size_t n
)
48 builtin_memcpy (char *dst
, const char *src
, size_t n
)
50 return __builtin_memcpy (dst
, src
, n
);
53 typedef char *(*proto_t
) (char *, const char *, size_t);
54 typedef uint32_t __attribute__ ((may_alias
, aligned (1))) unaligned_uint32_t
;
57 do_one_test (impl_t
*impl
, char *dst
, const char *src
, size_t len
)
61 /* Must clear the destination buffer set by the previous run. */
62 for (i
= 0; i
< len
; i
++)
65 if (CALL (impl
, dst
, src
, len
) != MEMCPY_RESULT (dst
, len
))
67 error (0, 0, "Wrong result in function %s %p %p", impl
->name
,
68 CALL (impl
, dst
, src
, len
), MEMCPY_RESULT (dst
, len
));
73 if (memcmp (dst
, src
, len
) != 0)
76 "Wrong result in function %s dst %p \"%.*s\" src %p \"%.*s\" len "
78 impl
->name
, dst
, (int)len
, dst
, src
, (int)len
, src
, len
);
85 do_test (size_t align1
, size_t align2
, size_t len
)
91 if (align1
+ len
>= page_size
)
95 if (align2
+ len
>= page_size
)
98 s1
= (char *)(buf1
+ align1
);
99 s2
= (char *)(buf2
+ align2
);
100 for (repeats
= 0; repeats
< 2; ++repeats
)
102 for (i
= 0, j
= 1; i
< len
; i
++, j
+= 23)
105 FOR_EACH_IMPL (impl
, 0)
106 do_one_test (impl
, s2
, s1
, len
);
111 do_test1 (size_t align1
, size_t align2
, size_t size
)
114 size_t mmap_size
, region_size
;
116 align1
&= (page_size
- 1);
120 align2
&= (page_size
- 1);
124 region_size
= (size
+ page_size
- 1) & (~(page_size
- 1));
126 mmap_size
= region_size
* 2 + 3 * page_size
;
127 large_buf
= mmap (NULL
, mmap_size
, PROT_READ
| PROT_WRITE
,
128 MAP_PRIVATE
| MAP_ANON
, -1, 0);
129 if (large_buf
== MAP_FAILED
)
131 puts ("Failed to allocate large_buf, skipping do_test");
134 if (mprotect (large_buf
+ region_size
+ page_size
, page_size
, PROT_NONE
))
135 error (EXIT_FAILURE
, errno
, "mprotect failed");
137 size_t array_size
= size
/ sizeof (uint32_t);
138 unaligned_uint32_t
*dest
= large_buf
+ align1
;
139 unaligned_uint32_t
*src
= large_buf
+ region_size
+ 2 * page_size
+ align2
;
142 for (repeats
= 0; repeats
< 2; repeats
++)
144 for (i
= 0; i
< array_size
; i
++)
145 src
[i
] = (uint32_t)i
;
146 FOR_EACH_IMPL (impl
, 0)
148 memset (dest
, -1, size
);
149 CALL (impl
, (char *)dest
, (char *)src
, size
);
150 if (memcmp (src
, dest
, size
))
152 for (i
= 0; i
< array_size
; i
++)
153 if (dest
[i
] != src
[i
])
156 "Wrong result in function %s dst \"%p\" src \"%p\" "
158 impl
->name
, dest
, src
, i
);
160 munmap ((void *)large_buf
, mmap_size
);
165 dest
= large_buf
+ region_size
+ 2 * page_size
+ align1
;
166 src
= large_buf
+ align2
;
168 munmap ((void *)large_buf
, mmap_size
);