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