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
20int 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