diff options
Diffstat (limited to 'include/asterisk')
-rw-r--r-- | include/asterisk/stringfields.h | 12 | ||||
-rw-r--r-- | include/asterisk/utils.h | 32 |
2 files changed, 39 insertions, 5 deletions
diff --git a/include/asterisk/stringfields.h b/include/asterisk/stringfields.h index 51a169604..4039bf482 100644 --- a/include/asterisk/stringfields.h +++ b/include/asterisk/stringfields.h @@ -114,6 +114,10 @@ */ typedef const char * ast_string_field; +/* the type of storage used to track how many bytes were allocated for a field */ + +typedef uint16_t ast_string_field_allocation; + /*! \internal \brief A constant empty string used for fields that have no other value @@ -123,13 +127,15 @@ extern const char *__ast_string_field_empty; /*! \internal \brief Structure used to hold a pool of space for string fields + \note base is aligned so base+used can stay aligned by incrementing used with + aligned numbers only */ struct ast_string_field_pool { struct ast_string_field_pool *prev; /*!< pointer to the previous pool, if any */ size_t size; /*!< the total size of the pool */ size_t used; /*!< the space used in the pool */ size_t active; /*!< the amount of space actively in use by fields */ - char base[0]; /*!< storage space for the fields */ + char base[0] __attribute__((aligned(sizeof(ast_string_field_allocation)))); /*!< storage space for the fields */ }; /*! @@ -293,10 +299,6 @@ void * attribute_malloc __ast_calloc_with_stringfields(unsigned int num_structs, void __ast_string_field_release_active(struct ast_string_field_pool *pool_head, const ast_string_field ptr); -/* the type of storage used to track how many bytes were allocated for a field */ - -typedef uint16_t ast_string_field_allocation; - /*! \brief Macro to provide access to the allocation field that lives immediately in front of a string field \param x Pointer to the string field diff --git a/include/asterisk/utils.h b/include/asterisk/utils.h index 44eeb5f8e..4d015f3ee 100644 --- a/include/asterisk/utils.h +++ b/include/asterisk/utils.h @@ -741,6 +741,38 @@ static void force_inline _ast_assert(int condition, const char *condition_str, #include "asterisk/strings.h" /*! + * \brief Add space and let result be a multiple of space. + * \param initial A number to add space to. + * \param space The space to add, this would typically be sizeof(sometype). + * \return The sum of initial plus space plus at most space-1. + * + * Many systems prefer integers to be stored on aligned on memory locations. + * A use case for this is when prepending length fields of type int to a buffer. + * If you keep the total used bytes a multiple of the size of the integer type, + * a next block of length+buffer will have the length field automatically + * aligned. + * + * It looks kind of ugly, but the compiler will optimize this down to 4 or 5 + * inexpensive instructions (on x86_64). + * + * Examples: + * ast_add_and_make_multiple_of(0x18, sizeof(int64_t)) ==> 0x20 + * ast_add_and_make_multiple_of(0x19, sizeof(int64_t)) ==> 0x28 + */ +#define ast_add_and_make_multiple_of(initial, space) (((initial + (2 * space - 1)) / space) * space) + +/*! + * \brief Add bytes so that result is a multiple of size. + * \param initial A number to enlarge. + * \param size The block size the number should be a multiple of. + * \return The sum of initial plus at most size-1. + * + * Similar ast_add_and_make_multiple_of, except that this doesn't add the room + * for the length object, it only ensures that the total is aligned. + */ +#define ast_make_multiple_of(initial, size) (((initial + size - 1) / size) * size) + +/*! * \brief An Entity ID is essentially a MAC address, brief and unique */ struct ast_eid { |