Index: pjproject/trunk/pjlib/include/pj/os.h
===================================================================
--- pjproject/trunk/pjlib/include/pj/os.h	(revision 3455)
+++ pjproject/trunk/pjlib/include/pj/os.h	(revision 3456)
@@ -1170,4 +1170,13 @@
 
 /**
+ * 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.
Index: pjproject/trunk/pjlib/src/pj/ioqueue_epoll.c
===================================================================
--- pjproject/trunk/pjlib/src/pj/ioqueue_epoll.c	(revision 3455)
+++ pjproject/trunk/pjlib/src/pj/ioqueue_epoll.c	(revision 3456)
@@ -466,5 +466,5 @@
 
 	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);
@@ -584,5 +584,5 @@
     pj_ioqueue_key_t *h;
 
-    pj_gettimeofday(&now);
+    pj_gettickcount(&now);
     h = ioqueue->closing_list.next;
     while (h != &ioqueue->closing_list) {
Index: pjproject/trunk/pjlib/src/pj/ioqueue_select.c
===================================================================
--- pjproject/trunk/pjlib/src/pj/ioqueue_select.c	(revision 3455)
+++ pjproject/trunk/pjlib/src/pj/ioqueue_select.c	(revision 3456)
@@ -412,5 +412,5 @@
 
 	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);
@@ -609,5 +609,5 @@
     pj_ioqueue_key_t *h;
 
-    pj_gettimeofday(&now);
+    pj_gettickcount(&now);
     h = ioqueue->closing_list.next;
     while (h != &ioqueue->closing_list) {
Index: pjproject/trunk/pjlib/src/pj/ioqueue_winnt.c
===================================================================
--- pjproject/trunk/pjlib/src/pj/ioqueue_winnt.c	(revision 3455)
+++ pjproject/trunk/pjlib/src/pj/ioqueue_winnt.c	(revision 3456)
@@ -620,5 +620,5 @@
 
 	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);
@@ -875,5 +875,5 @@
 	pj_ioqueue_key_t *key;
 
-	pj_gettimeofday(&now);
+	pj_gettickcount(&now);
 	
 	/* Move closing keys to free list when they've finished the closing
Index: pjproject/trunk/pjlib/src/pj/os_timestamp_common.c
===================================================================
--- pjproject/trunk/pjlib/src/pj/os_timestamp_common.c	(revision 3455)
+++ pjproject/trunk/pjlib/src/pj/os_timestamp_common.c	(revision 3456)
@@ -189,4 +189,18 @@
 }
 
+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 */
 
Index: pjproject/trunk/pjlib/src/pj/os_timestamp_posix.c
===================================================================
--- pjproject/trunk/pjlib/src/pj/os_timestamp_posix.c	(revision 3455)
+++ pjproject/trunk/pjlib/src/pj/os_timestamp_posix.c	(revision 3456)
@@ -25,4 +25,14 @@
 #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 && \
@@ -111,4 +121,71 @@
 }
 
+#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>
@@ -141,3 +218,2 @@
 
 #endif
-
Index: pjproject/trunk/pjlib/src/pj/symbols.c
===================================================================
--- pjproject/trunk/pjlib/src/pj/symbols.c	(revision 3455)
+++ pjproject/trunk/pjlib/src/pj/symbols.c	(revision 3456)
@@ -198,4 +198,5 @@
 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)
Index: pjproject/trunk/pjlib/src/pj/timer.c
===================================================================
--- pjproject/trunk/pjlib/src/pj/timer.c	(revision 3455)
+++ pjproject/trunk/pjlib/src/pj/timer.c	(revision 3456)
@@ -466,5 +466,5 @@
     PJ_ASSERT_RETURN(entry->_timer_id < 1, PJ_EINVALIDOP);
 
-    pj_gettimeofday(&expires);
+    pj_gettickcount(&expires);
     PJ_TIME_VAL_ADD(expires, *delay);
     
@@ -504,5 +504,5 @@
 
     count = 0;
-    pj_gettimeofday(&now);
+    pj_gettickcount(&now);
 
     lock_timer_heap(ht);
