summaryrefslogtreecommitdiff
path: root/main/utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'main/utils.c')
-rw-r--r--main/utils.c371
1 files changed, 0 insertions, 371 deletions
diff --git a/main/utils.c b/main/utils.c
index 9a400d9db..95eda1102 100644
--- a/main/utils.c
+++ b/main/utils.c
@@ -61,9 +61,6 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/time.h"
#define AST_API_MODULE /* ensure that inlinable API functions will be built in this module if required */
-#include "asterisk/stringfields.h"
-
-#define AST_API_MODULE /* ensure that inlinable API functions will be built in this module if required */
#include "asterisk/utils.h"
#define AST_API_MODULE
@@ -2028,374 +2025,6 @@ char *ast_to_camel_case_delim(const char *s, const char *delim)
return res;
}
-/*
- * stringfields support routines.
- */
-
-/* this is a little complex... string fields are stored with their
- allocated size in the bytes preceding the string; even the
- constant 'empty' string has to be this way, so the code that
- checks to see if there is enough room for a new string doesn't
- have to have any special case checks
-*/
-
-static const struct {
- ast_string_field_allocation allocation;
- char string[1];
-} __ast_string_field_empty_buffer;
-
-ast_string_field __ast_string_field_empty = __ast_string_field_empty_buffer.string;
-
-#define ALLOCATOR_OVERHEAD 48
-
-static size_t optimal_alloc_size(size_t size)
-{
- unsigned int count;
-
- size += ALLOCATOR_OVERHEAD;
-
- for (count = 1; size; size >>= 1, count++);
-
- return (1 << count) - ALLOCATOR_OVERHEAD;
-}
-
-/*! \brief add a new block to the pool.
- * We can only allocate from the topmost pool, so the
- * fields in *mgr reflect the size of that only.
- */
-static int add_string_pool(struct ast_string_field_mgr *mgr, struct ast_string_field_pool **pool_head,
- size_t size, const char *file, int lineno, const char *func)
-{
- struct ast_string_field_pool *pool;
- size_t alloc_size = optimal_alloc_size(sizeof(*pool) + size);
-
-#if defined(__AST_DEBUG_MALLOC)
- if (!(pool = __ast_calloc(1, alloc_size, file, lineno, func))) {
- return -1;
- }
-#else
- if (!(pool = ast_calloc(1, alloc_size))) {
- return -1;
- }
-#endif
-
- pool->prev = *pool_head;
- pool->size = alloc_size - sizeof(*pool);
- *pool_head = pool;
- mgr->last_alloc = NULL;
-
- return 0;
-}
-
-/*
- * This is an internal API, code should not use it directly.
- * It initializes all fields as empty, then uses 'size' for 3 functions:
- * size > 0 means initialize the pool list with a pool of given size.
- * This must be called right after allocating the object.
- * size = 0 means release all pools except the most recent one.
- * If the first pool was allocated via embedding in another
- * object, that pool will be preserved instead.
- * This is useful to e.g. reset an object to the initial value.
- * size < 0 means release all pools.
- * This must be done before destroying the object.
- */
-int __ast_string_field_init(struct ast_string_field_mgr *mgr, struct ast_string_field_pool **pool_head,
- int needed, const char *file, int lineno, const char *func)
-{
- const char **p = (const char **) pool_head + 1;
- struct ast_string_field_pool *cur = NULL;
- struct ast_string_field_pool *preserve = NULL;
-
- /* clear fields - this is always necessary */
- while ((struct ast_string_field_mgr *) p != mgr) {
- *p++ = __ast_string_field_empty;
- }
-
- mgr->last_alloc = NULL;
-#if defined(__AST_DEBUG_MALLOC)
- mgr->owner_file = file;
- mgr->owner_func = func;
- mgr->owner_line = lineno;
-#endif
- if (needed > 0) { /* allocate the initial pool */
- *pool_head = NULL;
- mgr->embedded_pool = NULL;
- return add_string_pool(mgr, pool_head, needed, file, lineno, func);
- }
-
- /* if there is an embedded pool, we can't actually release *all*
- * pools, we must keep the embedded one. if the caller is about
- * to free the structure that contains the stringfield manager
- * and embedded pool anyway, it will be freed as part of that
- * operation.
- */
- if ((needed < 0) && mgr->embedded_pool) {
- needed = 0;
- }
-
- if (needed < 0) { /* reset all pools */
- cur = *pool_head;
- } else if (mgr->embedded_pool) { /* preserve the embedded pool */
- preserve = mgr->embedded_pool;
- cur = *pool_head;
- } else { /* preserve the last pool */
- if (*pool_head == NULL) {
- ast_log(LOG_WARNING, "trying to reset empty pool\n");
- return -1;
- }
- preserve = *pool_head;
- cur = preserve->prev;
- }
-
- if (preserve) {
- preserve->prev = NULL;
- preserve->used = preserve->active = 0;
- }
-
- while (cur) {
- struct ast_string_field_pool *prev = cur->prev;
-
- if (cur != preserve) {
- ast_free(cur);
- }
- cur = prev;
- }
-
- *pool_head = preserve;
-
- return 0;
-}
-
-ast_string_field __ast_string_field_alloc_space(struct ast_string_field_mgr *mgr,
- struct ast_string_field_pool **pool_head, size_t needed)
-{
- char *result = NULL;
- size_t space = (*pool_head)->size - (*pool_head)->used;
- size_t to_alloc;
-
- /* Make room for ast_string_field_allocation and make it a multiple of that. */
- to_alloc = ast_make_room_for(needed, ast_string_field_allocation);
- ast_assert(to_alloc % ast_alignof(ast_string_field_allocation) == 0);
-
- if (__builtin_expect(to_alloc > space, 0)) {
- size_t new_size = (*pool_head)->size;
-
- while (new_size < to_alloc) {
- new_size *= 2;
- }
-
-#if defined(__AST_DEBUG_MALLOC)
- if (add_string_pool(mgr, pool_head, new_size, mgr->owner_file, mgr->owner_line, mgr->owner_func))
- return NULL;
-#else
- if (add_string_pool(mgr, pool_head, new_size, __FILE__, __LINE__, __FUNCTION__))
- return NULL;
-#endif
- }
-
- /* pool->base is always aligned (gcc aligned attribute). We ensure that
- * to_alloc is also a multiple of ast_alignof(ast_string_field_allocation)
- * causing result to always be aligned as well; which in turn fixes that
- * AST_STRING_FIELD_ALLOCATION(result) is aligned. */
- result = (*pool_head)->base + (*pool_head)->used;
- (*pool_head)->used += to_alloc;
- (*pool_head)->active += needed;
- result += ast_alignof(ast_string_field_allocation);
- AST_STRING_FIELD_ALLOCATION(result) = needed;
- mgr->last_alloc = result;
-
- return result;
-}
-
-int __ast_string_field_ptr_grow(struct ast_string_field_mgr *mgr,
- struct ast_string_field_pool **pool_head, size_t needed,
- const ast_string_field *ptr)
-{
- ssize_t grow = needed - AST_STRING_FIELD_ALLOCATION(*ptr);
- size_t space = (*pool_head)->size - (*pool_head)->used;
-
- if (*ptr != mgr->last_alloc) {
- return 1;
- }
-
- if (space < grow) {
- return 1;
- }
-
- (*pool_head)->used += grow;
- (*pool_head)->active += grow;
- AST_STRING_FIELD_ALLOCATION(*ptr) += grow;
-
- return 0;
-}
-
-void __ast_string_field_release_active(struct ast_string_field_pool *pool_head,
- const ast_string_field ptr)
-{
- struct ast_string_field_pool *pool, *prev;
-
- if (ptr == __ast_string_field_empty) {
- return;
- }
-
- for (pool = pool_head, prev = NULL; pool; prev = pool, pool = pool->prev) {
- if ((ptr >= pool->base) && (ptr <= (pool->base + pool->size))) {
- pool->active -= AST_STRING_FIELD_ALLOCATION(ptr);
- if (pool->active == 0) {
- if (prev) {
- prev->prev = pool->prev;
- ast_free(pool);
- } else {
- pool->used = 0;
- }
- }
- break;
- }
- }
-}
-
-void __ast_string_field_ptr_build_va(struct ast_string_field_mgr *mgr,
- struct ast_string_field_pool **pool_head,
- ast_string_field *ptr, const char *format, va_list ap)
-{
- size_t needed;
- size_t available;
- size_t space = (*pool_head)->size - (*pool_head)->used;
- int res;
- ssize_t grow;
- char *target;
- va_list ap2;
-
- /* if the field already has space allocated, try to reuse it;
- otherwise, try to use the empty space at the end of the current
- pool
- */
- if (*ptr != __ast_string_field_empty) {
- target = (char *) *ptr;
- available = AST_STRING_FIELD_ALLOCATION(*ptr);
- if (*ptr == mgr->last_alloc) {
- available += space;
- }
- } else {
- /* pool->used is always a multiple of ast_alignof(ast_string_field_allocation)
- * so we don't need to re-align anything here.
- */
- target = (*pool_head)->base + (*pool_head)->used + ast_alignof(ast_string_field_allocation);
- if (space > ast_alignof(ast_string_field_allocation)) {
- available = space - ast_alignof(ast_string_field_allocation);
- } else {
- available = 0;
- }
- }
-
- va_copy(ap2, ap);
- res = vsnprintf(target, available, format, ap2);
- va_end(ap2);
-
- if (res < 0) {
- /* Are we out of memory? */
- return;
- }
- if (res == 0) {
- __ast_string_field_release_active(*pool_head, *ptr);
- *ptr = __ast_string_field_empty;
- return;
- }
- needed = (size_t)res + 1; /* NUL byte */
-
- if (needed > available) {
- /* the allocation could not be satisfied using the field's current allocation
- (if it has one), or the space available in the pool (if it does not). allocate
- space for it, adding a new string pool if necessary.
- */
- if (!(target = (char *) __ast_string_field_alloc_space(mgr, pool_head, needed))) {
- return;
- }
- vsprintf(target, format, ap);
- va_end(ap); /* XXX va_end without va_start? */
- __ast_string_field_release_active(*pool_head, *ptr);
- *ptr = target;
- } else if (*ptr != target) {
- /* the allocation was satisfied using available space in the pool, but not
- using the space already allocated to the field
- */
- __ast_string_field_release_active(*pool_head, *ptr);
- mgr->last_alloc = *ptr = target;
- ast_assert(needed < (ast_string_field_allocation)-1);
- AST_STRING_FIELD_ALLOCATION(target) = (ast_string_field_allocation)needed;
- (*pool_head)->used += ast_make_room_for(needed, ast_string_field_allocation);
- (*pool_head)->active += needed;
- } else if ((grow = (needed - AST_STRING_FIELD_ALLOCATION(*ptr))) > 0) {
- /* the allocation was satisfied by using available space in the pool *and*
- the field was the last allocated field from the pool, so it grew
- */
- AST_STRING_FIELD_ALLOCATION(*ptr) += grow;
- (*pool_head)->used += ast_align_for(grow, ast_string_field_allocation);
- (*pool_head)->active += grow;
- }
-}
-
-void __ast_string_field_ptr_build(struct ast_string_field_mgr *mgr,
- struct ast_string_field_pool **pool_head,
- ast_string_field *ptr, const char *format, ...)
-{
- va_list ap;
-
- va_start(ap, format);
- __ast_string_field_ptr_build_va(mgr, pool_head, ptr, format, ap);
- va_end(ap);
-}
-
-void *__ast_calloc_with_stringfields(unsigned int num_structs, size_t struct_size, size_t field_mgr_offset,
- size_t field_mgr_pool_offset, size_t pool_size, const char *file,
- int lineno, const char *func)
-{
- struct ast_string_field_mgr *mgr;
- struct ast_string_field_pool *pool;
- struct ast_string_field_pool **pool_head;
- size_t pool_size_needed = sizeof(*pool) + pool_size;
- size_t size_to_alloc = optimal_alloc_size(struct_size + pool_size_needed);
- void *allocation;
- unsigned int x;
-
-#if defined(__AST_DEBUG_MALLOC)
- if (!(allocation = __ast_calloc(num_structs, size_to_alloc, file, lineno, func))) {
- return NULL;
- }
-#else
- if (!(allocation = ast_calloc(num_structs, size_to_alloc))) {
- return NULL;
- }
-#endif
-
- for (x = 0; x < num_structs; x++) {
- void *base = allocation + (size_to_alloc * x);
- const char **p;
-
- mgr = base + field_mgr_offset;
- pool_head = base + field_mgr_pool_offset;
- pool = base + struct_size;
-
- p = (const char **) pool_head + 1;
- while ((struct ast_string_field_mgr *) p != mgr) {
- *p++ = __ast_string_field_empty;
- }
-
- mgr->embedded_pool = pool;
- *pool_head = pool;
- pool->size = size_to_alloc - struct_size - sizeof(*pool);
-#if defined(__AST_DEBUG_MALLOC)
- mgr->owner_file = file;
- mgr->owner_func = func;
- mgr->owner_line = lineno;
-#endif
- }
-
- return allocation;
-}
-
-/* end of stringfields support */
-
AST_MUTEX_DEFINE_STATIC(fetchadd_m); /* used for all fetc&add ops */
int ast_atomic_fetchadd_int_slow(volatile int *p, int v)