aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorrizzo <rizzo@f38db490-d61c-443f-a65b-d21fe96a405b>2006-04-12 20:40:46 +0000
committerrizzo <rizzo@f38db490-d61c-443f-a65b-d21fe96a405b>2006-04-12 20:40:46 +0000
commit08c77ea86d932596542a63a1a67cb3e6a1229135 (patch)
tree0b296463204ccd97d57e585d6659dd75d15280fc /include
parentdb922028c05355324c33e3a08ce427ed0a16b45f (diff)
add 'show threads' and 'show profile' commands.
These are momstly debugging tools for developers, a bit documented in the header files (utils.h), although more documentation is definitely necessary. The performance impact is close to zero(*) so there is no need to compile it conditionally. (*) not completely true - thread destruction still needs to search a list _but_ this can be easily optimized if we end up with hundreds of active threads (in which case, though, the problem is clearly elsewhere). git-svn-id: http://svn.digium.com/svn/asterisk/trunk@19544 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'include')
-rw-r--r--include/asterisk.h35
-rw-r--r--include/asterisk/compat.h1
-rw-r--r--include/asterisk/lock.h35
-rw-r--r--include/asterisk/utils.h10
4 files changed, 78 insertions, 3 deletions
diff --git a/include/asterisk.h b/include/asterisk.h
index 38b0f67ab..7e63f608c 100644
--- a/include/asterisk.h
+++ b/include/asterisk.h
@@ -15,6 +15,8 @@
* \brief Asterisk main include file. File version handling, generic pbx functions.
*/
+#include "asterisk/compat.h"
+
#ifndef _ASTERISK_H
#define _ASTERISK_H
@@ -108,6 +110,24 @@ void ast_register_file_version(const char *file, const char *version);
void ast_unregister_file_version(const char *file);
/*!
+ * \brief support for event profiling
+ * (note, this must be documented a lot more)
+ * ast_add_profile allocates a generic 'counter' with a given name,
+ * which can be shown with the command 'show profile <name>'
+ *
+ * The counter accumulates positive or negative values supplied by
+ * ast_add_profile(), dividing them by the 'scale' value passed in the
+ * create call, and also counts the number of 'events'.
+ * Values can also be taked by the TSC counter on ia32 architectures,
+ * in which case you can mark the start of an event calling ast_mark(id, 1)
+ * and then the end of the event with ast_mark(id, 0).
+ * For non-i386 architectures, these two calls return 0.
+ */
+int ast_add_profile(const char *, uint64_t scale);
+int64_t ast_profile(int, int64_t);
+int64_t ast_mark(int, int start1_stop0);
+
+/*!
* \brief Register/unregister a source code file with the core.
* \param file the source file name
* \param version the version string (typically a CVS revision keyword string)
@@ -129,6 +149,20 @@ void ast_unregister_file_version(const char *file);
* revision number.
*/
#if defined(__GNUC__) && !defined(LOW_MEMORY)
+#ifdef MTX_PROFILE
+#define HAVE_MTX_PROFILE /* used in lock.h */
+#define ASTERISK_FILE_VERSION(file, version) \
+ static int mtx_prof = -1; /* profile mutex */ \
+ static void __attribute__((constructor)) __register_file_version(void) \
+ { \
+ mtx_prof = ast_add_profile("mtx_lock_" file, 0); \
+ ast_register_file_version(file, version); \
+ } \
+ static void __attribute__((destructor)) __unregister_file_version(void) \
+ { \
+ ast_unregister_file_version(file); \
+ }
+#else
#define ASTERISK_FILE_VERSION(file, version) \
static void __attribute__((constructor)) __register_file_version(void) \
{ \
@@ -138,6 +172,7 @@ void ast_unregister_file_version(const char *file);
{ \
ast_unregister_file_version(file); \
}
+#endif
#elif !defined(LOW_MEMORY) /* ! __GNUC__ && ! LOW_MEMORY*/
#define ASTERISK_FILE_VERSION(file, x) static const char __file_version[] = x;
#else /* LOW_MEMORY */
diff --git a/include/asterisk/compat.h b/include/asterisk/compat.h
index 4ed0b7a5d..79d23e7e7 100644
--- a/include/asterisk/compat.h
+++ b/include/asterisk/compat.h
@@ -80,6 +80,7 @@ int unsetenv(const char *name);
#endif
#ifdef __linux__
+#include <inttypes.h>
#define HAVE_STRCASESTR
#define HAVE_STRNDUP
#define HAVE_STRNLEN
diff --git a/include/asterisk/lock.h b/include/asterisk/lock.h
index f0192e7ba..e86462306 100644
--- a/include/asterisk/lock.h
+++ b/include/asterisk/lock.h
@@ -56,6 +56,23 @@
#ifndef _ASTERISK_LOCK_H
#define _ASTERISK_LOCK_H
+/* internal macro to profile mutexes. Only computes the delay on
+ * non-blocking calls.
+ */
+#ifndef HAVE_MTX_PROFILE
+#define __MTX_PROF /* nothing */
+#else
+#define __MTX_PROF { \
+ int i; \
+ /* profile only non-blocking events */ \
+ ast_mark(mtx_prof, 1); \
+ i = pthread_mutex_trylock(pmutex); \
+ ast_mark(mtx_prof, 0); \
+ if (!i) \
+ return i; \
+ }
+#endif /* HAVE_MTX_PROFILE */
+
#include <pthread.h>
#include <netdb.h>
#include <time.h>
@@ -75,7 +92,7 @@
#endif
#ifdef BSD
-#ifdef __GNUC__
+#if 0 && defined( __GNUC__)
#define AST_MUTEX_INIT_W_CONSTRUCTORS
#else
#define AST_MUTEX_INIT_ON_FIRST_USE
@@ -264,7 +281,13 @@ static inline int __ast_pthread_mutex_lock(const char *filename, int lineno, con
time_t seconds = time(NULL);
time_t current;
do {
+#ifdef HAVE_MTX_PROFILE
+ ast_mark(mtx_prof, 1);
+#endif
res = pthread_mutex_trylock(&t->mutex);
+#ifdef HAVE_MTX_PROFILE
+ ast_mark(mtx_prof, 0);
+#endif
if (res == EBUSY) {
current = time(NULL);
if ((current - seconds) && (!((current - seconds) % 5))) {
@@ -279,6 +302,12 @@ static inline int __ast_pthread_mutex_lock(const char *filename, int lineno, con
} while (res == EBUSY);
}
#else
+#ifdef HAVE_MTX_PROFILE
+ ast_mark(mtx_prof, 1);
+ res = pthread_mutex_trylock(&t->mutex);
+ ast_mark(mtx_prof, 0);
+ if (res)
+#endif
res = pthread_mutex_lock(&t->mutex);
#endif /* DETECT_DEADLOCKS */
@@ -581,6 +610,7 @@ static void __attribute__ ((destructor)) fini_##mutex(void) \
static inline int ast_mutex_lock(ast_mutex_t *pmutex)
{
+ __MTX_PROF
return pthread_mutex_lock(pmutex);
}
@@ -601,8 +631,10 @@ static inline int ast_mutex_lock(ast_mutex_t *pmutex)
{
if (*pmutex == (ast_mutex_t)AST_MUTEX_KIND)
ast_mutex_init(pmutex);
+ __MTX_PROF
return pthread_mutex_lock(pmutex);
}
+
static inline int ast_mutex_trylock(ast_mutex_t *pmutex)
{
if (*pmutex == (ast_mutex_t)AST_MUTEX_KIND)
@@ -616,6 +648,7 @@ static inline int ast_mutex_trylock(ast_mutex_t *pmutex)
static inline int ast_mutex_lock(ast_mutex_t *pmutex)
{
+ __MTX_PROF
return pthread_mutex_lock(pmutex);
}
diff --git a/include/asterisk/utils.h b/include/asterisk/utils.h
index c702fa6fb..35f2539ef 100644
--- a/include/asterisk/utils.h
+++ b/include/asterisk/utils.h
@@ -225,8 +225,14 @@ static force_inline int inaddrcmp(const struct sockaddr_in *sin1, const struct s
}
#define AST_STACKSIZE 256 * 1024
-#define ast_pthread_create(a,b,c,d) ast_pthread_create_stack(a,b,c,d,0)
-int ast_pthread_create_stack(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *), void *data, size_t stacksize);
+
+void ast_register_thread(char *name);
+void ast_unregister_thread(void *id);
+
+#define ast_pthread_create(a,b,c,d) ast_pthread_create_stack(a,b,c,d,0, \
+ __FILE__, __FUNCTION__, __LINE__, #c)
+int ast_pthread_create_stack(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *), void *data, size_t stacksize,
+ const char *file, const char *caller, int line, const char *start_fn);
/*!
\brief Process a string to find and replace characters