1 2 // These #defines attempt to ensure that posix_memalign() is declared, and 3 // so no spurious warning is given about using it. 4 5 // Advertise compliance of the code to the XSI (a POSIX superset that 6 // defines what a system must be like to be called "UNIX") 7 #undef _XOPEN_SOURCE 8 #define _XOPEN_SOURCE 600 9 10 // Advertise compliance to POSIX 11 #undef _POSIX_C_SOURCE 12 #define _POSIX_C_SOURCE 200112L 13 14 #include <stdlib.h> 15 #include <stdio.h> 16 #include <assert.h> 17 #include "tests/malloc.h" 18 #include <errno.h> 19 20 int main ( void ) 21 { 22 # if defined(VGO_darwin) 23 // Mac OS X has neither memalign() nor posix_memalign(); do nothing. 24 // Still true for 10.6 / 10.7 ? 25 26 # else 27 // Nb: assuming VG_MIN_MALLOC_SZB is 8 or more... 28 int* p; 29 int* piece; 30 int res; 31 assert(sizeof(long int) == sizeof(void*)); 32 33 // Check behaviour of memalign/free for big alignment. 34 // In particular, the below aims at checking that a 35 // superblock with a big size is not marked as reclaimable 36 // if the superblock is used to provide a big aligned block 37 // (see bug 250101, comment #14). 38 // Valgrind m_mallocfree.c will allocate a big superblock for the memalign 39 // call and will split it in two. This splitted superblock was 40 // wrongly marked as reclaimable, which was then causing 41 // assert failures (as reclaimable blocks cannot be splitted). 42 p = memalign(1024 * 1024, 4 * 1024 * 1024 + 1); assert(0 == (long)p % (1024 * 1024)); 43 // We allocate (and then free) a piece of memory smaller than 44 // the hole created in the big superblock. 45 // If the superblock is marked as reclaimable, the below free(s) will cause 46 // an assert. Note that the test has to be run with a --free-list-vol 47 // parameter smaller than the released blocks size to ensure the free is directly 48 // executed (otherwise memcheck does not really release the memory and so 49 // the bug is not properly tested). 50 piece = malloc(1024 * 1000); assert (piece); 51 free (piece); 52 free (p); 53 54 // Same as above but do the free in the reverse order. 55 p = memalign(1024 * 1024, 4 * 1024 * 1024 + 1); assert(0 == (long)p % (1024 * 1024)); 56 piece = malloc(1024 * 100); assert (piece); 57 free (p); 58 free (piece); 59 60 p = memalign(0, 100); assert(0 == (long)p % 8); 61 p = memalign(1, 100); assert(0 == (long)p % 8); 62 p = memalign(2, 100); assert(0 == (long)p % 8); 63 p = memalign(3, 100); assert(0 == (long)p % 8); 64 p = memalign(4, 100); assert(0 == (long)p % 8); 65 p = memalign(5, 100); assert(0 == (long)p % 8); 66 67 p = memalign(7, 100); assert(0 == (long)p % 8); 68 p = memalign(8, 100); assert(0 == (long)p % 8); 69 p = memalign(9, 100); assert(0 == (long)p % 16); 70 71 p = memalign(31, 100); assert(0 == (long)p % 32); 72 p = memalign(32, 100); assert(0 == (long)p % 32); 73 p = memalign(33, 100); assert(0 == (long)p % 64); 74 75 p = memalign(4095, 100); assert(0 == (long)p % 4096); 76 p = memalign(4096, 100); assert(0 == (long)p % 4096); 77 p = memalign(4097, 100); assert(0 == (long)p % 8192); 78 79 80 # define PM(a,b,c) posix_memalign((void**)a, b, c) 81 82 res = PM(&p, -1,100); assert(EINVAL == res); 83 res = PM(&p, 0, 100); assert(0 == res && 0 == (long)p % 8); 84 res = PM(&p, 1, 100); assert(EINVAL == res); 85 res = PM(&p, 2, 100); assert(EINVAL == res); 86 res = PM(&p, 3, 100); assert(EINVAL == res); 87 res = PM(&p, sizeof(void*), 100); 88 assert(0 == res && 0 == (long)p % sizeof(void*)); 89 90 res = PM(&p, 31, 100); assert(EINVAL == res); 91 res = PM(&p, 32, 100); assert(0 == res && 92 0 == (long)p % 32); 93 res = PM(&p, 33, 100); assert(EINVAL == res); 94 95 res = PM(&p, 4095, 100); assert(EINVAL == res); 96 res = PM(&p, 4096, 100); assert(0 == res && 97 0 == (long)p % 4096); 98 res = PM(&p, 4097, 100); assert(EINVAL == res); 99 100 # endif 101 102 return 0; 103 } 104