SCTP 库的简述和代码 (4)

試著忘記壹切 提交于 2019-12-06 04:16:47

2 定时器

简单的时间轮. 使用时间轮是因为, 定时器数目可能比较大.

要求使用者周期性调用, p_timer_wheel_hb

缺点是, 不精确.

 

 

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

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

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

    return cur_time;
}
#endif

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


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

    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]);
    }
}

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!