From 623fdccd9c92fc2a00516e5cd6ed2d5edc2272a1 Mon Sep 17 00:00:00 2001 From: Liong Sauw Ming Date: Wed, 16 Mar 2011 09:22:24 +0000 Subject: Fixed #1211: Add pjlib API pj_gettickcount() that returns a monotonically increasing timestamp * Changed the timer_heap to use pj_gettickcount(). * Changed ioqueue to use pj_gettickcount(). git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@3456 74dad513-b988-da41-8d7b-12977e46ad98 --- pjlib/include/pj/os.h | 9 +++++ pjlib/src/pj/ioqueue_epoll.c | 4 +- pjlib/src/pj/ioqueue_select.c | 4 +- pjlib/src/pj/ioqueue_winnt.c | 4 +- pjlib/src/pj/os_timestamp_common.c | 14 +++++++ pjlib/src/pj/os_timestamp_posix.c | 78 +++++++++++++++++++++++++++++++++++++- pjlib/src/pj/symbols.c | 1 + pjlib/src/pj/timer.c | 4 +- 8 files changed, 109 insertions(+), 9 deletions(-) (limited to 'pjlib') diff --git a/pjlib/include/pj/os.h b/pjlib/include/pj/os.h index 8d50476a..1cdbc476 100644 --- a/pjlib/include/pj/os.h +++ b/pjlib/include/pj/os.h @@ -1168,6 +1168,15 @@ PJ_DECL(pj_color_t) pj_term_get_color(void); */ #if defined(PJ_HAS_HIGH_RES_TIMER) && PJ_HAS_HIGH_RES_TIMER != 0 +/** + * Get monotonic time since some unspecified starting point. + * + * @param tv Variable to store the result. + * + * @return PJ_SUCCESS if successful. + */ +PJ_DECL(pj_status_t) pj_gettickcount(pj_time_val *tv); + /** * Acquire high resolution timer value. The time value are stored * in cycles. diff --git a/pjlib/src/pj/ioqueue_epoll.c b/pjlib/src/pj/ioqueue_epoll.c index ee9c5dd0..8d6e36f5 100644 --- a/pjlib/src/pj/ioqueue_epoll.c +++ b/pjlib/src/pj/ioqueue_epoll.c @@ -465,7 +465,7 @@ static void decrement_counter(pj_ioqueue_key_t *key) if (key->ref_count == 0) { pj_assert(key->closing == 1); - pj_gettimeofday(&key->free_time); + pj_gettickcount(&key->free_time); key->free_time.msec += PJ_IOQUEUE_KEY_FREE_DELAY; pj_time_val_normalize(&key->free_time); @@ -583,7 +583,7 @@ static void scan_closing_keys(pj_ioqueue_t *ioqueue) pj_time_val now; pj_ioqueue_key_t *h; - pj_gettimeofday(&now); + pj_gettickcount(&now); h = ioqueue->closing_list.next; while (h != &ioqueue->closing_list) { pj_ioqueue_key_t *next = h->next; diff --git a/pjlib/src/pj/ioqueue_select.c b/pjlib/src/pj/ioqueue_select.c index 3a7c14e3..3125bae7 100644 --- a/pjlib/src/pj/ioqueue_select.c +++ b/pjlib/src/pj/ioqueue_select.c @@ -411,7 +411,7 @@ static void decrement_counter(pj_ioqueue_key_t *key) if (key->ref_count == 0) { pj_assert(key->closing == 1); - pj_gettimeofday(&key->free_time); + pj_gettickcount(&key->free_time); key->free_time.msec += PJ_IOQUEUE_KEY_FREE_DELAY; pj_time_val_normalize(&key->free_time); @@ -608,7 +608,7 @@ static void scan_closing_keys(pj_ioqueue_t *ioqueue) pj_time_val now; pj_ioqueue_key_t *h; - pj_gettimeofday(&now); + pj_gettickcount(&now); h = ioqueue->closing_list.next; while (h != &ioqueue->closing_list) { pj_ioqueue_key_t *next = h->next; diff --git a/pjlib/src/pj/ioqueue_winnt.c b/pjlib/src/pj/ioqueue_winnt.c index 22bf0a94..34924779 100644 --- a/pjlib/src/pj/ioqueue_winnt.c +++ b/pjlib/src/pj/ioqueue_winnt.c @@ -619,7 +619,7 @@ static void decrement_counter(pj_ioqueue_key_t *key) pj_lock_acquire(key->ioqueue->lock); pj_assert(key->closing == 1); - pj_gettimeofday(&key->free_time); + pj_gettickcount(&key->free_time); key->free_time.msec += PJ_IOQUEUE_KEY_FREE_DELAY; pj_time_val_normalize(&key->free_time); @@ -874,7 +874,7 @@ static void scan_closing_keys(pj_ioqueue_t *ioqueue) pj_time_val now; pj_ioqueue_key_t *key; - pj_gettimeofday(&now); + pj_gettickcount(&now); /* Move closing keys to free list when they've finished the closing * idle time. diff --git a/pjlib/src/pj/os_timestamp_common.c b/pjlib/src/pj/os_timestamp_common.c index 293f6162..c7f32c69 100644 --- a/pjlib/src/pj/os_timestamp_common.c +++ b/pjlib/src/pj/os_timestamp_common.c @@ -188,5 +188,19 @@ PJ_DEF(pj_uint32_t) pj_elapsed_cycle( const pj_timestamp *start, return stop->u32.lo - start->u32.lo; } +PJ_DEF(pj_status_t) pj_gettickcount(pj_time_val *tv) +{ + pj_timestamp ts, start; + pj_status_t status; + + if ((status = pj_get_timestamp(&ts)) != PJ_SUCCESS) + return status; + + pj_set_timestamp32(&start, 0, 0); + *tv = pj_elapsed_time(&start, &ts); + + return PJ_SUCCESS; +} + #endif /* PJ_HAS_HIGH_RES_TIMER */ diff --git a/pjlib/src/pj/os_timestamp_posix.c b/pjlib/src/pj/os_timestamp_posix.c index 258241a0..353177b1 100644 --- a/pjlib/src/pj/os_timestamp_posix.c +++ b/pjlib/src/pj/os_timestamp_posix.c @@ -24,6 +24,16 @@ #include #include +#if defined(PJ_HAS_UNISTD_H) && PJ_HAS_UNISTD_H != 0 +# include + +# if defined(_POSIX_TIMERS) && _POSIX_TIMERS > 0 && \ + defined(_POSIX_MONOTONIC_CLOCK) +# define USE_POSIX_TIMERS 1 +# endif + +#endif + #if defined(PJ_HAS_PENTIUM) && PJ_HAS_PENTIUM!=0 && \ defined(PJ_TIMESTAMP_USE_RDTSC) && PJ_TIMESTAMP_USE_RDTSC!=0 && \ defined(PJ_M_I386) && PJ_M_I386!=0 && \ @@ -110,6 +120,73 @@ PJ_DEF(pj_status_t) pj_get_timestamp_freq(pj_timestamp *freq) return 0; } +#elif defined(PJ_DARWINOS) && PJ_DARWINOS != 0 +#include +#include +#include + +#define NSEC_PER_SEC 1000000000 + +PJ_DEF(pj_status_t) pj_get_timestamp(pj_timestamp *ts) +{ + mach_timespec_t tp; + int ret; + clock_serv_t serv; + + ret = host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &serv); + if (ret != KERN_SUCCESS) { + return PJ_RETURN_OS_ERROR(EINVAL); + } + + ret = clock_get_time(serv, &tp); + if (ret != KERN_SUCCESS) { + return PJ_RETURN_OS_ERROR(EINVAL); + } + + ts->u64 = tp.tv_sec; + ts->u64 *= NSEC_PER_SEC; + ts->u64 += tp.tv_nsec; + + return PJ_SUCCESS; +} + +PJ_DEF(pj_status_t) pj_get_timestamp_freq(pj_timestamp *freq) +{ + freq->u32.hi = 0; + freq->u32.lo = NSEC_PER_SEC; + + return PJ_SUCCESS; +} + +#elif defined(USE_POSIX_TIMERS) && USE_POSIX_TIMERS != 0 +#include +#include + +#define NSEC_PER_SEC 1000000000 + +PJ_DEF(pj_status_t) pj_get_timestamp(pj_timestamp *ts) +{ + struct timespec tp; + + if (clock_gettime(CLOCK_MONOTONIC, &tp) != 0) { + return PJ_RETURN_OS_ERROR(pj_get_native_os_error()); + } + + ts->u64 = tp.tv_sec; + ts->u64 *= NSEC_PER_SEC; + ts->u64 += tp.tv_nsec; + + return PJ_SUCCESS; +} + +PJ_DEF(pj_status_t) pj_get_timestamp_freq(pj_timestamp *freq) +{ + freq->u32.hi = 0; + freq->u32.lo = NSEC_PER_SEC; + + return PJ_SUCCESS; +} + #else #include #include @@ -140,4 +217,3 @@ PJ_DEF(pj_status_t) pj_get_timestamp_freq(pj_timestamp *freq) } #endif - diff --git a/pjlib/src/pj/symbols.c b/pjlib/src/pj/symbols.c index dc4c8c8f..bca6c5ce 100644 --- a/pjlib/src/pj/symbols.c +++ b/pjlib/src/pj/symbols.c @@ -197,6 +197,7 @@ PJ_EXPORT_SYMBOL(pj_sem_destroy) PJ_EXPORT_SYMBOL(pj_gettimeofday) PJ_EXPORT_SYMBOL(pj_time_decode) #if defined(PJ_HAS_HIGH_RES_TIMER) && PJ_HAS_HIGH_RES_TIMER != 0 +PJ_EXPORT_SYMBOL(pj_gettickcount) PJ_EXPORT_SYMBOL(pj_get_timestamp) PJ_EXPORT_SYMBOL(pj_get_timestamp_freq) PJ_EXPORT_SYMBOL(pj_elapsed_time) diff --git a/pjlib/src/pj/timer.c b/pjlib/src/pj/timer.c index 9ab3ab54..573c7ecb 100644 --- a/pjlib/src/pj/timer.c +++ b/pjlib/src/pj/timer.c @@ -465,7 +465,7 @@ PJ_DEF(pj_status_t) pj_timer_heap_schedule( pj_timer_heap_t *ht, /* Prevent same entry from being scheduled more than once */ PJ_ASSERT_RETURN(entry->_timer_id < 1, PJ_EINVALIDOP); - pj_gettimeofday(&expires); + pj_gettickcount(&expires); PJ_TIME_VAL_ADD(expires, *delay); lock_timer_heap(ht); @@ -503,7 +503,7 @@ PJ_DEF(unsigned) pj_timer_heap_poll( pj_timer_heap_t *ht, } count = 0; - pj_gettimeofday(&now); + pj_gettickcount(&now); lock_timer_heap(ht); while ( ht->cur_size && -- cgit v1.2.3