diff options
| author | otto <> | 2018-11-05 08:23:40 +0000 |
|---|---|---|
| committer | otto <> | 2018-11-05 08:23:40 +0000 |
| commit | fd007b9176dd16f281fe3910e0e8296117e212ac (patch) | |
| tree | 36c7bff76bfb6fb329f5d66d3c4ba67b71576965 /src/lib/libc | |
| parent | 11d9261f23dcd7e9a09e512cc035b9c4ea3bfa69 (diff) | |
| download | openbsd-fd007b9176dd16f281fe3910e0e8296117e212ac.tar.gz openbsd-fd007b9176dd16f281fe3910e0e8296117e212ac.tar.bz2 openbsd-fd007b9176dd16f281fe3910e0e8296117e212ac.zip | |
Implement C11's aligned_alloc(3). ok guenther@
Diffstat (limited to 'src/lib/libc')
| -rw-r--r-- | src/lib/libc/stdlib/malloc.3 | 45 | ||||
| -rw-r--r-- | src/lib/libc/stdlib/malloc.c | 44 |
2 files changed, 84 insertions, 5 deletions
diff --git a/src/lib/libc/stdlib/malloc.3 b/src/lib/libc/stdlib/malloc.3 index 1f5d9c7104..71c329f9ec 100644 --- a/src/lib/libc/stdlib/malloc.3 +++ b/src/lib/libc/stdlib/malloc.3 | |||
| @@ -30,9 +30,9 @@ | |||
| 30 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 30 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 31 | .\" SUCH DAMAGE. | 31 | .\" SUCH DAMAGE. |
| 32 | .\" | 32 | .\" |
| 33 | .\" $OpenBSD: malloc.3,v 1.115 2017/05/15 18:05:34 tb Exp $ | 33 | .\" $OpenBSD: malloc.3,v 1.116 2018/11/05 08:23:40 otto Exp $ |
| 34 | .\" | 34 | .\" |
| 35 | .Dd $Mdocdate: May 15 2017 $ | 35 | .Dd $Mdocdate: November 5 2018 $ |
| 36 | .Dt MALLOC 3 | 36 | .Dt MALLOC 3 |
| 37 | .Os | 37 | .Os |
| 38 | .Sh NAME | 38 | .Sh NAME |
| @@ -42,7 +42,8 @@ | |||
| 42 | .Nm free , | 42 | .Nm free , |
| 43 | .Nm reallocarray , | 43 | .Nm reallocarray , |
| 44 | .Nm recallocarray , | 44 | .Nm recallocarray , |
| 45 | .Nm freezero | 45 | .Nm freezero , |
| 46 | .Nm aligned_alloc | ||
| 46 | .Nd memory allocation and deallocation | 47 | .Nd memory allocation and deallocation |
| 47 | .Sh SYNOPSIS | 48 | .Sh SYNOPSIS |
| 48 | .In stdlib.h | 49 | .In stdlib.h |
| @@ -60,6 +61,8 @@ | |||
| 60 | .Fn recallocarray "void *ptr" "size_t oldnmemb" "size_t nmemb" "size_t size" | 61 | .Fn recallocarray "void *ptr" "size_t oldnmemb" "size_t nmemb" "size_t size" |
| 61 | .Ft void | 62 | .Ft void |
| 62 | .Fn freezero "void *ptr" "size_t size" | 63 | .Fn freezero "void *ptr" "size_t size" |
| 64 | .Ft void * | ||
| 65 | .Fn aligned_alloc "size_t alignment" "size_t size" | ||
| 63 | .Vt char *malloc_options ; | 66 | .Vt char *malloc_options ; |
| 64 | .Sh DESCRIPTION | 67 | .Sh DESCRIPTION |
| 65 | The standard functions | 68 | The standard functions |
| @@ -206,7 +209,7 @@ is not | |||
| 206 | .Dv NULL , | 209 | .Dv NULL , |
| 207 | the | 210 | the |
| 208 | .Fa size | 211 | .Fa size |
| 209 | argument must be equal or smaller than the size of the earlier allocation | 212 | argument must be equal to or smaller than the size of the earlier allocation |
| 210 | that returned | 213 | that returned |
| 211 | .Fa ptr . | 214 | .Fa ptr . |
| 212 | .Fn freezero | 215 | .Fn freezero |
| @@ -215,6 +218,21 @@ guarantees the memory range starting at | |||
| 215 | with length | 218 | with length |
| 216 | .Fa size | 219 | .Fa size |
| 217 | is discarded while deallocating the whole object originally allocated. | 220 | is discarded while deallocating the whole object originally allocated. |
| 221 | .Pp | ||
| 222 | The | ||
| 223 | .Fn aligned_alloc | ||
| 224 | function allocates | ||
| 225 | .Fa size | ||
| 226 | bytes of memory such that the allocation's base address is a multiple of | ||
| 227 | .Fa alignment . | ||
| 228 | The requested | ||
| 229 | .Fa alignment | ||
| 230 | must be a power of 2. | ||
| 231 | If | ||
| 232 | .Fa size | ||
| 233 | is not a multiple of | ||
| 234 | .Fa alignment , | ||
| 235 | behavior is undefined. | ||
| 218 | .Sh RETURN VALUES | 236 | .Sh RETURN VALUES |
| 219 | Upon successful completion, the allocation functions | 237 | Upon successful completion, the allocation functions |
| 220 | return a pointer to the allocated space; otherwise, | 238 | return a pointer to the allocated space; otherwise, |
| @@ -223,6 +241,17 @@ is returned and | |||
| 223 | .Va errno | 241 | .Va errno |
| 224 | is set to | 242 | is set to |
| 225 | .Er ENOMEM . | 243 | .Er ENOMEM . |
| 244 | The function | ||
| 245 | .Fn aligned_alloc | ||
| 246 | returns | ||
| 247 | .Dv NULL | ||
| 248 | and sets | ||
| 249 | .Va errno | ||
| 250 | to | ||
| 251 | .Er EINVAL | ||
| 252 | if | ||
| 253 | .Fa alignment | ||
| 254 | is not a power of 2. | ||
| 226 | .Pp | 255 | .Pp |
| 227 | If | 256 | If |
| 228 | .Fa nmemb | 257 | .Fa nmemb |
| @@ -514,6 +543,10 @@ and | |||
| 514 | .Fn free | 543 | .Fn free |
| 515 | functions conform to | 544 | functions conform to |
| 516 | .St -ansiC . | 545 | .St -ansiC . |
| 546 | The | ||
| 547 | .Fn aligned_alloc | ||
| 548 | function conforms to | ||
| 549 | .St -isoC-2011 . | ||
| 517 | .Pp | 550 | .Pp |
| 518 | If | 551 | If |
| 519 | .Fa nmemb | 552 | .Fa nmemb |
| @@ -588,6 +621,10 @@ The | |||
| 588 | .Fn freezero | 621 | .Fn freezero |
| 589 | function appeared in | 622 | function appeared in |
| 590 | .Ox 6.2 . | 623 | .Ox 6.2 . |
| 624 | The | ||
| 625 | .Fn aligned_alloc | ||
| 626 | function appeared in | ||
| 627 | .Ox 6.5 . | ||
| 591 | .Sh CAVEATS | 628 | .Sh CAVEATS |
| 592 | When using | 629 | When using |
| 593 | .Fn malloc , | 630 | .Fn malloc , |
diff --git a/src/lib/libc/stdlib/malloc.c b/src/lib/libc/stdlib/malloc.c index 81c30812a4..70e7f37dc8 100644 --- a/src/lib/libc/stdlib/malloc.c +++ b/src/lib/libc/stdlib/malloc.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: malloc.c,v 1.249 2018/04/07 09:57:08 otto Exp $ */ | 1 | /* $OpenBSD: malloc.c,v 1.250 2018/11/05 08:23:40 otto Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2008, 2010, 2011, 2016 Otto Moerbeek <otto@drijf.net> | 3 | * Copyright (c) 2008, 2010, 2011, 2016 Otto Moerbeek <otto@drijf.net> |
| 4 | * Copyright (c) 2012 Matthew Dempsky <matthew@openbsd.org> | 4 | * Copyright (c) 2012 Matthew Dempsky <matthew@openbsd.org> |
| @@ -2058,6 +2058,48 @@ err: | |||
| 2058 | } | 2058 | } |
| 2059 | /*DEF_STRONG(posix_memalign);*/ | 2059 | /*DEF_STRONG(posix_memalign);*/ |
| 2060 | 2060 | ||
| 2061 | void * | ||
| 2062 | aligned_alloc(size_t alignment, size_t size) | ||
| 2063 | { | ||
| 2064 | struct dir_info *d; | ||
| 2065 | int saved_errno = errno; | ||
| 2066 | void *r; | ||
| 2067 | |||
| 2068 | /* Make sure that alignment is a positive power of 2. */ | ||
| 2069 | if (((alignment - 1) & alignment) != 0 || alignment == 0) { | ||
| 2070 | errno = EINVAL; | ||
| 2071 | return NULL; | ||
| 2072 | }; | ||
| 2073 | /* Per spec, size should be a multiple of alignment */ | ||
| 2074 | if ((size & (alignment - 1)) != 0) { | ||
| 2075 | errno = EINVAL; | ||
| 2076 | return NULL; | ||
| 2077 | } | ||
| 2078 | |||
| 2079 | d = getpool(); | ||
| 2080 | if (d == NULL) { | ||
| 2081 | _malloc_init(0); | ||
| 2082 | d = getpool(); | ||
| 2083 | } | ||
| 2084 | _MALLOC_LOCK(d->mutex); | ||
| 2085 | d->func = "aligned_alloc"; | ||
| 2086 | if (d->active++) { | ||
| 2087 | malloc_recurse(d); | ||
| 2088 | return NULL; | ||
| 2089 | } | ||
| 2090 | r = omemalign(d, alignment, size, 0, CALLER); | ||
| 2091 | d->active--; | ||
| 2092 | _MALLOC_UNLOCK(d->mutex); | ||
| 2093 | if (r == NULL) { | ||
| 2094 | if (mopts.malloc_xmalloc) | ||
| 2095 | wrterror(d, "out of memory"); | ||
| 2096 | return NULL; | ||
| 2097 | } | ||
| 2098 | errno = saved_errno; | ||
| 2099 | return r; | ||
| 2100 | } | ||
| 2101 | /*DEF_STRONG(aligned_alloc);*/ | ||
| 2102 | |||
| 2061 | #ifdef MALLOC_STATS | 2103 | #ifdef MALLOC_STATS |
| 2062 | 2104 | ||
| 2063 | struct malloc_leak { | 2105 | struct malloc_leak { |
