tech-userlevel archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: aligned_alloc c11 function



Hi everyone, here is the second take on aligned_alloc,
I have incorporated the changes suggested by Christos and Robert Elz.

Ok to commit?

Regards,
Niclas Rosenvik



/* $NetBSD$ */

/*-
 * 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 - 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;
}
? lib/libc/stdlib/aligned_alloc.c
Index: distrib/sets/lists/base/shl.mi
===================================================================
RCS file: /cvsroot/src/distrib/sets/lists/base/shl.mi,v
retrieving revision 1.751
diff -u -r1.751 shl.mi
--- distrib/sets/lists/base/shl.mi	25 Sep 2015 10:30:36 -0000	1.751
+++ distrib/sets/lists/base/shl.mi	31 Oct 2015 11:50:00 -0000
@@ -18,7 +18,7 @@
 ./lib/libblacklist.so.0.0			base-sys-shlib		dynamicroot
 ./lib/libc.so					base-sys-shlib		dynamicroot
 ./lib/libc.so.12				base-sys-shlib		dynamicroot
-./lib/libc.so.12.197				base-sys-shlib		dynamicroot
+./lib/libc.so.12.198				base-sys-shlib		dynamicroot
 ./lib/libcrypt.so				base-sys-shlib		dynamicroot
 ./lib/libcrypt.so.1				base-sys-shlib		dynamicroot
 ./lib/libcrypt.so.1.0				base-sys-shlib		dynamicroot
@@ -209,7 +209,7 @@
 ./usr/lib/libc++.so.1.0				base-sys-shlib		compatfile,libcxx
 ./usr/lib/libc.so				base-sys-shlib		compatfile
 ./usr/lib/libc.so.12				base-sys-shlib		compatfile
-./usr/lib/libc.so.12.197			base-sys-shlib		compatfile
+./usr/lib/libc.so.12.198			base-sys-shlib		compatfile
 ./usr/lib/libcdk.so				base-obsolete		compatfile,obsolete
 ./usr/lib/libcom_err.so				base-krb5-shlib		compatfile,kerberos
 ./usr/lib/libcom_err.so.7			base-krb5-shlib		compatfile,kerberos
Index: distrib/sets/lists/comp/mi
===================================================================
RCS file: /cvsroot/src/distrib/sets/lists/comp/mi,v
retrieving revision 1.1998
diff -u -r1.1998 mi
--- distrib/sets/lists/comp/mi	14 Oct 2015 15:20:44 -0000	1.1998
+++ distrib/sets/lists/comp/mi	31 Oct 2015 11:50:08 -0000
@@ -11888,6 +11888,7 @@
 ./usr/share/man/html3/aio_suspend.html		comp-c-htmlman		html
 ./usr/share/man/html3/aio_write.html		comp-c-htmlman		html
 ./usr/share/man/html3/alarm.html		comp-c-htmlman		html
+./usr/share/man/html3/aligned_alloc.html	comp-c-htmlman		html
 ./usr/share/man/html3/alloca.html		comp-c-htmlman		html
 ./usr/share/man/html3/allocaddrinfo.html	comp-c-htmlman		html
 ./usr/share/man/html3/alphasort.html		comp-c-htmlman		html
@@ -18689,6 +18690,7 @@
 ./usr/share/man/man3/aio_suspend.3		comp-c-man		.man
 ./usr/share/man/man3/aio_write.3		comp-c-man		.man
 ./usr/share/man/man3/alarm.3			comp-c-man		.man
+./usr/share/man/man3/aligned_alloc.3		comp-c-man		.man
 ./usr/share/man/man3/alloca.3			comp-c-man		.man
 ./usr/share/man/man3/allocaddrinfo.3		comp-c-man		.man
 ./usr/share/man/man3/alphasort.3		comp-c-man		.man
Index: include/stdlib.h
===================================================================
RCS file: /cvsroot/src/include/stdlib.h,v
retrieving revision 1.115
diff -u -r1.115 stdlib.h
--- include/stdlib.h	17 Feb 2015 20:33:40 -0000	1.115
+++ include/stdlib.h	31 Oct 2015 11:50:43 -0000
@@ -234,6 +234,7 @@
 
 #if defined(_ISOC11_SOURCE) || (__STDC_VERSION__ - 0) >= 201101L || \
     defined(_NETBSD_SOURCE) || (__cplusplus - 0) >= 201103L
+void	*aligned_alloc(size_t, size_t);
 int	at_quick_exit(void (*)(void));
 __dead void quick_exit(int);
 #endif
Index: lib/libc/shlib_version
===================================================================
RCS file: /cvsroot/src/lib/libc/shlib_version,v
retrieving revision 1.258
diff -u -r1.258 shlib_version
--- lib/libc/shlib_version	16 Jan 2015 18:45:01 -0000	1.258
+++ lib/libc/shlib_version	31 Oct 2015 11:50:43 -0000
@@ -42,4 +42,4 @@
 # - move gethostbyname to a compat library
 # - remove arc4random(3) API
 major=12
-minor=197
+minor=198
Index: lib/libc/stdlib/Makefile.inc
===================================================================
RCS file: /cvsroot/src/lib/libc/stdlib/Makefile.inc,v
retrieving revision 1.90
diff -u -r1.90 Makefile.inc
--- lib/libc/stdlib/Makefile.inc	1 May 2015 14:17:56 -0000	1.90
+++ lib/libc/stdlib/Makefile.inc	31 Oct 2015 11:50:43 -0000
@@ -5,7 +5,7 @@
 .PATH: ${ARCHDIR}/stdlib ${.CURDIR}/stdlib
 
 SRCS+=	_env.c _rand48.c \
-	a64l.c abort.c atexit.c atof.c atoi.c atol.c atoll.c \
+	a64l.c abort.c aligned_alloc.c atexit.c atof.c atoi.c atol.c atoll.c \
 	bsearch.c drand48.c exit.c \
 	getenv.c getopt.c getopt_long.c getsubopt.c \
 	hcreate.c heapsort.c imaxdiv.c insque.c jrand48.c l64a.c lldiv.c \
@@ -74,6 +74,7 @@
 MLINKS+=insque.3 remque.3
 MLINKS+=lsearch.3 lfind.3
 MLINKS+=malloc.3 calloc.3 malloc.3 realloc.3 malloc.3 free.3
+MLINKS+=posix_memalign.3 aligned_alloc.3
 MLINKS+=qsort.3 heapsort.3 qsort.3 mergesort.3
 MLINKS+=ptsname.3 ptsname_r.3
 MLINKS+=rand.3 rand_r.3
Index: lib/libc/stdlib/malloc.3
===================================================================
RCS file: /cvsroot/src/lib/libc/stdlib/malloc.3,v
retrieving revision 1.44
diff -u -r1.44 malloc.3
--- lib/libc/stdlib/malloc.3	26 Jul 2015 22:32:03 -0000	1.44
+++ lib/libc/stdlib/malloc.3	31 Oct 2015 11:50:43 -0000
@@ -252,7 +252,8 @@
 .Xr getpagesize 3 ,
 .Xr memory 3 ,
 .Xr posix_memalign 3 ,
-.Xr reallocarr 3
+.Xr reallocarr 3 ,
+.Xr aligned_alloc 3
 .Pp
 For the implementation details, see
 .Xr jemalloc 3 .
Index: lib/libc/stdlib/posix_memalign.3
===================================================================
RCS file: /cvsroot/src/lib/libc/stdlib/posix_memalign.3,v
retrieving revision 1.1
diff -u -r1.1 posix_memalign.3
--- lib/libc/stdlib/posix_memalign.3	19 Nov 2007 14:48:43 -0000	1.1
+++ lib/libc/stdlib/posix_memalign.3	31 Oct 2015 11:50:43 -0000
@@ -29,11 +29,11 @@
 .\"
 .\" FreeBSD: src/lib/libc/stdlib/posix_memalign.3,v 1.3 2007/03/28 04:32:51 jasone Exp
 .\"
-.Dd November 19, 2007
+.Dd October 30, 2015
 .Dt POSIX_MEMALIGN 3
 .Os
 .Sh NAME
-.Nm posix_memalign
+.Nm posix_memalign , aligned_alloc
 .Nd aligned memory allocation
 .Sh LIBRARY
 .Lb libc
@@ -41,23 +41,39 @@
 .In stdlib.h
 .Ft int
 .Fn posix_memalign "void **ptr" "size_t alignment" "size_t size"
+.Ft void *
+.Fn aligned_alloc "size_t alignment" "size_t size"
 .Sh DESCRIPTION
 The
 .Fn posix_memalign
 function allocates
 .Fa size
 bytes of memory such that the allocation's base address is an even multiple of
-.Fa alignment ,
+.Fa alignment , 
 and returns the allocation in the value pointed to by
 .Fa ptr .
-.Pp
 The requested
 .Fa alignment
 must be a power of 2 at least as large as
-.Fn sizeof "void *" .
+.Fn sizeof "void *".
+.Pp
+The
+.Fn aligned_alloc
+function allocates
+.Fa size
+bytes of memory such that the allocation's base address is an even multiple of
+.Fa alignment .
+The requested
+.Fa alignment
+must be a power of 2 and
+.Fa size
+must be a integer multiple of
+.Fa alignment .
 .Pp
 Memory that is allocated via
 .Fn posix_memalign
+or
+.Fn aligned_alloc
 can be used as an argument in subsequent calls to
 .Xr realloc 3
 and
@@ -66,19 +82,49 @@
 The
 .Fn posix_memalign
 function returns the value 0 if successful; otherwise it returns an error value.
+.Pp
+The
+.Fn aligned_alloc
+function returns a pointer to the allocated memory is successful; on failure it
+returns NULL and sets
+.Fa errno
+to indicate the error.
 .Sh ERRORS
 The
 .Fn posix_memalign
-function will fail if:
+and
+.Fn aligned_alloc
+functions will fail if:
 .Bl -tag -width Er
 .It Bq Er EINVAL
 The
 .Fa alignment
-parameter is not a power of 2 at least as large as
-.Fn sizeof "void *" .
+parameter is not a power of 2.
 .It Bq Er ENOMEM
 Memory allocation error.
 .El
+.Pp
+The
+.Fn posix_memalign
+function will also fail if
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The
+.Fa alignment
+parameter is not at least as large as
+.Fn sizeof "void *" .
+.El
+.Pp
+The
+.Fn aligned_alloc
+function will also fail if
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The
+.Fa size
+parameter is not an integer multiple of
+.Fa alignment .
+.El
 .Sh SEE ALSO
 .Xr free 3 ,
 .Xr malloc 3 ,
@@ -89,3 +135,7 @@
 .Fn posix_memalign
 function conforms to
 .St -p1003.1-2001 .
+The
+.Fn aligned_alloc
+function conforms to
+.St -isoC-2011 .
Index: lib/librumpuser/rumpuser_port.h
===================================================================
RCS file: /cvsroot/src/lib/librumpuser/rumpuser_port.h,v
retrieving revision 1.46
diff -u -r1.46 rumpuser_port.h
--- lib/librumpuser/rumpuser_port.h	21 Sep 2015 21:50:16 -0000	1.46
+++ lib/librumpuser/rumpuser_port.h	31 Oct 2015 11:50:44 -0000
@@ -12,6 +12,7 @@
  */
 #if !defined(RUMPUSER_CONFIG)
 
+#define HAVE_ALIGNED_ALLOC 1
 #define HAVE_ARC4RANDOM_BUF 1
 #define HAVE_CHFLAGS 1
 #define HAVE_CLOCKID_T 1
Index: tests/lib/libc/stdlib/t_posix_memalign.c
===================================================================
RCS file: /cvsroot/src/tests/lib/libc/stdlib/t_posix_memalign.c,v
retrieving revision 1.2
diff -u -r1.2 t_posix_memalign.c
--- tests/lib/libc/stdlib/t_posix_memalign.c	7 Jul 2011 11:12:18 -0000	1.2
+++ tests/lib/libc/stdlib/t_posix_memalign.c	31 Oct 2015 11:50:52 -0000
@@ -80,9 +80,57 @@
 	}
 }
 
+
+ATF_TC(aligned_alloc_basic);
+ATF_TC_HEAD(aligned_alloc_basic, tc)
+{
+	atf_tc_set_md_var(tc, "descr", "Checks aligned_alloc(3)");
+}
+ATF_TC_BODY(aligned_alloc_basic, tc)
+{
+	static const size_t size[] = {
+		1, 2, 3, 4, 10, 100, 16384, 32768, 65536, 10000
+	};
+	static const size_t align[] = {
+		512, 1024, 16, 32, 64, 4, 2048, 16, 2, 2048
+	};
+
+	size_t i;
+	void *p;
+
+	for (i = 0; i < __arraycount(size); i++) {
+		(void)printf("Checking aligned_alloc(%zu, %zu)...\n",
+		    align[i], size[i]);
+		p = aligned_alloc(align[i], size[i]);
+                if (p == NULL) {
+                    if (align[i] % 2 != 0 || size[i] % align[i] != 0) {
+                        ATF_REQUIRE_EQ_MSG(errno, EINVAL,
+                            "aligned_alloc: %s", strerror(errno));
+                    }
+                    else {
+                        ATF_REQUIRE_EQ_MSG(errno, ENOMEM,
+			    "aligned_alloc: %s", strerror(errno));
+                    }
+                }
+		else {
+                    ATF_REQUIRE_EQ_MSG(align[i] % 2, 0,
+                        "aligned_alloc: success when alignment was not"
+                        "a power of 2");
+                    ATF_REQUIRE_EQ_MSG(size[i] % align[i], 0,
+			"aligned_alloc: success when size was not an"
+                        "integer multiple of alignment");
+		    ATF_REQUIRE_EQ_MSG(((intptr_t)p) & (align[i] - 1), 0,
+			"p = %p", p);
+		    free(p);
+		}
+	}
+}
+
+
 ATF_TP_ADD_TCS(tp)
 {
 	ATF_TP_ADD_TC(tp, posix_memalign_basic);
+        ATF_TP_ADD_TC(tp, aligned_alloc_basic);
 
 	return atf_no_error();
 }


Home | Main Index | Thread Index | Old Index