summaryrefslogtreecommitdiff
path: root/pjlib
diff options
context:
space:
mode:
authorLiong Sauw Ming <ming@teluu.com>2011-03-16 09:22:24 +0000
committerLiong Sauw Ming <ming@teluu.com>2011-03-16 09:22:24 +0000
commit623fdccd9c92fc2a00516e5cd6ed2d5edc2272a1 (patch)
treebf30cf0db67ac5c9aa3f431efdaa7d1938656a31 /pjlib
parent2a9988f3e4c9b8d40ffebaa4427908de29324711 (diff)
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
Diffstat (limited to 'pjlib')
-rw-r--r--pjlib/include/pj/os.h9
-rw-r--r--pjlib/src/pj/ioqueue_epoll.c4
-rw-r--r--pjlib/src/pj/ioqueue_select.c4
-rw-r--r--pjlib/src/pj/ioqueue_winnt.c4
-rw-r--r--pjlib/src/pj/os_timestamp_common.c14
-rw-r--r--pjlib/src/pj/os_timestamp_posix.c78
-rw-r--r--pjlib/src/pj/symbols.c1
-rw-r--r--pjlib/src/pj/timer.c4
8 files changed, 109 insertions, 9 deletions
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
@@ -1169,6 +1169,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 <stdlib.h>
#include <ctype.h>
+#if defined(PJ_HAS_UNISTD_H) && PJ_HAS_UNISTD_H != 0
+# include <unistd.h>
+
+# 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 <mach/mach.h>
+#include <mach/clock.h>
+#include <errno.h>
+
+#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 <sys/time.h>
+#include <errno.h>
+
+#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 <sys/time.h>
#include <errno.h>
@@ -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 &&