1 /* 2 * Unit test suite for memory functions 3 * 4 * Copyright 2003 Dimitrie O. Paun 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 19 */ 20 21 #include "precomp.h" 22 23 #include <malloc.h> 24 25 static void (__cdecl *p_aligned_free)(void*) = NULL; 26 static void * (__cdecl *p_aligned_malloc)(size_t,size_t) = NULL; 27 static void * (__cdecl *p_aligned_offset_malloc)(size_t,size_t,size_t) = NULL; 28 static void * (__cdecl *p_aligned_realloc)(void*,size_t,size_t) = NULL; 29 static void * (__cdecl *p_aligned_offset_realloc)(void*,size_t,size_t,size_t) = NULL; 30 31 static void test_aligned_malloc(unsigned int size, unsigned int alignment) 32 { 33 void *mem; 34 35 mem = p_aligned_malloc(size, alignment); 36 37 if ((alignment & (alignment - 1)) == 0) 38 ok(mem != NULL, "_aligned_malloc(%d, %d) failed\n", size, alignment); 39 else 40 ok(mem == NULL, "_aligned_malloc(%d, %d) should have failed\n", size, alignment); 41 42 if (mem) 43 { 44 ok(((DWORD_PTR)mem & (alignment ? alignment - 1 : 0)) == 0, 45 "_aligned_malloc(%d, %d) not aligned: %p\n", size, alignment, mem); 46 if (winetest_debug > 1) 47 { 48 void *saved; 49 saved = *(void **)((DWORD_PTR)((char *)mem - sizeof(void *)) & ~(sizeof(void *) - 1)); 50 trace("_aligned_malloc(%3d, %3d) returns %p, saved = %p\n", size, alignment, mem, saved ); 51 } 52 p_aligned_free(mem); 53 } 54 else 55 ok(errno == EINVAL, "_aligned_malloc(%d, %d) errno: %d != %d\n", size, alignment, errno, EINVAL); 56 } 57 58 static void test_aligned_offset_malloc(unsigned int size, unsigned int alignment, unsigned int offset) 59 { 60 void *mem; 61 62 mem = p_aligned_offset_malloc(size, alignment, offset); 63 64 if ((alignment & (alignment - 1)) == 0) 65 if (offset < size) 66 ok(mem != NULL, "_aligned_offset_malloc(%d, %d, %d) failed\n", size, alignment, offset); 67 else 68 ok(errno == EINVAL, "_aligned_offset_malloc(%d, %d, %d) errno: %d != %d\n", size, alignment, offset, errno, EINVAL); 69 else 70 ok(mem == NULL, "_aligned_offset_malloc(%d, %d, %d) should have failed\n", size, alignment, offset); 71 72 if (mem) 73 { 74 ok(((DWORD_PTR)((char *)mem + offset) & (alignment ? alignment - 1 : 0)) == 0, 75 "_aligned_offset_malloc(%d, %d, %d) not aligned: %p\n", size, alignment, offset, mem); 76 if (winetest_debug > 1) 77 { 78 void *saved; 79 saved = *(void **)((DWORD_PTR)((char *)mem - sizeof(void *)) & ~(sizeof(void *) - 1)); 80 trace("_aligned_offset_malloc(%3d, %3d, %3d) returns %p, saved = %p\n", 81 size, alignment, offset, mem, saved); 82 } 83 p_aligned_free(mem); 84 } 85 else 86 ok(errno == EINVAL, "_aligned_offset_malloc(%d, %d, %d) errno: %d != %d\n", size, alignment, offset, errno, EINVAL); 87 } 88 89 static void test_aligned_realloc(unsigned int size1, unsigned int size2, unsigned int alignment) 90 { 91 void *mem, *mem1, *mem2; 92 93 mem = p_aligned_malloc(size1, alignment); 94 95 if ((alignment & (alignment - 1)) == 0) 96 ok(mem != NULL, "_aligned_malloc(%d, %d) failed\n", size1, alignment); 97 else 98 ok(mem == NULL, "_aligned_malloc(%d, %d) should have failed\n", size1, alignment); 99 100 if (mem) 101 { 102 mem1 = malloc(size1); 103 if (mem1) 104 { 105 unsigned int i; 106 for (i = 0; i < size1; i++) 107 ((char *)mem)[i] = i + 1; 108 memcpy(mem1, mem, size1); 109 } 110 111 ok(((DWORD_PTR)mem & (alignment ? alignment - 1 : 0)) == 0, 112 "_aligned_malloc(%d, %d) not aligned: %p\n", size1, alignment, mem); 113 if (winetest_debug > 1) 114 { 115 void *saved; 116 saved = *(void **)((DWORD_PTR)((char *)mem - sizeof(void *)) & ~(sizeof(void *) - 1)); 117 trace("_aligned_malloc(%3d, %3d) returns %p, saved = %p\n", size1, alignment, mem, saved); 118 } 119 120 mem2 = p_aligned_realloc(mem, size2, alignment); 121 122 ok(mem2 != NULL, "_aligned_realloc(%p, %d, %d) failed\n", mem, size2, alignment); 123 124 if (mem2) 125 { 126 ok(((DWORD_PTR)mem2 & (alignment ? alignment - 1 : 0)) == 0, 127 "_aligned_realloc(%p, %d, %d) not aligned: %p\n", mem, size2, alignment, mem2); 128 if (winetest_debug > 1) 129 { 130 void *saved; 131 saved = *(void **)((DWORD_PTR)((char *)mem2 - sizeof(void *)) & ~(sizeof(void *) - 1)); 132 trace("_aligned_realloc(%p, %3d, %3d) returns %p, saved = %p\n", 133 mem, size2, alignment, mem2, saved); 134 } 135 if (mem1) 136 { 137 ok(memcmp(mem2, mem1, min(size1, size2))==0, "_aligned_realloc(%p, %d, %d) has different data\n", mem, size2, alignment); 138 if (memcmp(mem2, mem1, min(size1, size2)) && winetest_debug > 1) 139 { 140 unsigned int i; 141 for (i = 0; i < min(size1, size2); i++) 142 { 143 if (((char *)mem2)[i] != ((char *)mem1)[i]) 144 trace("%d: %02x != %02x\n", i, ((char *)mem2)[i] & 0xff, ((char *)mem1)[i] & 0xff); 145 } 146 } 147 } 148 p_aligned_free(mem2); 149 } else { 150 ok(errno == EINVAL, "_aligned_realloc(%p, %d, %d) errno: %d != %d\n", mem, size2, alignment, errno, EINVAL); 151 p_aligned_free(mem); 152 } 153 154 free(mem1); 155 } 156 else 157 ok(errno == EINVAL, "_aligned_malloc(%d, %d) errno: %d != %d\n", size1, alignment, errno, EINVAL); 158 } 159 160 static void test_aligned_offset_realloc(unsigned int size1, unsigned int size2, 161 unsigned int alignment, unsigned int offset) 162 { 163 void *mem, *mem1, *mem2; 164 165 mem = p_aligned_offset_malloc(size1, alignment, offset); 166 167 if ((alignment & (alignment - 1)) == 0) 168 ok(mem != NULL, "_aligned_offset_malloc(%d, %d, %d) failed\n", size1, alignment, offset); 169 else 170 ok(mem == NULL, "_aligned_offset_malloc(%d, %d, %d) should have failed\n", size1, alignment, offset); 171 172 if (mem) 173 { 174 mem1 = malloc(size1); 175 if (mem1) 176 { 177 unsigned int i; 178 for (i = 0; i < size1; i++) 179 ((char *)mem)[i] = i + 1; 180 memcpy(mem1, mem, size1); 181 } 182 183 ok(((DWORD_PTR)((char *)mem + offset) & (alignment ? alignment - 1 : 0)) == 0, 184 "_aligned_offset_malloc(%d, %d, %d) not aligned: %p\n", size1, alignment, offset, mem); 185 if (winetest_debug > 1) 186 { 187 void *saved; 188 saved = *(void **)((DWORD_PTR)((char *)mem - sizeof(void *)) & ~(sizeof(void *) - 1)); 189 trace("_aligned_offset_malloc(%3d, %3d, %3d) returns %p, saved = %p\n", 190 size1, alignment, offset, mem, saved); 191 } 192 193 mem2 = p_aligned_offset_realloc(mem, size2, alignment, offset); 194 195 ok(mem2 != NULL, "_aligned_offset_realloc(%p, %d, %d, %d) failed\n", mem, size2, alignment, offset); 196 197 if (mem2) 198 { 199 ok(((DWORD_PTR)((char *)mem + offset) & (alignment ? alignment - 1 : 0)) == 0, 200 "_aligned_offset_realloc(%p, %d, %d, %d) not aligned: %p\n", mem, size2, alignment, offset, mem2); 201 if (winetest_debug > 1) 202 { 203 void *saved; 204 saved = *(void **)((DWORD_PTR)((char *)mem2 - sizeof(void *)) & ~(sizeof(void *) - 1)); 205 trace("_aligned_offset_realloc(%p, %3d, %3d, %3d) returns %p, saved = %p\n", 206 mem, size2, alignment, offset, mem2, saved); 207 } 208 if (mem1) 209 { 210 ok(memcmp(mem2, mem1, min(size1, size2))==0, "_aligned_offset_realloc(%p, %d, %d, %d) has different data\n", mem, size2, alignment, offset); 211 if (memcmp(mem2, mem1, min(size1, size2)) && winetest_debug > 1) 212 { 213 unsigned int i; 214 for (i = 0; i < min(size1, size2); i++) 215 { 216 if (((char *)mem2)[i] != ((char *)mem1)[i]) 217 trace("%d: %02x != %02x\n", i, ((char *)mem2)[i] & 0xff, ((char *)mem1)[i] & 0xff); 218 } 219 } 220 } 221 p_aligned_free(mem2); 222 } else { 223 ok(errno == EINVAL, "_aligned_offset_realloc(%p, %d, %d, %d) errno: %d != %d\n", mem, size2, alignment, offset, errno, EINVAL); 224 p_aligned_free(mem); 225 } 226 227 free(mem1); 228 } 229 else 230 ok(errno == EINVAL, "_aligned_offset_malloc(%d, %d) errno: %d != %d\n", size1, alignment, errno, EINVAL); 231 } 232 233 static void test_aligned(void) 234 { 235 HMODULE msvcrt = GetModuleHandleA("msvcrt.dll"); 236 237 if (msvcrt == NULL) 238 return; 239 240 p_aligned_free = (void*)GetProcAddress(msvcrt, "_aligned_free"); 241 p_aligned_malloc = (void*)GetProcAddress(msvcrt, "_aligned_malloc"); 242 p_aligned_offset_malloc = (void*)GetProcAddress(msvcrt, "_aligned_offset_malloc"); 243 p_aligned_realloc = (void*)GetProcAddress(msvcrt, "_aligned_realloc"); 244 p_aligned_offset_realloc = (void*)GetProcAddress(msvcrt, "_aligned_offset_realloc"); 245 246 if (!p_aligned_free || !p_aligned_malloc || !p_aligned_offset_malloc || !p_aligned_realloc || !p_aligned_offset_realloc) 247 { 248 skip("aligned memory tests skipped\n"); 249 return; 250 } 251 252 test_aligned_malloc(256, 0); 253 test_aligned_malloc(256, 1); 254 test_aligned_malloc(256, 2); 255 test_aligned_malloc(256, 3); 256 test_aligned_malloc(256, 4); 257 test_aligned_malloc(256, 8); 258 test_aligned_malloc(256, 16); 259 test_aligned_malloc(256, 32); 260 test_aligned_malloc(256, 64); 261 test_aligned_malloc(256, 127); 262 test_aligned_malloc(256, 128); 263 264 test_aligned_offset_malloc(256, 0, 0); 265 test_aligned_offset_malloc(256, 1, 0); 266 test_aligned_offset_malloc(256, 2, 0); 267 test_aligned_offset_malloc(256, 3, 0); 268 test_aligned_offset_malloc(256, 4, 0); 269 test_aligned_offset_malloc(256, 8, 0); 270 test_aligned_offset_malloc(256, 16, 0); 271 test_aligned_offset_malloc(256, 32, 0); 272 test_aligned_offset_malloc(256, 64, 0); 273 test_aligned_offset_malloc(256, 127, 0); 274 test_aligned_offset_malloc(256, 128, 0); 275 276 test_aligned_offset_malloc(256, 0, 4); 277 test_aligned_offset_malloc(256, 1, 4); 278 test_aligned_offset_malloc(256, 2, 4); 279 test_aligned_offset_malloc(256, 3, 4); 280 test_aligned_offset_malloc(256, 4, 4); 281 test_aligned_offset_malloc(256, 8, 4); 282 test_aligned_offset_malloc(256, 16, 4); 283 test_aligned_offset_malloc(256, 32, 4); 284 test_aligned_offset_malloc(256, 64, 4); 285 test_aligned_offset_malloc(256, 127, 4); 286 test_aligned_offset_malloc(256, 128, 4); 287 288 test_aligned_offset_malloc(256, 8, 7); 289 test_aligned_offset_malloc(256, 8, 9); 290 test_aligned_offset_malloc(256, 8, 16); 291 test_aligned_offset_malloc(256, 8, 17); 292 test_aligned_offset_malloc(256, 8, 254); 293 test_aligned_offset_malloc(256, 8, 255); 294 test_aligned_offset_malloc(256, 8, 256); 295 test_aligned_offset_malloc(256, 8, 512); 296 297 test_aligned_realloc(256, 512, 0); 298 test_aligned_realloc(256, 128, 0); 299 test_aligned_realloc(256, 512, 4); 300 test_aligned_realloc(256, 128, 4); 301 test_aligned_realloc(256, 512, 8); 302 test_aligned_realloc(256, 128, 8); 303 test_aligned_realloc(256, 512, 16); 304 test_aligned_realloc(256, 128, 16); 305 test_aligned_realloc(256, 512, 32); 306 test_aligned_realloc(256, 128, 32); 307 test_aligned_realloc(256, 512, 64); 308 test_aligned_realloc(256, 128, 64); 309 310 test_aligned_offset_realloc(256, 512, 0, 0); 311 test_aligned_offset_realloc(256, 128, 0, 0); 312 test_aligned_offset_realloc(256, 512, 4, 0); 313 test_aligned_offset_realloc(256, 128, 4, 0); 314 test_aligned_offset_realloc(256, 512, 8, 0); 315 test_aligned_offset_realloc(256, 128, 8, 0); 316 test_aligned_offset_realloc(256, 512, 16, 0); 317 test_aligned_offset_realloc(256, 128, 16, 0); 318 test_aligned_offset_realloc(256, 512, 32, 0); 319 test_aligned_offset_realloc(256, 128, 32, 0); 320 test_aligned_offset_realloc(256, 512, 64, 0); 321 test_aligned_offset_realloc(256, 128, 64, 0); 322 323 test_aligned_offset_realloc(256, 512, 0, 4); 324 test_aligned_offset_realloc(256, 128, 0, 4); 325 test_aligned_offset_realloc(256, 512, 4, 4); 326 test_aligned_offset_realloc(256, 128, 4, 4); 327 test_aligned_offset_realloc(256, 512, 8, 4); 328 test_aligned_offset_realloc(256, 128, 8, 4); 329 test_aligned_offset_realloc(256, 512, 16, 4); 330 test_aligned_offset_realloc(256, 128, 16, 4); 331 test_aligned_offset_realloc(256, 512, 32, 4); 332 test_aligned_offset_realloc(256, 128, 32, 4); 333 test_aligned_offset_realloc(256, 512, 64, 4); 334 test_aligned_offset_realloc(256, 128, 64, 4); 335 336 test_aligned_offset_realloc(256, 512, 0, 8); 337 test_aligned_offset_realloc(256, 128, 0, 8); 338 test_aligned_offset_realloc(256, 512, 4, 8); 339 test_aligned_offset_realloc(256, 128, 4, 8); 340 test_aligned_offset_realloc(256, 512, 8, 8); 341 test_aligned_offset_realloc(256, 128, 8, 8); 342 test_aligned_offset_realloc(256, 512, 16, 8); 343 test_aligned_offset_realloc(256, 128, 16, 8); 344 test_aligned_offset_realloc(256, 512, 32, 8); 345 test_aligned_offset_realloc(256, 128, 32, 8); 346 test_aligned_offset_realloc(256, 512, 64, 8); 347 test_aligned_offset_realloc(256, 128, 64, 8); 348 349 test_aligned_offset_realloc(256, 512, 0, 16); 350 test_aligned_offset_realloc(256, 128, 0, 16); 351 test_aligned_offset_realloc(256, 512, 4, 16); 352 test_aligned_offset_realloc(256, 128, 4, 16); 353 test_aligned_offset_realloc(256, 512, 8, 16); 354 test_aligned_offset_realloc(256, 128, 8, 16); 355 test_aligned_offset_realloc(256, 512, 16, 16); 356 test_aligned_offset_realloc(256, 128, 16, 16); 357 test_aligned_offset_realloc(256, 512, 32, 16); 358 test_aligned_offset_realloc(256, 128, 32, 16); 359 test_aligned_offset_realloc(256, 512, 64, 16); 360 test_aligned_offset_realloc(256, 128, 64, 16); 361 362 test_aligned_offset_realloc(256, 512, 0, 32); 363 test_aligned_offset_realloc(256, 128, 0, 32); 364 test_aligned_offset_realloc(256, 512, 4, 32); 365 test_aligned_offset_realloc(256, 128, 4, 32); 366 test_aligned_offset_realloc(256, 512, 8, 32); 367 test_aligned_offset_realloc(256, 128, 8, 32); 368 test_aligned_offset_realloc(256, 512, 16, 32); 369 test_aligned_offset_realloc(256, 128, 16, 32); 370 test_aligned_offset_realloc(256, 512, 32, 32); 371 test_aligned_offset_realloc(256, 128, 32, 32); 372 test_aligned_offset_realloc(256, 512, 64, 32); 373 test_aligned_offset_realloc(256, 128, 64, 32); 374 375 test_aligned_offset_realloc(256, 512, 0, 64); 376 test_aligned_offset_realloc(256, 128, 0, 64); 377 test_aligned_offset_realloc(256, 512, 4, 64); 378 test_aligned_offset_realloc(256, 128, 4, 64); 379 test_aligned_offset_realloc(256, 512, 8, 64); 380 test_aligned_offset_realloc(256, 128, 8, 64); 381 test_aligned_offset_realloc(256, 512, 16, 64); 382 test_aligned_offset_realloc(256, 128, 16, 64); 383 test_aligned_offset_realloc(256, 512, 32, 64); 384 test_aligned_offset_realloc(256, 128, 32, 64); 385 test_aligned_offset_realloc(256, 512, 64, 64); 386 test_aligned_offset_realloc(256, 128, 64, 64); 387 388 test_aligned_offset_realloc(256, 512, 0, 96); 389 test_aligned_offset_realloc(256, 128, 0, 96); 390 test_aligned_offset_realloc(256, 512, 4, 96); 391 test_aligned_offset_realloc(256, 128, 4, 96); 392 test_aligned_offset_realloc(256, 512, 8, 96); 393 test_aligned_offset_realloc(256, 128, 8, 96); 394 test_aligned_offset_realloc(256, 512, 16, 96); 395 test_aligned_offset_realloc(256, 128, 16, 96); 396 test_aligned_offset_realloc(256, 512, 32, 96); 397 test_aligned_offset_realloc(256, 128, 32, 96); 398 test_aligned_offset_realloc(256, 512, 64, 96); 399 test_aligned_offset_realloc(256, 128, 64, 96); 400 401 test_aligned_offset_realloc(256, 512, 0, 112); 402 test_aligned_offset_realloc(256, 128, 0, 112); 403 test_aligned_offset_realloc(256, 512, 4, 112); 404 test_aligned_offset_realloc(256, 128, 4, 112); 405 test_aligned_offset_realloc(256, 512, 8, 112); 406 test_aligned_offset_realloc(256, 128, 8, 112); 407 test_aligned_offset_realloc(256, 512, 16, 112); 408 test_aligned_offset_realloc(256, 128, 16, 112); 409 test_aligned_offset_realloc(256, 512, 32, 112); 410 test_aligned_offset_realloc(256, 128, 32, 112); 411 test_aligned_offset_realloc(256, 512, 64, 112); 412 test_aligned_offset_realloc(256, 128, 64, 112); 413 } 414 415 static void test_sbheap(void) 416 { 417 void *mem; 418 int threshold; 419 420 if(sizeof(void*) == 8) { 421 ok(!_set_sbh_threshold(0), "_set_sbh_threshold succeeded\n"); 422 ok(!_set_sbh_threshold(1000), "_set_sbh_threshold succeeded\n"); 423 return; 424 } 425 426 mem = malloc(1); 427 ok(mem != NULL, "malloc failed\n"); 428 429 ok(_set_sbh_threshold(1), "_set_sbh_threshold failed\n"); 430 threshold = _get_sbh_threshold(); 431 ok(threshold == 16, "threshold = %d\n", threshold); 432 433 ok(_set_sbh_threshold(8), "_set_sbh_threshold failed\n"); 434 threshold = _get_sbh_threshold(); 435 ok(threshold == 16, "threshold = %d\n", threshold); 436 437 ok(_set_sbh_threshold(1000), "_set_sbh_threshold failed\n"); 438 threshold = _get_sbh_threshold(); 439 ok(threshold == 1008, "threshold = %d\n", threshold); 440 441 free(mem); 442 443 mem = malloc(1); 444 ok(mem != NULL, "malloc failed\n"); 445 ok(!((UINT_PTR)mem & 0xf), "incorrect alignment (%p)\n", mem); 446 447 mem = realloc(mem, 10); 448 ok(mem != NULL, "realloc failed\n"); 449 ok(!((UINT_PTR)mem & 0xf), "incorrect alignment (%p)\n", mem); 450 451 ok(_set_sbh_threshold(0), "_set_sbh_threshold failed\n"); 452 threshold = _get_sbh_threshold(); 453 ok(threshold == 0, "threshold = %d\n", threshold); 454 455 free(mem); 456 } 457 458 static void test_calloc(void) 459 { 460 void *ptr; 461 462 ptr = calloc(1, 0); 463 ok(ptr != NULL, "got %p\n", ptr); 464 free(ptr); 465 466 ptr = calloc(0, 0); 467 ok(ptr != NULL, "got %p\n", ptr); 468 free(ptr); 469 470 ptr = calloc(0, 1); 471 ok(ptr != NULL, "got %p\n", ptr); 472 free(ptr); 473 474 errno = 0; 475 ptr = calloc(~(size_t)0 / 2, ~(size_t)0 / 2); 476 ok(ptr == NULL || broken(ptr != NULL) /* winxp sp0 */, "got %p\n", ptr); 477 ok(errno == ENOMEM || broken(errno == 0) /* winxp, win2k3 */, "got errno %d\n", errno); 478 free(ptr); 479 } 480 481 START_TEST(heap) 482 { 483 void *mem; 484 485 mem = malloc(0); 486 ok(mem != NULL, "memory not allocated for size 0\n"); 487 free(mem); 488 489 mem = realloc(NULL, 10); 490 ok(mem != NULL, "memory not allocated\n"); 491 492 mem = realloc(mem, 20); 493 ok(mem != NULL, "memory not reallocated\n"); 494 495 mem = realloc(mem, 0); 496 ok(mem == NULL, "memory not freed\n"); 497 498 mem = realloc(NULL, 0); 499 ok(mem != NULL, "memory not (re)allocated for size 0\n"); 500 501 free(mem); 502 503 test_aligned(); 504 test_sbheap(); 505 test_calloc(); 506 } 507