xref: /netbsd-src/lib/libc/stdlib/aligned_alloc.c (revision a928bc806116f599aeedad4ccd547b082d4b6267)
1*a928bc80Sriastradh /* $NetBSD: aligned_alloc.c,v 1.3 2024/08/18 18:47:20 riastradh Exp $ */
2b16a5c9dSnros 
3b16a5c9dSnros /*-
4b16a5c9dSnros  * Copyright (C) 2015 The NetBSD Foundation, Inc.
5b16a5c9dSnros  * All rights reserved.
6b16a5c9dSnros  *
7b16a5c9dSnros  * This code is derived from software contributed to The NetBSD Foundation
8b16a5c9dSnros  * by Niclas Rosenvik.
9b16a5c9dSnros  *
10b16a5c9dSnros  * Redistribution and use in source and binary forms, with or without
11b16a5c9dSnros  * modification, are permitted provided that the following conditions
12b16a5c9dSnros  * are met:
13b16a5c9dSnros  * 1. Redistributions of source code must retain the above copyright
14b16a5c9dSnros  *    notice(s), this list of conditions and the following disclaimer as
15b16a5c9dSnros  *    the first lines of this file unmodified other than the possible
16b16a5c9dSnros  *    addition of one or more copyright notices.
17b16a5c9dSnros  * 2. Redistributions in binary form must reproduce the above copyright
18b16a5c9dSnros  *    notice(s), this list of conditions and the following disclaimer in
19b16a5c9dSnros  *    the documentation and/or other materials provided with the
20b16a5c9dSnros  *    distribution.
21b16a5c9dSnros  *
22b16a5c9dSnros  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY
23b16a5c9dSnros  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24b16a5c9dSnros  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
25b16a5c9dSnros  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE
26b16a5c9dSnros  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27b16a5c9dSnros  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28b16a5c9dSnros  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
29b16a5c9dSnros  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
30b16a5c9dSnros  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
31b16a5c9dSnros  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
32b16a5c9dSnros  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33b16a5c9dSnros  */
34b16a5c9dSnros 
35*a928bc80Sriastradh #include <sys/cdefs.h>
36*a928bc80Sriastradh __RCSID("$NetBSD: aligned_alloc.c,v 1.3 2024/08/18 18:47:20 riastradh Exp $");
37*a928bc80Sriastradh 
38b16a5c9dSnros #include <errno.h>
39b16a5c9dSnros #include <stdlib.h>
40b16a5c9dSnros 
41b16a5c9dSnros void *
42b16a5c9dSnros aligned_alloc(size_t alignment, size_t size)
43b16a5c9dSnros {
44b16a5c9dSnros         void *memptr;
45b16a5c9dSnros         int err;
46b16a5c9dSnros 
47b16a5c9dSnros         /*
488d702a64Smaya          * Check that alignment is a power of 2.
49b16a5c9dSnros          */
508d702a64Smaya         if (alignment == 0 || ((alignment - 1) & alignment) != 0) {
51b16a5c9dSnros                 errno = EINVAL;
52b16a5c9dSnros                 return NULL;
53b16a5c9dSnros         }
54b16a5c9dSnros 
55b16a5c9dSnros         /*
56b16a5c9dSnros          * Adjust alignment to satisfy posix_memalign,
57b16a5c9dSnros          * larger alignments satisfy smaller alignments.
58b16a5c9dSnros          */
59b16a5c9dSnros         while (alignment < sizeof(void *)) {
60b16a5c9dSnros                 alignment <<= 1;
61b16a5c9dSnros         }
62b16a5c9dSnros 
63b16a5c9dSnros         err = posix_memalign(&memptr, alignment, size);
64b16a5c9dSnros         if (err) {
65b16a5c9dSnros                 errno = err;
66b16a5c9dSnros                 return NULL;
67b16a5c9dSnros         }
68b16a5c9dSnros 
69b16a5c9dSnros         return memptr;
70b16a5c9dSnros }
71