Changeset 4154


Ignore:
Timestamp:
Jun 5, 2012 10:41:17 AM (7 years ago)
Author:
bennylp
Message:

Re #1527: added debugging facility to the timer heap. By enabling PJ_TIMER_DEBUG, application can use pj_timer_heap_dump() or pjsip_endpt_dump() to dump the timer entries along with the source location where it is scheduled from. The macro will also enable dumping the timer heap entries when the SIP endpoint is being destroyed

Location:
pjproject/trunk
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjlib/include/pj/config.h

    r4141 r4154  
    472472#ifndef PJ_POOL_DEBUG 
    473473#  define PJ_POOL_DEBUG             0 
     474#endif 
     475 
     476 
     477/** 
     478 * Enable timer heap debugging facility. When this is enabled, application 
     479 * can call pj_timer_heap_dump() to show the contents of the timer heap 
     480 * along with the source location where the timer entries were scheduled. 
     481 * See https://trac.pjsip.org/repos/ticket/1527 for more info. 
     482 * 
     483 * Default: 0 
     484 */ 
     485#ifndef PJ_TIMER_DEBUG 
     486#  define PJ_TIMER_DEBUG            0 
    474487#endif 
    475488 
  • pjproject/trunk/pjlib/include/pj/timer.h

    r3034 r4154  
    8686 * This structure represents an entry to the timer. 
    8787 */ 
    88 struct pj_timer_entry 
     88typedef struct pj_timer_entry 
    8989{ 
    9090    /**  
     
    118118     */ 
    119119    pj_time_val _timer_value; 
    120 }; 
     120 
     121#if PJ_TIMER_DEBUG 
     122    const char  *src_file; 
     123    int          src_line; 
     124#endif 
     125} pj_timer_entry; 
    121126 
    122127 
     
    209214 * @return          PJ_SUCCESS, or the appropriate error code. 
    210215 */ 
     216#if PJ_TIMER_DEBUG 
     217#  define pj_timer_heap_schedule(ht,e,d) \ 
     218                        pj_timer_heap_schedule_dbg(ht,e,d,__FILE__,__LINE__) 
     219 
     220  PJ_DECL(pj_status_t) pj_timer_heap_schedule_dbg( pj_timer_heap_t *ht, 
     221                                                   pj_timer_entry *entry, 
     222                                                   const pj_time_val *delay, 
     223                                                   const char *src_file, 
     224                                                   int src_line); 
     225#else 
    211226PJ_DECL(pj_status_t) pj_timer_heap_schedule( pj_timer_heap_t *ht, 
    212227                                             pj_timer_entry *entry,  
    213228                                             const pj_time_val *delay); 
     229#endif  /* PJ_TIMER_DEBUG */ 
    214230 
    215231/** 
     
    263279                                      pj_time_val *next_delay); 
    264280 
     281#if PJ_TIMER_DEBUG 
     282/** 
     283 * Dump timer heap entries. 
     284 * 
     285 * @param ht        The timer heap. 
     286 */ 
     287PJ_DECL(void) pj_timer_heap_dump(pj_timer_heap_t *ht); 
     288#endif 
     289 
    265290/** 
    266291 * @} 
  • pjproject/trunk/pjlib/include/pj/types.h

    r3999 r4154  
    214214typedef struct pj_timer_heap_t pj_timer_heap_t; 
    215215 
    216 /** 
    217  * Forward declaration for timer entry. 
    218  */ 
    219 typedef struct pj_timer_entry pj_timer_entry; 
    220  
    221216/**  
    222217 * Opaque data type for atomic operations. 
  • pjproject/trunk/pjlib/src/pj/timer.c

    r3456 r4154  
    3535#include <pj/errno.h> 
    3636#include <pj/lock.h> 
     37#include <pj/log.h> 
     38 
     39#define THIS_FILE       "timer.c" 
    3740 
    3841#define HEAP_PARENT(X)  (X == 0 ? 0 : (((X) - 1) / 2)) 
     
    453456} 
    454457 
     458#if PJ_TIMER_DEBUG 
     459PJ_DEF(pj_status_t) pj_timer_heap_schedule_dbg( pj_timer_heap_t *ht, 
     460                                                pj_timer_entry *entry, 
     461                                                const pj_time_val *delay, 
     462                                                const char *src_file, 
     463                                                int src_line) 
     464#else 
    455465PJ_DEF(pj_status_t) pj_timer_heap_schedule( pj_timer_heap_t *ht, 
    456466                                            pj_timer_entry *entry,  
    457467                                            const pj_time_val *delay) 
     468#endif 
    458469{ 
    459470    pj_status_t status; 
     
    466477    PJ_ASSERT_RETURN(entry->_timer_id < 1, PJ_EINVALIDOP); 
    467478 
     479#if PJ_TIMER_DEBUG 
     480    entry->src_file = src_file; 
     481    entry->src_line = src_line; 
     482#endif 
    468483    pj_gettickcount(&expires); 
    469484    PJ_TIME_VAL_ADD(expires, *delay); 
     
    553568} 
    554569 
     570#if PJ_TIMER_DEBUG 
     571PJ_DEF(void) pj_timer_heap_dump(pj_timer_heap_t *ht) 
     572{ 
     573    lock_timer_heap(ht); 
     574 
     575    PJ_LOG(3,(THIS_FILE, "Dumping timer heap:")); 
     576    PJ_LOG(3,(THIS_FILE, "  Cur size: %d entries, max: %d", 
     577                         (int)ht->cur_size, (int)ht->max_size)); 
     578 
     579    if (ht->cur_size) { 
     580        unsigned i; 
     581        pj_time_val now; 
     582 
     583        PJ_LOG(3,(THIS_FILE, "  Entries: ")); 
     584        PJ_LOG(3,(THIS_FILE, "    _id\tId\tElapsed\tSource")); 
     585        PJ_LOG(3,(THIS_FILE, "    ----------------------------------")); 
     586 
     587        pj_gettickcount(&now); 
     588 
     589        for (i=0; i<(unsigned)ht->cur_size; ++i) { 
     590            pj_timer_entry *e = ht->heap[i]; 
     591            pj_time_val delta; 
     592 
     593            if (PJ_TIME_VAL_LTE(e->_timer_value, now)) 
     594                delta.sec = delta.msec = 0; 
     595            else { 
     596                delta = e->_timer_value; 
     597                PJ_TIME_VAL_SUB(delta, now); 
     598            } 
     599 
     600            PJ_LOG(3,(THIS_FILE, "    %d\t%d\t%d.%03d\t%s:%d", 
     601                      e->_timer_id, e->id, 
     602                      (int)delta.sec, (int)delta.msec, 
     603                      e->src_file, e->src_line)); 
     604        } 
     605    } 
     606 
     607    unlock_timer_heap(ht); 
     608} 
     609#endif 
     610 
  • pjproject/trunk/pjsip/include/pjsip/sip_endpoint.h

    r3999 r4154  
    151151 * @return          PJ_OK (zero) if successfull. 
    152152 */ 
     153#if PJ_TIMER_DEBUG 
     154#define pjsip_endpt_schedule_timer(ept,ent,d) \ 
     155                        pjsip_endpt_schedule_timer_dbg(ept, ent, d, \ 
     156                                                       __FILE__, __LINE__) 
     157 
     158PJ_DECL(pj_status_t) pjsip_endpt_schedule_timer_dbg(pjsip_endpoint *endpt, 
     159                                                    pj_timer_entry *entry, 
     160                                                    const pj_time_val *delay, 
     161                                                    const char *src_file, 
     162                                                    int src_line); 
     163#else 
    153164PJ_DECL(pj_status_t) pjsip_endpt_schedule_timer( pjsip_endpoint *endpt, 
    154165                                                 pj_timer_entry *entry, 
    155166                                                 const pj_time_val *delay ); 
     167#endif 
    156168 
    157169/** 
  • pjproject/trunk/pjsip/include/pjsip/sip_event.h

    r3553 r4154  
    3535 */ 
    3636#include <pj/types.h> 
     37#include <pj/timer.h> 
    3738 
    3839 
  • pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h

    r4138 r4154  
    20202020 * @see pjsip_endpt_schedule_timer() 
    20212021 */ 
     2022#if PJ_TIMER_DEBUG 
     2023#define pjsua_schedule_timer(e,d) pjsua_schedule_timer_dbg(e,d,\ 
     2024                                                           __FILE__,__LINE__) 
     2025 
     2026PJ_DECL(pj_status_t) pjsua_schedule_timer_dbg(pj_timer_entry *entry, 
     2027                                              const pj_time_val *delay, 
     2028                                              const char *src_file, 
     2029                                              int src_line); 
     2030#else 
    20222031PJ_DECL(pj_status_t) pjsua_schedule_timer(pj_timer_entry *entry, 
    20232032                                          const pj_time_val *delay); 
     2033#endif 
    20242034 
    20252035/** 
     
    20342044 * @return              PJ_SUCCESS on success, or the appropriate error code. 
    20352045 */ 
     2046#if PJ_TIMER_DEBUG 
     2047#define pjsua_schedule_timer2(cb,u,d) \ 
     2048                        pjsua_schedule_timer2_dbg(cb,u,d,__FILE__,__LINE__) 
     2049 
     2050PJ_DECL(pj_status_t) pjsua_schedule_timer2_dbg(void (*cb)(void *user_data), 
     2051                                               void *user_data, 
     2052                                               unsigned msec_delay, 
     2053                                               const char *src_file, 
     2054                                               int src_line); 
     2055#else 
    20362056PJ_DECL(pj_status_t) pjsua_schedule_timer2(void (*cb)(void *user_data), 
    20372057                                           void *user_data, 
    20382058                                           unsigned msec_delay); 
     2059#endif 
    20392060 
    20402061/** 
  • pjproject/trunk/pjsip/src/pjsip/sip_endpoint.c

    r3999 r4154  
    607607 
    608608    /* Destroy timer heap */ 
     609#if PJ_TIMER_DEBUG 
     610    pj_timer_heap_dump(endpt->timer_heap); 
     611#endif 
    609612    pj_timer_heap_destroy(endpt->timer_heap); 
    610613 
     
    769772 * Schedule timer. 
    770773 */ 
     774#if PJ_TIMER_DEBUG 
     775PJ_DEF(pj_status_t) pjsip_endpt_schedule_timer_dbg(pjsip_endpoint *endpt, 
     776                                                    pj_timer_entry *entry, 
     777                                                    const pj_time_val *delay, 
     778                                                    const char *src_file, 
     779                                                    int src_line) 
     780{ 
     781    PJ_LOG(6, (THIS_FILE, "pjsip_endpt_schedule_timer(entry=%p, delay=%u.%u)", 
     782                         entry, delay->sec, delay->msec)); 
     783    return pj_timer_heap_schedule_dbg(endpt->timer_heap, entry, delay, 
     784                                      src_file, src_line); 
     785} 
     786#else 
    771787PJ_DEF(pj_status_t) pjsip_endpt_schedule_timer( pjsip_endpoint *endpt, 
    772788                                                pj_timer_entry *entry, 
     
    777793    return pj_timer_heap_schedule( endpt->timer_heap, entry, delay ); 
    778794} 
     795#endif 
    779796 
    780797/* 
     
    11941211 
    11951212    /* Timer. */ 
     1213#if PJ_TIMER_DEBUG 
     1214    pj_timer_heap_dump(endpt->timer_heap); 
     1215#else 
    11961216    PJ_LOG(3,(THIS_FILE, " Timer heap has %u entries",  
    11971217                        pj_timer_heap_count(endpt->timer_heap))); 
     1218#endif 
    11981219 
    11991220    /* Unlock mutex. */ 
  • pjproject/trunk/pjsip/src/pjsua-lib/pjsua_core.c

    r4122 r4154  
    26242624 * Schedule a timer entry.  
    26252625 */ 
     2626#if PJ_TIMER_DEBUG 
     2627PJ_DEF(pj_status_t) pjsua_schedule_timer_dbg( pj_timer_entry *entry, 
     2628                                              const pj_time_val *delay, 
     2629                                              const char *src_file, 
     2630                                              int src_line) 
     2631{ 
     2632    return pjsip_endpt_schedule_timer_dbg(pjsua_var.endpt, entry, delay, 
     2633                                          src_file, src_line); 
     2634} 
     2635#else 
    26262636PJ_DEF(pj_status_t) pjsua_schedule_timer( pj_timer_entry *entry, 
    26272637                                          const pj_time_val *delay) 
     
    26292639    return pjsip_endpt_schedule_timer(pjsua_var.endpt, entry, delay); 
    26302640} 
     2641#endif 
    26312642 
    26322643/* Timer callback */ 
     
    26512662 * Schedule a timer callback.  
    26522663 */ 
     2664#if PJ_TIMER_DEBUG 
     2665PJ_DEF(pj_status_t) pjsua_schedule_timer2_dbg( void (*cb)(void *user_data), 
     2666                                               void *user_data, 
     2667                                               unsigned msec_delay, 
     2668                                               const char *src_file, 
     2669                                               int src_line) 
     2670#else 
    26532671PJ_DEF(pj_status_t) pjsua_schedule_timer2( void (*cb)(void *user_data), 
    26542672                                           void *user_data, 
    26552673                                           unsigned msec_delay) 
     2674#endif 
    26562675{ 
    26572676    pjsua_timer_list *tmr = NULL; 
     
    26732692    delay.msec = msec_delay; 
    26742693 
     2694#if PJ_TIMER_DEBUG 
     2695    status = pjsip_endpt_schedule_timer_dbg(pjsua_var.endpt, &tmr->entry, 
     2696                                            &delay, src_file, src_line); 
     2697#else 
    26752698    status = pjsip_endpt_schedule_timer(pjsua_var.endpt, &tmr->entry, &delay); 
     2699#endif 
    26762700    if (status != PJ_SUCCESS) { 
    26772701        pj_list_push_back(&pjsua_var.timer_list, tmr); 
Note: See TracChangeset for help on using the changeset viewer.