|
@@ -423,17 +423,21 @@ void *rh_detach_region(rh_info_t * info, void *start, int size)
|
|
return (void *)s;
|
|
return (void *)s;
|
|
}
|
|
}
|
|
|
|
|
|
-void *rh_alloc(rh_info_t * info, int size, const char *owner)
|
|
|
|
|
|
+void *rh_alloc_align(rh_info_t * info, int size, int alignment, const char *owner)
|
|
{
|
|
{
|
|
struct list_head *l;
|
|
struct list_head *l;
|
|
rh_block_t *blk;
|
|
rh_block_t *blk;
|
|
rh_block_t *newblk;
|
|
rh_block_t *newblk;
|
|
void *start;
|
|
void *start;
|
|
|
|
|
|
- /* Validate size */
|
|
|
|
- if (size <= 0)
|
|
|
|
|
|
+ /* Validate size, (must be power of two) */
|
|
|
|
+ if (size <= 0 || (alignment & (alignment - 1)) != 0)
|
|
return ERR_PTR(-EINVAL);
|
|
return ERR_PTR(-EINVAL);
|
|
|
|
|
|
|
|
+ /* given alignment larger that default rheap alignment */
|
|
|
|
+ if (alignment > info->alignment)
|
|
|
|
+ size += alignment - 1;
|
|
|
|
+
|
|
/* Align to configured alignment */
|
|
/* Align to configured alignment */
|
|
size = (size + (info->alignment - 1)) & ~(info->alignment - 1);
|
|
size = (size + (info->alignment - 1)) & ~(info->alignment - 1);
|
|
|
|
|
|
@@ -476,15 +480,27 @@ void *rh_alloc(rh_info_t * info, int size, const char *owner)
|
|
|
|
|
|
attach_taken_block(info, newblk);
|
|
attach_taken_block(info, newblk);
|
|
|
|
|
|
|
|
+ /* for larger alignment return fixed up pointer */
|
|
|
|
+ /* this is no problem with the deallocator since */
|
|
|
|
+ /* we scan for pointers that lie in the blocks */
|
|
|
|
+ if (alignment > info->alignment)
|
|
|
|
+ start = (void *)(((unsigned long)start + alignment - 1) &
|
|
|
|
+ ~(alignment - 1));
|
|
|
|
+
|
|
return start;
|
|
return start;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+void *rh_alloc(rh_info_t * info, int size, const char *owner)
|
|
|
|
+{
|
|
|
|
+ return rh_alloc_align(info, size, info->alignment, owner);
|
|
|
|
+}
|
|
|
|
+
|
|
/* allocate at precisely the given address */
|
|
/* allocate at precisely the given address */
|
|
void *rh_alloc_fixed(rh_info_t * info, void *start, int size, const char *owner)
|
|
void *rh_alloc_fixed(rh_info_t * info, void *start, int size, const char *owner)
|
|
{
|
|
{
|
|
struct list_head *l;
|
|
struct list_head *l;
|
|
rh_block_t *blk, *newblk1, *newblk2;
|
|
rh_block_t *blk, *newblk1, *newblk2;
|
|
- unsigned long s, e, m, bs, be;
|
|
|
|
|
|
+ unsigned long s, e, m, bs = 0, be = 0;
|
|
|
|
|
|
/* Validate size */
|
|
/* Validate size */
|
|
if (size <= 0)
|
|
if (size <= 0)
|