static int timer_thread_run(void* p) { pj_time_val tick = {0, 10}; timer_running = 1; while (timer_running) { if (pj_timer_heap_count(timer) == 0) { pj_sem_wait(timer_sem); } else { pj_thread_sleep(PJ_TIME_VAL_MSEC(tick)); pj_timer_heap_poll(timer, NULL); } } pj_timer_heap_destroy(timer); timer = NULL; pj_sem_destroy(timer_sem); timer_sem = NULL; pj_pool_release(timer_pool); timer_pool = NULL; timer_initialized = 0; return 0; }
void capture_pjlib_state(pj_stun_config *cfg, struct pjlib_state *st) { pj_caching_pool *cp; st->timer_cnt = (unsigned)pj_timer_heap_count(cfg->timer_heap); cp = (pj_caching_pool*)cfg->pf; st->pool_used_cnt = (unsigned)cp->used_count; }
// // Get current number of timers // pj_size_t count() { return pj_timer_heap_count(ht_); }
static int test_timer_heap(void) { int i, j; pj_timer_entry *entry; pj_pool_t *pool; pj_timer_heap_t *timer; pj_time_val delay; pj_status_t rc; int err=0; unsigned size, count; size = pj_timer_heap_mem_size(MAX_COUNT)+MAX_COUNT*sizeof(pj_timer_entry); pool = pj_pool_create( mem, NULL, size, 4000, NULL); if (!pool) { PJ_LOG(3,("test", "...error: unable to create pool of %u bytes", size)); return -10; } entry = (pj_timer_entry*)pj_pool_calloc(pool, MAX_COUNT, sizeof(*entry)); if (!entry) return -20; for (i=0; i<MAX_COUNT; ++i) { entry[i].cb = &timer_callback; } rc = pj_timer_heap_create(pool, MAX_COUNT, &timer); if (rc != PJ_SUCCESS) { app_perror("...error: unable to create timer heap", rc); return -30; } count = MIN_COUNT; for (i=0; i<LOOP; ++i) { int early = 0; int done=0; int cancelled=0; int rc; pj_timestamp t1, t2, t_sched, t_cancel, t_poll; pj_time_val now, expire; pj_gettimeofday(&now); pj_srand(now.sec); t_sched.u32.lo = t_cancel.u32.lo = t_poll.u32.lo = 0; // Register timers for (j=0; j<(int)count; ++j) { delay.sec = pj_rand() % DELAY; delay.msec = pj_rand() % 1000; // Schedule timer pj_get_timestamp(&t1); rc = pj_timer_heap_schedule(timer, &entry[j], &delay); if (rc != 0) return -40; pj_get_timestamp(&t2); t_sched.u32.lo += (t2.u32.lo - t1.u32.lo); // Poll timers. pj_get_timestamp(&t1); rc = pj_timer_heap_poll(timer, NULL); pj_get_timestamp(&t2); if (rc > 0) { t_poll.u32.lo += (t2.u32.lo - t1.u32.lo); early += rc; } } // Set the time where all timers should finish pj_gettimeofday(&expire); delay.sec = DELAY; delay.msec = 0; PJ_TIME_VAL_ADD(expire, delay); // Wait unfil all timers finish, cancel some of them. do { int index = pj_rand() % count; pj_get_timestamp(&t1); rc = pj_timer_heap_cancel(timer, &entry[index]); pj_get_timestamp(&t2); if (rc > 0) { cancelled += rc; t_cancel.u32.lo += (t2.u32.lo - t1.u32.lo); } pj_gettimeofday(&now); pj_get_timestamp(&t1); #if defined(PJ_SYMBIAN) && PJ_SYMBIAN!=0 /* On Symbian, we must use OS poll (Active Scheduler poll) since * timer is implemented using Active Object. */ rc = 0; while (pj_symbianos_poll(-1, 0)) ++rc; #else rc = pj_timer_heap_poll(timer, NULL); #endif pj_get_timestamp(&t2); if (rc > 0) { done += rc; t_poll.u32.lo += (t2.u32.lo - t1.u32.lo); } } while (PJ_TIME_VAL_LTE(now, expire)&&pj_timer_heap_count(timer) > 0); if (pj_timer_heap_count(timer)) { PJ_LOG(3, (THIS_FILE, "ERROR: %d timers left", pj_timer_heap_count(timer))); ++err; } t_sched.u32.lo /= count; t_cancel.u32.lo /= count; t_poll.u32.lo /= count; PJ_LOG(4, (THIS_FILE, "...ok (count:%d, early:%d, cancelled:%d, " "sched:%d, cancel:%d poll:%d)", count, early, cancelled, t_sched.u32.lo, t_cancel.u32.lo, t_poll.u32.lo)); count = count * 2; if (count > MAX_COUNT) break; } pj_pool_release(pool); return err; }