Commit 28cae4f8 authored by Swann Perarnau's avatar Swann Perarnau

[feature] add an inner-malloc util function

Add a set of macros to help us deal with several mallocs back-to-back in
creators, while ensuring that pointers stay aligned properly.

See #45 for details. Related to the !68 cleanup.
parent d69071fc
......@@ -28,8 +28,9 @@ include_aml_tiling_HEADERS = \
include_amlutilsdir=$(includedir)/aml/utils
include_amlutils_HEADERS = \
aml/utils/vector.h \
aml/utils/bitmap.h \
aml/utils/version.h \
aml/utils/error.h
aml/utils/error.h \
aml/utils/inner-malloc.h \
aml/utils/vector.h \
aml/utils/version.h
......@@ -35,6 +35,7 @@
#include "aml/utils/bitmap.h"
#include "aml/utils/error.h"
#include "aml/utils/inner-malloc.h"
#include "aml/utils/vector.h"
#include "aml/utils/version.h"
......
/*******************************************************************************
* Copyright 2019 UChicago Argonne, LLC.
* (c.f. AUTHORS, LICENSE)
*
* This file is part of the AML project.
* For more info, see https://xgitlab.cels.anl.gov/argo/aml
*
* SPDX-License-Identifier: BSD-3-Clause
*******************************************************************************/
#ifndef AML_INNER_MALLOC_H
#define AML_INNER_MALLOC_H
/**
* @defgroup aml_inner_malloc "AML Internal Allocation Management"
* @brief AML helper functions to handle inner allocations
* @{
*
* Set of macros to create properly sized allocations of our internal complex
* objects. In particular, help with the generic handle and implementation
* specific data allocation as a single allocation, with all pointer properly
* aligned.
*
* This code is all macros to handle the type specific logic we need.
**/
/** Returns the allocation size required to handle two objects side-by-side.
*
* Use an anonymous struct to ask the compiler what size an allocation should be
* so that the second object is properly aligned too.
*/
#define AML_SIZEOF_ALIGNED(a, b) \
(sizeof(struct { a __e1; b __e2; }))
/** Returns the offset of the second object when allocated side-by-side.
*
* Use the same anonymous struct trick to figure out what offset the pointer is
* at.
*/
#define AML_OFFSETOF_ALIGNED(a, b) \
(offsetof(struct { a __e1; b __e2; }, __e2))
/** Allocate a pointer that can be used to contain two types.
*
**/
#define AML_INNER_MALLOC_2(a, b) calloc(1, AML_SIZEOF_ALIGNED(a, b))
/** Returns the next pointer after an AML_INNER_MALLOC.
*
* Can be used to iterate over the pointers we need, using the last two types as
* parameters.
**/
#define AML_INNER_MALLOC_NEXTPTR(ptr, a, b) \
(void *)(((intptr_t) ptr) + AML_OFFSETOF_ALIGNED(a, b))
/**
* @}
**/
#endif //AML_INNER_MALLOC_H
......@@ -8,8 +8,10 @@ if TEST_VALGRIND
TESTS_ENVIRONMENT= @LIBTOOL@ --mode=execute @VALGRIND@ --tool=memcheck -q --leak-check=full
endif
UTILS_TESTS = utils/test_vector \
UTILS_TESTS = \
utils/test_bitmap \
utils/test_inner_malloc \
utils/test_vector \
utils/test_version
AREA_TESTS = \
......
/*******************************************************************************
* Copyright 2019 UChicago Argonne, LLC.
* (c.f. AUTHORS, LICENSE)
*
* This file is part of the AML project.
* For more info, see https://xgitlab.cels.anl.gov/argo/aml
*
* SPDX-License-Identifier: BSD-3-Clause
*******************************************************************************/
#include "aml.h"
#include <assert.h>
int main(void)
{
assert(AML_SIZEOF_ALIGN_GENERIC(16, size_t) % 16 == 0);
assert(AML_SIZEOF_ALIGN_GENERIC(16, char) % 16 == 0);
assert(AML_SIZEOF_ALIGN_DEFAULT(struct aml_area) %
AML_DEFAULT_INNER_MALLOC_ALIGN == 0);
intptr_t *ptr = AML_INNER_MALLOC_2(void *, void *);
assert(ptr != NULL);
void *b = AML_INNER_MALLOC_NEXTPTR(ptr, void *);
assert(b == &ptr[1]);
free(ptr);
return 0;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment