pjsip logo pjsip.org
Open source SIP stack and media stack for presence, im/instant messaging, and multimedia communication

HOME

SIP/media Features
High Performance SIP
Small Footprint SIP
Symbian Port

FAQ

Documentation

Licensing

Download

Development (Trac)

Projects using pjsip

Mailing List

Open Source Links


About: PJLIB, PJLIB-UTIL, PJSIP, and PJMEDIA are created by: Benny Prijono
<bennylp@pjsip.org>


 

Home --> Documentations --> PJLIB Reference

Test: Timer

This file provides implementation of timer_test(). It tests the functionality of the timer heap.

This file is pjlib-test/timer.c

/* $Id: timer.c 2039 2008-06-20 22:44:47Z bennylp $ */
/* 
 * Copyright (C)2003-2008 Benny Prijono <benny@prijono.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 */
#include "test.h"

#if INCLUDE_TIMER_TEST

#include <pjlib.h>

#define LOOP            16
#define MIN_COUNT       250
#define MAX_COUNT       (LOOP * MIN_COUNT)
#define MIN_DELAY       2
#define D               (MAX_COUNT / 32000)
#define DELAY           (D < MIN_DELAY ? MIN_DELAY : D)
#define THIS_FILE       "timer_test"


static void timer_callback(pj_timer_heap_t *ht, pj_timer_entry *e)
{
    PJ_UNUSED_ARG(ht);
    PJ_UNUSED_ARG(e);
}

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);
            rc = pj_timer_heap_poll(timer, NULL);
            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;
}


int timer_test()
{
    return test_timer_heap();
}

#else
/* To prevent warning about "translation unit is empty"
 * when this test is disabled. 
 */
int dummy_timer_test;
#endif  /* INCLUDE_TIMER_TEST */


 


PJLIB Open Source, high performance, small footprint, and very very portable framework
(C)2001-2008 Benny Prijono