Home | History | Annotate | Download | only in tests
      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