Browse Source

Implement C11's aligned_alloc(3). ok guenther@

OPENBSD_6_5
otto 5 years ago
parent
commit
e4341e950b
3 changed files with 90 additions and 6 deletions
  1. +6
    -1
      src/include/stdlib.h
  2. +41
    -4
      src/lib/libc/stdlib/malloc.3
  3. +43
    -1
      src/lib/libc/stdlib/malloc.c

+ 6
- 1
src/include/stdlib.h View File

@ -1,4 +1,4 @@
/* $OpenBSD: stdlib.h,v 1.72 2017/09/05 03:16:13 schwarze Exp $ */
/* $OpenBSD: stdlib.h,v 1.73 2018/11/05 08:23:40 otto Exp $ */
/* $NetBSD: stdlib.h,v 1.25 1995/12/27 21:19:08 jtc Exp $ */
/*-
@ -221,6 +221,11 @@ unsigned long long
strtoull(const char *__restrict, char **__restrict, int);
#endif
#if __ISO_C_VISIBLE >= 2011
void *
aligned_alloc(size_t, size_t);
#endif
/*
* The Open Group Base Specifications, Issue 6; IEEE Std 1003.1-2001 (POSIX)
*/


+ 41
- 4
src/lib/libc/stdlib/malloc.3 View File

@ -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 ,


+ 43
- 1
src/lib/libc/stdlib/malloc.c View File

@ -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 {


Loading…
Cancel
Save