1 /*
   2  * This file and its contents are supplied under the terms of the
   3  * Common Development and Distribution License ("CDDL"), version 1.0.
   4  * You may only use this file in accordance with the terms of version
   5  * 1.0 of the CDDL.
   6  *
   7  * A full copy of the text of the CDDL should have accompanied this
   8  * source.  A copy of the CDDL is also available via the Internet at
   9  * http://www.illumos.org/license/CDDL.
  10  */
  11 
  12 /*
  13  * Copyright 2016 Joyent, Inc.
  14  */
  15 
  16 /*
  17  * Basic tests for posix_memalign(3C). Note that we test ENOMEM failure by
  18  * relying on the implementation of the current libc malloc. Specifically we go
  19  * through and add a mapping so we can't expand the heap and then use it up. If
  20  * the memory allocator is ever changed, this test will start failing, at which
  21  * point, it may not be worth the cost of keeping it around.
  22  */
  23 
  24 #include <stdlib.h>
  25 #include <errno.h>
  26 #include <libproc.h>
  27 #include <sys/sysmacros.h>
  28 #include <sys/mman.h>
  29 #include <sys/debug.h>
  30 
  31 int
  32 main(void)
  33 {
  34         pstatus_t status;
  35         /*
  36          * We use a non-NULL value, so we can verify that failure does not
  37          * change the value of 'buf'
  38          */
  39         void *sentinel = (void *)0xbad00000;
  40         void *buf = sentinel;
  41         int err = 0;
  42 
  43         /*
  44          * Alignment must be sizeof (void *) (word) aligned.
  45          */
  46         err = posix_memalign(&buf, sizeof (void *) - 1, 16);
  47         VERIFY3S(err, ==, EINVAL);
  48         VERIFY3P(buf, ==, sentinel);
  49 
  50         err = posix_memalign(&buf, sizeof (void *) + 1, 16);
  51         VERIFY3S(err, ==, EINVAL);
  52         VERIFY3P(buf, ==, sentinel);
  53 
  54         err = posix_memalign(&buf, 23, 16);
  55         VERIFY3S(err, ==, EINVAL);
  56         VERIFY3P(buf, ==, sentinel);
  57 
  58         err = posix_memalign(&buf, sizeof (void *), 16);
  59         VERIFY3S(err, ==, 0);
  60         VERIFY3B(IS_P2ALIGNED(buf, sizeof (void *)), ==, B_TRUE);
  61         VERIFY3P(buf, !=, sentinel);
  62         VERIFY3P(buf, !=, NULL);
  63         free(buf);
  64         buf = sentinel;
  65 
  66         /*
  67          * Cause ENOMEM
  68          */
  69         VERIFY0(proc_get_status(getpid(), &status));
  70         VERIFY3P(mmap((caddr_t)P2ROUNDUP(status.pr_brkbase +
  71             status.pr_brksize, 0x1000), 0x1000,
  72             PROT_READ, MAP_ANON | MAP_FIXED | MAP_PRIVATE, -1, 0),
  73             !=, (void *)-1);
  74 
  75         for (;;) {
  76                 if (malloc(16) == NULL)
  77                         break;
  78         }
  79 
  80 
  81         for (;;) {
  82                 if (posix_memalign(&buf, sizeof (void *), 16) == ENOMEM)
  83                         break;
  84         }
  85 
  86         buf = sentinel;
  87         err = posix_memalign(&buf, sizeof (void *), 16);
  88         VERIFY3S(err, ==, ENOMEM);
  89         VERIFY3P(buf, ==, sentinel);
  90 
  91         return (0);
  92 }