SCTP 庫的簡述和代碼 (4)

2 定時器app

簡單的時間輪. 使用時間輪是由於, 定時器數目可能比較大. rest

要求使用者週期性調用, p_timer_wheel_hbelement

缺點是, 不精確.get

 

 

/* Hash table for hold timer list */
static list_header wheel_slot[WHEEL_ELEM];
static unsigned int svd_tick;
static int cur_slot = 0;it

#ifndef WIN32
unsigned int GetTickCount()
{
    struct timeval current;
    unsigned int cur_time;io

    gettimeofday(&current, NULL);
    cur_time = current.tv_sec*1000 + current.tv_usec/1000;table

    return cur_time;
}
#endif定時器

unsigned int get_cur_time()
{
    return GetTickCount();
}queue


void p_timer_restart (p_timer_t *new_timer)
{
    int target_slot;
    list_header *timer_list;im

    assert(new_timer);
   
    target_slot = (cur_slot + new_timer->period_ms)%WHEEL_ELEM;
    new_timer->left_sec = new_timer->period_ms/WHEEL_ELEM;
   
    timer_list = &wheel_slot[target_slot];
    list_enqueue_tail(timer_list, &new_timer->list);
}

p_timer_t* p_timer_start (int period_ms,
                         timer_callback timer_cb,
                         void *app_context)
{
    p_timer_t* new_timer;
    int target_slot;
    list_header *timer_list;

    assert(timer_cb);
    assert(period_ms);
    new_timer = malloc_obj(sizeof(p_timer_t), TIMER_MEM_OBJ);
    assert(new_timer);

    new_timer->app_context = app_context;
    new_timer->timer_cb = timer_cb;
    new_timer->period_ms = period_ms;
    new_timer->left_sec =  new_timer->period_ms / WHEEL_ELEM;


    target_slot = (cur_slot + period_ms)%WHEEL_ELEM;
    timer_list = &wheel_slot[target_slot];
    list_enqueue_tail(timer_list, &new_timer->list);
    return new_timer;
}

BOOL p_timer_running(p_timer_t *timer)
{
    if (timer == NULL) {
        return FALSE;
    }
    return (timer->period_ms == 0);
}

BOOL p_timer_stop(p_timer_t *timer)
{
    if (timer == NULL) {
        return FALSE;
    }
    timer->period_ms = 0;
    return TRUE;
}

void p_timer_wheel_hb()
{
    list_header *tmr_list;
    list_head *element, *tmp_elem;
    p_timer_t *tmr;
    unsigned int cur_tick, delta_tick;

    cur_tick = GetTickCount();
    if (svd_tick == 0) {
        svd_tick = cur_tick;
    }
    delta_tick = cur_tick - svd_tick;
    svd_tick = cur_tick;
    while (delta_tick--) {
        tmr_list = &wheel_slot[cur_slot];
        list_for_each_safe(tmr_list, tmp_elem, element) {
            tmr = list_entry(element, p_timer_t, list);
            if (tmr->left_sec) {
                tmr->left_sec--;
                continue;
            }
            list_delink(tmr_list, element);
            if (tmr->period_ms == 0) {
                free_obj(tmr, TIMER_MEM_OBJ);
            } else {
                tmr->timer_cb(tmr, tmr->app_context);
                p_timer_restart(tmr);
            }
        }
        cur_slot = (cur_slot + 1) % WHEEL_ELEM;
    }
    return;
}

void timer_proc_exit()
{
    int i;
    list_head *element, *tmp_elem;
    p_timer_t* p_timer;
    list_header *tmr_list;


    for (i = 0; i < WHEEL_ELEM; i++) {
        tmr_list = &wheel_slot[i];
        list_for_each_safe(tmr_list, tmp_elem, element) {
            p_timer = list_entry(element, p_timer_t, list);
            list_delink(tmr_list, element);
            free_obj(p_timer, TIMER_MEM_OBJ);
        }
    }
}

//------------- Internal API -------------------------------------------------- void timer_subsys_init() {     int i;         svd_tick = 0;     for (i = 0; i< WHEEL_ELEM; i++) {         list_init(&wheel_slot[i]);     } }

相關文章
相關標籤/搜索