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 
main(void)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    p = memalign(4 * 1024 * 1024, 100);   assert(0 == (long)p % (4 * 1024 * 1024));
80    p = memalign(16 * 1024 * 1024, 100);   assert(0 == (long)p % (16 * 1024 * 1024));
81 
82 #  define PM(a,b,c) posix_memalign((void**)a, b, c)
83 
84    res = PM(&p, -1,100);      assert(EINVAL == res);
85    res = PM(&p, 0, 100);      assert(0 == res && 0 == (long)p % 8);
86    res = PM(&p, 1, 100);      assert(EINVAL == res);
87    res = PM(&p, 2, 100);      assert(EINVAL == res);
88    res = PM(&p, 3, 100);      assert(EINVAL == res);
89    res = PM(&p, sizeof(void*), 100);
90                               assert(0 == res && 0 == (long)p % sizeof(void*));
91 
92    res = PM(&p, 31, 100);     assert(EINVAL == res);
93    res = PM(&p, 32, 100);     assert(0 == res && 0 == (long)p % 32);
94    res = PM(&p, 33, 100);     assert(EINVAL == res);
95 
96    res = PM(&p, 4095, 100);   assert(EINVAL == res);
97    res = PM(&p, 4096, 100);   assert(0 == res && 0 == (long)p % 4096);
98    res = PM(&p, 4097, 100);   assert(EINVAL == res);
99 
100    res = PM(&p, 4 * 1024 * 1024, 100);   assert(0 == res
101                                                 && 0 == (long)p % (4 * 1024 * 1024));
102    res = PM(&p, 16 * 1024 * 1024, 100);   assert(0 == res
103                                                 && 0 == (long)p % (16 * 1024 * 1024));
104 #  endif
105 
106    return 0;
107 }
108