test-memset.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. /* Test memset functions.
  2. Copyright (C) 1999-2019 Free Software Foundation, Inc.
  3. This file is part of the GNU C Library.
  4. Written by Jakub Jelinek <jakub@redhat.com>, 1999.
  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.
  9. The GNU C Library is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. Lesser General Public License for more details.
  13. You should have received a copy of the GNU Lesser General Public
  14. License along with the GNU C Library; if not, see
  15. <http://www.gnu.org/licenses/>. */
  16. #define TEST_MAIN
  17. #ifdef TEST_BZERO
  18. # ifdef TEST_EXPLICIT_BZERO
  19. # define TEST_NAME "explicit_bzero"
  20. # else
  21. # define TEST_NAME "bzero"
  22. # endif
  23. #else
  24. # ifndef WIDE
  25. # define TEST_NAME "memset"
  26. # else
  27. # define TEST_NAME "wmemset"
  28. # endif /* WIDE */
  29. #endif /* !TEST_BZERO */
  30. #define MIN_PAGE_SIZE 131072
  31. #include "test-string.h"
  32. #ifndef WIDE
  33. # define MEMSET memset
  34. # define CHAR char
  35. # define UCHAR unsigned char
  36. # define SIMPLE_MEMSET simple_memset
  37. # define MEMCMP memcmp
  38. # define BIG_CHAR CHAR_MAX
  39. #else
  40. # include <wchar.h>
  41. # define MEMSET wmemset
  42. # define CHAR wchar_t
  43. # define UCHAR wchar_t
  44. # define SIMPLE_MEMSET simple_wmemset
  45. # define MEMCMP wmemcmp
  46. # define BIG_CHAR WCHAR_MAX
  47. #endif /* WIDE */
  48. CHAR *SIMPLE_MEMSET (CHAR *, int, size_t);
  49. #ifdef TEST_BZERO
  50. typedef void (*proto_t) (char *, size_t);
  51. void simple_bzero (char *, size_t);
  52. void builtin_bzero (char *, size_t);
  53. IMPL (simple_bzero, 0)
  54. IMPL (builtin_bzero, 0)
  55. #ifdef TEST_EXPLICIT_BZERO
  56. IMPL (explicit_bzero, 1)
  57. #else
  58. IMPL (bzero, 1)
  59. #endif
  60. void
  61. simple_bzero (char *s, size_t n)
  62. {
  63. SIMPLE_MEMSET (s, 0, n);
  64. }
  65. void
  66. builtin_bzero (char *s, size_t n)
  67. {
  68. __builtin_bzero (s, n);
  69. }
  70. #else
  71. typedef CHAR *(*proto_t) (CHAR *, int, size_t);
  72. IMPL (SIMPLE_MEMSET, 0)
  73. # ifndef WIDE
  74. char *builtin_memset (char *, int, size_t);
  75. IMPL (builtin_memset, 0)
  76. # endif /* !WIDE */
  77. IMPL (MEMSET, 1)
  78. # ifndef WIDE
  79. char *
  80. builtin_memset (char *s, int c, size_t n)
  81. {
  82. return __builtin_memset (s, c, n);
  83. }
  84. # endif /* !WIDE */
  85. #endif /* !TEST_BZERO */
  86. CHAR *
  87. inhibit_loop_to_libcall
  88. SIMPLE_MEMSET (CHAR *s, int c, size_t n)
  89. {
  90. CHAR *r = s, *end = s + n;
  91. while (r < end)
  92. *r++ = c;
  93. return s;
  94. }
  95. static void
  96. do_one_test (impl_t *impl, CHAR *s, int c __attribute ((unused)), size_t n)
  97. {
  98. CHAR tstbuf[n];
  99. #ifdef TEST_BZERO
  100. simple_bzero (tstbuf, n);
  101. CALL (impl, s, n);
  102. if (memcmp (s, tstbuf, n) != 0)
  103. #else
  104. CHAR *res = CALL (impl, s, c, n);
  105. if (res != s
  106. || SIMPLE_MEMSET (tstbuf, c, n) != tstbuf
  107. || MEMCMP (s, tstbuf, n) != 0)
  108. #endif /* !TEST_BZERO */
  109. {
  110. error (0, 0, "Wrong result in function %s", impl->name);
  111. ret = 1;
  112. return;
  113. }
  114. }
  115. static void
  116. do_test (size_t align, int c, size_t len)
  117. {
  118. align &= 7;
  119. if ((align + len) * sizeof (CHAR) > page_size)
  120. return;
  121. FOR_EACH_IMPL (impl, 0)
  122. do_one_test (impl, (CHAR *) (buf1) + align, c, len);
  123. }
  124. #ifndef TEST_BZERO
  125. static void
  126. do_random_tests (void)
  127. {
  128. size_t i, j, k, n, align, len, size;
  129. int c, o;
  130. UCHAR *p, *res;
  131. UCHAR *p2 = (UCHAR *) buf2;
  132. for (i = 0; i < 65536 / sizeof (CHAR); ++i)
  133. p2[i] = random () & BIG_CHAR;
  134. for (n = 0; n < ITERATIONS; n++)
  135. {
  136. if ((random () & 31) == 0)
  137. size = 65536 / sizeof (CHAR);
  138. else
  139. size = 512;
  140. p = (UCHAR *) (buf1 + page_size) - size;
  141. len = random () & (size - 1);
  142. align = size - len - (random () & 31);
  143. if (align > size)
  144. align = size - len;
  145. if ((random () & 7) == 0)
  146. align &= ~63;
  147. if ((random () & 7) == 0)
  148. c = 0;
  149. else
  150. c = random () & BIG_CHAR;
  151. o = random () & BIG_CHAR;
  152. if (o == c)
  153. o = (c + 1) & BIG_CHAR;
  154. j = len + align + 128;
  155. if (j > size)
  156. j = size;
  157. if (align >= 128)
  158. k = align - 128;
  159. else
  160. k = 0;
  161. for (i = k; i < align; ++i)
  162. p[i] = o;
  163. for (i = align + len; i < j; ++i)
  164. p[i] = o;
  165. FOR_EACH_IMPL (impl, 1)
  166. {
  167. for (i = 0; i < len; ++i)
  168. {
  169. p[i + align] = p2[i];
  170. if (p[i + align] == c)
  171. p[i + align] = o;
  172. }
  173. res = (UCHAR *) CALL (impl, (CHAR *) p + align, c, len);
  174. if (res != p + align)
  175. {
  176. error (0, 0, "Iteration %zd - wrong result in function %s (%zd, %d, %zd) %p != %p",
  177. n, impl->name, align, c, len, res, p + align);
  178. ret = 1;
  179. }
  180. for (i = k; i < align; ++i)
  181. if (p[i] != o)
  182. {
  183. error (0, 0, "Iteration %zd - garbage before %s (%zd, %d, %zd)",
  184. n, impl->name, align, c, len);
  185. ret = 1;
  186. break;
  187. }
  188. for (; i < align + len; ++i)
  189. if (p[i] != c)
  190. {
  191. error (0, 0, "Iteration %zd - not cleared correctly %s (%zd, %d, %zd)",
  192. n, impl->name, align, c, len);
  193. ret = 1;
  194. break;
  195. }
  196. for (; i < j; ++i)
  197. if (p[i] != o)
  198. {
  199. error (0, 0, "Iteration %zd - garbage after %s (%zd, %d, %zd)",
  200. n, impl->name, align, c, len);
  201. ret = 1;
  202. break;
  203. }
  204. }
  205. }
  206. }
  207. #endif /* !TEST_BZERO */
  208. int
  209. test_main (void)
  210. {
  211. size_t i;
  212. int c = 0;
  213. test_init ();
  214. printf ("%24s", "");
  215. FOR_EACH_IMPL (impl, 0)
  216. printf ("\t%s", impl->name);
  217. putchar ('\n');
  218. #ifndef TEST_BZERO
  219. for (c = -65; c <= 130; c += 65)
  220. #endif
  221. {
  222. for (i = 0; i < 18; ++i)
  223. do_test (0, c, 1 << i);
  224. for (i = 1; i < 32; ++i)
  225. {
  226. do_test (i, c, i);
  227. if (i & (i - 1))
  228. do_test (0, c, i);
  229. }
  230. do_test (1, c, 14);
  231. do_test (3, c, 1024);
  232. do_test (4, c, 64);
  233. do_test (2, c, 25);
  234. }
  235. #ifndef TEST_BZERO
  236. do_random_tests ();
  237. #endif
  238. return ret;
  239. }
  240. #include <support/test-driver.c>