diff options
author | otto <> | 2018-11-05 08:23:40 +0000 |
---|---|---|
committer | otto <> | 2018-11-05 08:23:40 +0000 |
commit | 6b72d5e8e18c526ac7df6014aad4e30541eeb0cb (patch) | |
tree | 36c7bff76bfb6fb329f5d66d3c4ba67b71576965 | |
parent | 6947abc46581e19432245e0ce409d468fb702c7d (diff) | |
download | openbsd-6b72d5e8e18c526ac7df6014aad4e30541eeb0cb.tar.gz openbsd-6b72d5e8e18c526ac7df6014aad4e30541eeb0cb.tar.bz2 openbsd-6b72d5e8e18c526ac7df6014aad4e30541eeb0cb.zip |
Implement C11's aligned_alloc(3). ok guenther@
-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 { |