[asterisk-commits] russell: branch russell/debug_threads r77823 - in /team/russell/debug_threads...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Jul 31 10:18:06 CDT 2007


Author: russell
Date: Tue Jul 31 10:18:05 2007
New Revision: 77823

URL: http://svn.digium.com/view/asterisk?view=rev&rev=77823
Log:
pull in thread storage from trunk

Added:
    team/russell/debug_threads/include/asterisk/threadstorage.h   (with props)
Modified:
    team/russell/debug_threads/utils.c

Added: team/russell/debug_threads/include/asterisk/threadstorage.h
URL: http://svn.digium.com/view/asterisk/team/russell/debug_threads/include/asterisk/threadstorage.h?view=auto&rev=77823
==============================================================================
--- team/russell/debug_threads/include/asterisk/threadstorage.h (added)
+++ team/russell/debug_threads/include/asterisk/threadstorage.h Tue Jul 31 10:18:05 2007
@@ -1,0 +1,208 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2006, Digium, Inc.
+ *
+ * Russell Bryant <russell at digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*!
+ * \file threadstorage.h
+ * \author Russell Bryant <russell at digium.com>
+ * \brief Definitions to aid in the use of thread local storage
+ *
+ * \arg \ref AstThreadStorage
+ */
+
+/*!
+ * \page AstThreadStorage The Asterisk Thread Storage API
+ *
+ *
+ * The POSIX threads (pthreads) API provides the ability to define thread
+ * specific data.  The functions and structures defined here are intended
+ * to centralize the code that is commonly used when using thread local
+ * storage.
+ *
+ * The motivation for using this code in Asterisk is for situations where
+ * storing data on a thread-specific basis can provide some amount of
+ * performance benefit.  For example, there are some call types in Asterisk
+ * where ast_frame structures must be allocated very rapidly (easily 50, 100,
+ * 200 times a second).  Instead of doing the equivalent of that many calls
+ * to malloc() and free() per second, thread local storage is used to keep a
+ * list of unused frame structures so that they can be continuously reused.
+ *
+ * - \ref threadstorage.h
+ */
+
+#ifndef ASTERISK_THREADSTORAGE_H
+#define ASTERISK_THREADSTORAGE_H
+
+#include <pthread.h>
+
+#include "asterisk/utils.h"
+#include "asterisk/inline_api.h"
+
+/*!
+ * \brief data for a thread locally stored variable
+ */
+struct ast_threadstorage {
+	pthread_once_t once;	/*!< Ensure that the key is only initialized by one thread */
+	pthread_key_t key;	/*!< The key used to retrieve this thread's data */
+	void (*key_init)(void);	/*!< The function that initializes the key */
+	int (*custom_init)(void *); /*!< Custom initialization function specific to the object */
+};
+
+#if defined(DEBUG_THREADLOCALS)
+void __ast_threadstorage_object_add(void *key, size_t len, const char *file, const char *function, unsigned int line);
+void __ast_threadstorage_object_remove(void *key);
+void __ast_threadstorage_object_replace(void *key_old, void *key_new, size_t len);
+#endif /* defined(DEBUG_THREADLOCALS) */
+
+/*!
+ * \brief Define a thread storage variable
+ *
+ * \arg name The name of the thread storage object
+ *
+ * This macro would be used to declare an instance of thread storage in a file.
+ *
+ * Example usage:
+ * \code
+ * AST_THREADSTORAGE(my_buf);
+ * \endcode
+ */
+#define AST_THREADSTORAGE(name) \
+	AST_THREADSTORAGE_CUSTOM(name, NULL, ast_free) 
+
+/*!
+ * \brief Define a thread storage variable, with custom initialization and cleanup
+ *
+ * \arg name The name of the thread storage object
+ * \arg init This is a custom function that will be called after each thread specific
+ *           object is allocated, with the allocated block of memory passed
+ *           as the argument.
+ * \arg cleanup This is a custom function that will be called instead of ast_free
+ *              when the thread goes away.  Note that if this is used, it *MUST*
+ *              call free on the allocated memory.
+ *
+ * Example usage:
+ * \code
+ * AST_THREADSTORAGE_CUSTOM(my_buf, my_init, my_cleanup);
+ * \endcode
+ */
+#if !defined(DEBUG_THREADLOCALS)
+#define AST_THREADSTORAGE_CUSTOM(name, c_init, c_cleanup)	\
+static void __init_##name(void);				\
+static struct ast_threadstorage name = {			\
+	.once = PTHREAD_ONCE_INIT,				\
+	.key_init = __init_##name,				\
+	.custom_init = c_init,					\
+};								\
+static void __init_##name(void)					\
+{								\
+	pthread_key_create(&(name).key, c_cleanup);		\
+}
+#else /* defined(DEBUG_THREADLOCALS) */
+#define AST_THREADSTORAGE_CUSTOM(name, c_init, c_cleanup)	\
+static void __init_##name(void);				\
+static struct ast_threadstorage name = {			\
+	.once = PTHREAD_ONCE_INIT,				\
+	.key_init = __init_##name,				\
+	.custom_init = c_init,					\
+};								\
+static void __cleanup_##name(void *data)			\
+{								\
+	__ast_threadstorage_object_remove(data);		\
+	c_cleanup(data);					\
+}								\
+static void __init_##name(void)					\
+{								\
+	pthread_key_create(&(name).key, __cleanup_##name);	\
+}
+#endif /* defined(DEBUG_THREADLOCALS) */
+
+/*!
+ * \brief Retrieve thread storage
+ *
+ * \arg ts This is a pointer to the thread storage structure declared by using
+ *      the AST_THREADSTORAGE macro.  If declared with 
+ *      AST_THREADSTORAGE(my_buf, my_buf_init), then this argument would be 
+ *      (&my_buf).
+ * \arg init_size This is the amount of space to be allocated the first time
+ *      this thread requests its data. Thus, this should be the size that the
+ *      code accessing this thread storage is assuming the size to be.
+ *
+ * \return This function will return the thread local storage associated with
+ *         the thread storage management variable passed as the first argument.
+ *         The result will be NULL in the case of a memory allocation error.
+ *
+ * Example usage:
+ * \code
+ * AST_THREADSTORAGE(my_buf, my_buf_init);
+ * #define MY_BUF_SIZE   128
+ * ...
+ * void my_func(const char *fmt, ...)
+ * {
+ *      void *buf;
+ *
+ *      if (!(buf = ast_threadstorage_get(&my_buf, MY_BUF_SIZE)))
+ *           return;
+ *      ...
+ * }
+ * \endcode
+ */
+#if !defined(DEBUG_THREADLOCALS)
+AST_INLINE_API(
+void *ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size),
+{
+	void *buf;
+
+	pthread_once(&ts->once, ts->key_init);
+	if (!(buf = pthread_getspecific(ts->key))) {
+		if (!(buf = calloc(1, init_size)))
+			return NULL;
+		if (ts->custom_init && ts->custom_init(buf)) {
+			free(buf);
+			return NULL;
+		}
+		pthread_setspecific(ts->key, buf);
+	}
+
+	return buf;
+}
+)
+#else /* defined(DEBUG_THREADLOCALS) */
+AST_INLINE_API(
+void *__ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size, const char *file, const char *function, unsigned int line),
+{
+	void *buf;
+
+	pthread_once(&ts->once, ts->key_init);
+	if (!(buf = pthread_getspecific(ts->key))) {
+		if (!(buf = ast_calloc(1, init_size)))
+			return NULL;
+		if (ts->custom_init && ts->custom_init(buf)) {
+			free(buf);
+			return NULL;
+		}
+		pthread_setspecific(ts->key, buf);
+		__ast_threadstorage_object_add(buf, init_size, file, function, line);
+	}
+
+	return buf;
+}
+)
+
+#define ast_threadstorage_get(ts, init_size) __ast_threadstorage_get(ts, init_size, __FILE__, __PRETTY_FUNCTION__, __LINE__)
+#endif /* defined(DEBUG_THREADLOCALS) */
+
+#endif /* ASTERISK_THREADSTORAGE_H */

Propchange: team/russell/debug_threads/include/asterisk/threadstorage.h
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: team/russell/debug_threads/include/asterisk/threadstorage.h
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: team/russell/debug_threads/include/asterisk/threadstorage.h
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: team/russell/debug_threads/utils.c
URL: http://svn.digium.com/view/asterisk/team/russell/debug_threads/utils.c?view=diff&rev=77823&r1=77822&r2=77823
==============================================================================
--- team/russell/debug_threads/utils.c (original)
+++ team/russell/debug_threads/utils.c Tue Jul 31 10:18:05 2007
@@ -56,6 +56,9 @@
 
 #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
+#include "asterisk/threadstorage.h"
 
 static char base64[64];
 static char b2a[256];




More information about the asterisk-commits mailing list