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