[asterisk-commits] kpfleming: trunk r192362 - in /trunk: include/asterisk/ main/
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Tue May 5 09:17:21 CDT 2009
Author: kpfleming
Date: Tue May 5 09:17:18 2009
New Revision: 192362
URL: http://svn.asterisk.org/svn-view/asterisk?view=rev&rev=192362
Log:
Add a more efficient way of allocating structures that use stringfields
This commit adds an API call that can be used to allocate a structure along with this stringfield storage in a single allocation.
Modified:
trunk/include/asterisk/stringfields.h
trunk/main/utils.c
Modified: trunk/include/asterisk/stringfields.h
URL: http://svn.asterisk.org/svn-view/asterisk/trunk/include/asterisk/stringfields.h?view=diff&rev=192362&r1=192361&r2=192362
==============================================================================
--- trunk/include/asterisk/stringfields.h (original)
+++ trunk/include/asterisk/stringfields.h Tue May 5 09:17:18 2009
@@ -138,6 +138,7 @@
*/
struct ast_string_field_mgr {
ast_string_field last_alloc; /*!< the last field allocated */
+ struct ast_string_field_pool *embedded_pool; /*!< pointer to the embedded pool, if any */
#if defined(__AST_DEBUG_MALLOC)
const char *owner_file; /*!< filename of owner */
const char *owner_func; /*!< function name of owner */
@@ -252,6 +253,30 @@
*/
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);
+
+/*!
+ * \brief Allocate a structure with embedded stringfields in a single allocation
+ * \param n Number of structures to allocate (see ast_calloc)
+ * \param type The type of structure to allocate
+ * \param size The number of bytes of space (minimum) to allocate for stringfields to use
+ *
+ * This function will allocate memory for one or more structures that use stringfields, and
+ * also allocate space for the stringfields and initialize the stringfield management
+ * structure embedded in the outer structure.
+ *
+ * \since 1.6.3
+ */
+#define ast_calloc_with_stringfields(n, type, size) \
+ __ast_calloc_with_stringfields(n, sizeof(type), offsetof(type, __field_mgr), offsetof(type, __field_mgr_pool), \
+ size, __FILE__, __LINE__, __PRETTY_FUNCTION__)
+
+/*!
+ * \internal
+ * \brief internal version of ast_calloc_with_stringfields
+ */
+void * attribute_malloc __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);
/*!
\internal
Modified: trunk/main/utils.c
URL: http://svn.asterisk.org/svn-view/asterisk/trunk/main/utils.c?view=diff&rev=192362&r1=192361&r2=192362
==============================================================================
--- trunk/main/utils.c (original)
+++ trunk/main/utils.c Tue May 5 09:17:18 2009
@@ -1530,6 +1530,8 @@
* 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.
@@ -1559,6 +1561,9 @@
if (needed < 0) { /* reset all pools */
/* nothing to do */
+ } 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");
@@ -1736,6 +1741,50 @@
va_end(ap1);
va_end(ap2);
}
+
+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);
+ }
+
+ return allocation;
+}
+
/* end of stringfields support */
AST_MUTEX_DEFINE_STATIC(fetchadd_m); /* used for all fetc&add ops */
More information about the asterisk-commits
mailing list