xref: /illumos-gate/usr/src/test/libc-tests/tests/posix_memalign.c (revision 8a2b682e57a046b828f37bcde1776f131ef4629f)
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 }
93