diff options
Diffstat (limited to 'lib/libc/stdlib/aligned_alloc.c')
| -rw-r--r-- | lib/libc/stdlib/aligned_alloc.c | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/lib/libc/stdlib/aligned_alloc.c b/lib/libc/stdlib/aligned_alloc.c new file mode 100644 index 00000000000..ab116333a43 --- /dev/null +++ b/lib/libc/stdlib/aligned_alloc.c @@ -0,0 +1,70 @@ +/* $NetBSD: aligned_alloc.c,v 1.1 2015/11/07 16:21:42 nros Exp $ */ + +/*- + * Copyright (C) 2015 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Niclas Rosenvik. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice(s), this list of conditions and the following disclaimer as + * the first lines of this file unmodified other than the possible + * addition of one or more copyright notices. + * 2. Redistributions in binary form must reproduce the above copyright + * notice(s), this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <errno.h> +#include <stdlib.h> + +void * +aligned_alloc(size_t alignment, size_t size) +{ + void *memptr; + int err; + + /* + * Check that alignment is a power of 2 + * and that size is an integer multiple of alignment. + */ + if (alignment == 0 || ((alignment - 1) & alignment) != 0 || + (size & (alignment-1)) != 0) { + errno = EINVAL; + return NULL; + } + + /* + * Adjust alignment to satisfy posix_memalign, + * larger alignments satisfy smaller alignments. + */ + while (alignment < sizeof(void *)) { + alignment <<= 1; + } + + err = posix_memalign(&memptr, alignment, size); + + if (err) { + errno = err; + return NULL; + } + + return memptr; +} |
