diff options
author | Otto Moerbeek <otto@cvs.openbsd.org> | 2018-11-05 08:23:41 +0000 |
---|---|---|
committer | Otto Moerbeek <otto@cvs.openbsd.org> | 2018-11-05 08:23:41 +0000 |
commit | cecf1f096e82006d6c9e3371fdea05125f38e03e (patch) | |
tree | abc4ae1480031cdbb165dec6efe69ca14084cd4e /lib/libc/stdlib | |
parent | 57933f13bb51bbf48a0c323eca44b7457aa56b98 (diff) |
Implement C11's aligned_alloc(3). ok guenther@
Diffstat (limited to 'lib/libc/stdlib')
-rw-r--r-- | lib/libc/stdlib/malloc.3 | 45 | ||||
-rw-r--r-- | lib/libc/stdlib/malloc.c | 44 |
2 files changed, 84 insertions, 5 deletions
diff --git a/lib/libc/stdlib/malloc.3 b/lib/libc/stdlib/malloc.3 index 1f5d9c71044..71c329f9ece 100644 --- a/lib/libc/stdlib/malloc.3 +++ b/lib/libc/stdlib/malloc.3 @@ -30,9 +30,9 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $OpenBSD: malloc.3,v 1.115 2017/05/15 18:05:34 tb Exp $ +.\" $OpenBSD: malloc.3,v 1.116 2018/11/05 08:23:40 otto Exp $ .\" -.Dd $Mdocdate: May 15 2017 $ +.Dd $Mdocdate: November 5 2018 $ .Dt MALLOC 3 .Os .Sh NAME @@ -42,7 +42,8 @@ .Nm free , .Nm reallocarray , .Nm recallocarray , -.Nm freezero +.Nm freezero , +.Nm aligned_alloc .Nd memory allocation and deallocation .Sh SYNOPSIS .In stdlib.h @@ -60,6 +61,8 @@ .Fn recallocarray "void *ptr" "size_t oldnmemb" "size_t nmemb" "size_t size" .Ft void .Fn freezero "void *ptr" "size_t size" +.Ft void * +.Fn aligned_alloc "size_t alignment" "size_t size" .Vt char *malloc_options ; .Sh DESCRIPTION The standard functions @@ -206,7 +209,7 @@ is not .Dv NULL , the .Fa size -argument must be equal or smaller than the size of the earlier allocation +argument must be equal to or smaller than the size of the earlier allocation that returned .Fa ptr . .Fn freezero @@ -215,6 +218,21 @@ guarantees the memory range starting at with length .Fa size is discarded while deallocating the whole object originally allocated. +.Pp +The +.Fn aligned_alloc +function allocates +.Fa size +bytes of memory such that the allocation's base address is a multiple of +.Fa alignment . +The requested +.Fa alignment +must be a power of 2. +If +.Fa size +is not a multiple of +.Fa alignment , +behavior is undefined. .Sh RETURN VALUES Upon successful completion, the allocation functions return a pointer to the allocated space; otherwise, @@ -223,6 +241,17 @@ is returned and .Va errno is set to .Er ENOMEM . +The function +.Fn aligned_alloc +returns +.Dv NULL +and sets +.Va errno +to +.Er EINVAL +if +.Fa alignment +is not a power of 2. .Pp If .Fa nmemb @@ -514,6 +543,10 @@ and .Fn free functions conform to .St -ansiC . +The +.Fn aligned_alloc +function conforms to +.St -isoC-2011 . .Pp If .Fa nmemb @@ -588,6 +621,10 @@ The .Fn freezero function appeared in .Ox 6.2 . +The +.Fn aligned_alloc +function appeared in +.Ox 6.5 . .Sh CAVEATS When using .Fn malloc , diff --git a/lib/libc/stdlib/malloc.c b/lib/libc/stdlib/malloc.c index 81c30812a46..70e7f37dc82 100644 --- a/lib/libc/stdlib/malloc.c +++ b/lib/libc/stdlib/malloc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: malloc.c,v 1.249 2018/04/07 09:57:08 otto Exp $ */ +/* $OpenBSD: malloc.c,v 1.250 2018/11/05 08:23:40 otto Exp $ */ /* * Copyright (c) 2008, 2010, 2011, 2016 Otto Moerbeek <otto@drijf.net> * Copyright (c) 2012 Matthew Dempsky <matthew@openbsd.org> @@ -2058,6 +2058,48 @@ err: } /*DEF_STRONG(posix_memalign);*/ +void * +aligned_alloc(size_t alignment, size_t size) +{ + struct dir_info *d; + int saved_errno = errno; + void *r; + + /* Make sure that alignment is a positive power of 2. */ + if (((alignment - 1) & alignment) != 0 || alignment == 0) { + errno = EINVAL; + return NULL; + }; + /* Per spec, size should be a multiple of alignment */ + if ((size & (alignment - 1)) != 0) { + errno = EINVAL; + return NULL; + } + + d = getpool(); + if (d == NULL) { + _malloc_init(0); + d = getpool(); + } + _MALLOC_LOCK(d->mutex); + d->func = "aligned_alloc"; + if (d->active++) { + malloc_recurse(d); + return NULL; + } + r = omemalign(d, alignment, size, 0, CALLER); + d->active--; + _MALLOC_UNLOCK(d->mutex); + if (r == NULL) { + if (mopts.malloc_xmalloc) + wrterror(d, "out of memory"); + return NULL; + } + errno = saved_errno; + return r; +} +/*DEF_STRONG(aligned_alloc);*/ + #ifdef MALLOC_STATS struct malloc_leak { |