diff options
author | rizzo <rizzo@f38db490-d61c-443f-a65b-d21fe96a405b> | 2006-04-12 20:40:46 +0000 |
---|---|---|
committer | rizzo <rizzo@f38db490-d61c-443f-a65b-d21fe96a405b> | 2006-04-12 20:40:46 +0000 |
commit | 08c77ea86d932596542a63a1a67cb3e6a1229135 (patch) | |
tree | 0b296463204ccd97d57e585d6659dd75d15280fc /include | |
parent | db922028c05355324c33e3a08ce427ed0a16b45f (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.h | 35 | ||||
-rw-r--r-- | include/asterisk/compat.h | 1 | ||||
-rw-r--r-- | include/asterisk/lock.h | 35 | ||||
-rw-r--r-- | include/asterisk/utils.h | 10 |
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 |