2 Copyright © 1995-2007, The AROS Development Team. All rights reserved.
5 POSIX function posix_memalign().
8 #include "__arosc_privdata.h"
9 #include "__memalign.h"
13 #include <exec/memory.h>
14 #include <proto/exec.h>
15 #include <aros/symbolsets.h>
16 #include <aros/debug.h>
17 #include <sys/param.h>
19 /*****************************************************************************
22 #include <sys/types.h>
33 Allocate aligned memory.
36 memptr - Pointer to a place to store the pointer to allocated memory.
37 alignment - Alignment of allocated memory. The address of the
38 allocated memory will be a multiple of this value, which
39 must be a power of two and a multiple of sizeof(void *).
40 size - How much memory to allocate.
43 Returns zero on success.
44 Returns EINVAL if the alignment parameter was not a power of two, or
45 was not a multiple of sizeof(void *).
46 Returns ENOMEM if there was insufficient memory to fulfill the request.
49 Memory allocated by posix_memalign() should be freed with free(). If
50 not, it will be freed when the program terminates.
52 This function must not be used in a shared library or in a threaded
55 If an error occurs, errno will not be set.
66 ******************************************************************************/
68 UBYTE
*mem
= NULL
, *orig
;
70 /* check the alignment is valid */
71 if (alignment
% sizeof(void *) != 0 || !powerof2(alignment
))
74 /* allocate enough space to satisfy the alignment and save some info */
75 mem
= AllocPooled(__startup_mempool
, size
+ alignment
+ AROS_ALIGN(sizeof(size_t)) + AROS_ALIGN(sizeof(void *)));
79 /* store the size for free(). it will add sizeof(size_t) itself */
80 *((size_t *) mem
) = size
+ alignment
+ AROS_ALIGN(sizeof(void *));
81 mem
+= AROS_ALIGN(sizeof(size_t));
83 /* if its already aligned correctly, then we just use it as-is */
84 if (((IPTR
) mem
& (alignment
-1)) == 0) {
91 /* move forward to an even alignment boundary */
92 mem
= (UBYTE
*) (((IPTR
) mem
+ alignment
- 1) & -alignment
);
94 /* store a magic number in the place that free() will look for the
95 * allocation size, so it can handle this specially */
96 ((size_t *) mem
)[-1] = MEMALIGN_MAGIC
;
98 /* then store the original pointer before it, for free() to find */
99 ((void **) &(((size_t *) mem
)[-1]))[-1] = orig
;
103 } /* posix_memalign */