forked from acouzens/open5gs
245 lines
5.2 KiB
C
245 lines
5.2 KiB
C
#define TRACE_MODULE _timer
|
|
#include "core_debug.h"
|
|
#include "core_timer.h"
|
|
#include "core_time.h"
|
|
#include "core_param.h"
|
|
#include "core_pool.h"
|
|
|
|
typedef struct _tm_block_t {
|
|
lnode_t node;
|
|
|
|
tm_service_t *tm_s;
|
|
c_uint32_t expire_time;
|
|
|
|
expire_func_t expire_func;
|
|
c_uintptr_t arg1;
|
|
c_uintptr_t arg2;
|
|
c_uintptr_t arg3;
|
|
|
|
tm_type_e type;
|
|
c_uint8_t running;
|
|
c_uint32_t duration;
|
|
} tm_block_t;
|
|
|
|
pool_declare(timer_pool, tm_block_t, MAX_NUM_OF_TIMER);
|
|
|
|
static int _tm_cmp_func(lnode_t *pnode1, lnode_t *pnode2);
|
|
static tm_block_t *_tm_get(void);
|
|
static void _tm_free(tm_block_t *tm);
|
|
|
|
#define _tm_add(__l, __tm) \
|
|
list_insert_sorted(__l, __tm, _tm_cmp_func)
|
|
|
|
#define _tm_remove(__l, __tm) \
|
|
list_remove(__l, __tm)
|
|
|
|
status_t tm_init(void)
|
|
{
|
|
pool_init(&timer_pool, MAX_NUM_OF_TIMER);
|
|
return CORE_OK;
|
|
}
|
|
|
|
status_t tm_final(void)
|
|
{
|
|
pool_final(&timer_pool);
|
|
return CORE_OK;
|
|
}
|
|
|
|
c_uint32_t tm_pool_avail(void)
|
|
{
|
|
return pool_avail(&timer_pool);
|
|
}
|
|
|
|
void tm_service_init(tm_service_t *tm_service)
|
|
{
|
|
memset(tm_service, 0x00, sizeof(tm_service_t));
|
|
list_init(&tm_service->active_list);
|
|
list_init(&tm_service->idle_list);
|
|
return;
|
|
}
|
|
|
|
status_t tm_execute_tm_service(tm_service_t *p_tm_s)
|
|
{
|
|
c_uint32_t cur_time;
|
|
tm_block_t *tm;
|
|
|
|
cur_time = time_as_msec(time_now());
|
|
tm = list_first(&(p_tm_s->active_list));
|
|
|
|
while(tm)
|
|
{
|
|
if(tm->expire_time < cur_time)
|
|
{
|
|
/* execute expiry function */
|
|
tm->expire_func(tm->arg1, tm->arg2, tm->arg3);
|
|
|
|
/* remove this tm_block from the active list */
|
|
_tm_remove(&(p_tm_s->active_list), tm);
|
|
|
|
if(tm->type == TIMER_TYPE_PERIODIC)
|
|
{
|
|
tm->expire_time = cur_time + tm->duration;
|
|
|
|
/* add this tm_block to the active list */
|
|
_tm_add(&(p_tm_s->active_list), tm);
|
|
}
|
|
else
|
|
{
|
|
/* add this tm_block to the idle list */
|
|
_tm_add(&(p_tm_s->idle_list), tm);
|
|
tm->running = 0;
|
|
}
|
|
|
|
tm = list_first(&(p_tm_s->active_list));
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
return CORE_OK;
|
|
}
|
|
|
|
static int _tm_cmp_func(lnode_t *pnode1, lnode_t *pnode2)
|
|
{
|
|
tm_block_t *tm1 = (tm_block_t*)pnode1;
|
|
tm_block_t *tm2 = (tm_block_t*)pnode2;
|
|
|
|
if(tm1->expire_time < tm2->expire_time)
|
|
return -1;
|
|
else
|
|
return 1;
|
|
}
|
|
|
|
static tm_block_t *_tm_get(void)
|
|
{
|
|
tm_block_t *tm_b = NULL;
|
|
|
|
/* get timer node from node pool */
|
|
pool_alloc_node(&timer_pool, &tm_b);
|
|
|
|
/* check for error */
|
|
d_assert(tm_b != NULL, return NULL, "fail to get timer pool\n");
|
|
|
|
/* intialize timer node */
|
|
memset((char*)tm_b, 0x00, sizeof(tm_block_t));
|
|
return tm_b;
|
|
|
|
}
|
|
|
|
static void _tm_free(tm_block_t *tm)
|
|
{
|
|
/* free tlv node to the node pool */
|
|
pool_free_node(&timer_pool, tm);
|
|
return;
|
|
|
|
}
|
|
|
|
tm_block_id tm_create(tm_service_t *tm_service)
|
|
{
|
|
tm_block_t *tm = NULL;
|
|
tm = _tm_get();
|
|
|
|
d_assert(tm, return 0, "tm_create failed\n");
|
|
tm->tm_s = tm_service;
|
|
|
|
_tm_add(&(tm->tm_s->idle_list), tm);
|
|
|
|
return (tm_block_id)tm;
|
|
}
|
|
|
|
void tm_delete(tm_block_id id)
|
|
{
|
|
tm_block_t *tm = (tm_block_t *)id;
|
|
|
|
/* If running timer, pop it from active list */
|
|
if (tm->running == 1)
|
|
_tm_remove(&(tm->tm_s->active_list), tm);
|
|
/* If not running timer, pop it from idle list */
|
|
else
|
|
_tm_remove(&(tm->tm_s->idle_list), tm);
|
|
|
|
_tm_free(tm);
|
|
|
|
return;
|
|
}
|
|
|
|
status_t tm_set(
|
|
tm_block_id id, tm_type_e type, c_uint32_t duration,
|
|
expire_func_t expire_func,
|
|
c_uintptr_t arg1, c_uintptr_t arg2, c_uintptr_t arg3)
|
|
{
|
|
tm_block_t *tm = (tm_block_t *)id;
|
|
|
|
tm->type = type;
|
|
tm->duration = duration;
|
|
tm->expire_func = expire_func;
|
|
tm->arg1 = arg1;
|
|
tm->arg2 = arg2;
|
|
tm->arg3 = arg3;
|
|
|
|
return CORE_OK;
|
|
}
|
|
|
|
status_t tm_set_duration(tm_block_id id, c_uint32_t duration)
|
|
{
|
|
tm_block_t *tm = (tm_block_t *)id;
|
|
|
|
tm->duration = duration;
|
|
|
|
return CORE_OK;
|
|
}
|
|
|
|
status_t tm_set_by_desc(tm_block_id id, tm_desc_t *desc)
|
|
{
|
|
tm_block_t *tm = (tm_block_t *)id;
|
|
|
|
tm->type = desc->type;
|
|
tm->duration = desc->duration;
|
|
tm->expire_func = desc->expire_func;
|
|
tm->arg1 = desc->arg1;
|
|
tm->arg2 = desc->arg2;
|
|
tm->arg3 = desc->arg3;
|
|
|
|
return CORE_OK;
|
|
}
|
|
|
|
status_t tm_start(tm_block_id id)
|
|
{
|
|
c_uint32_t cur_time = time_as_msec(time_now());
|
|
tm_block_t *tm = (tm_block_t *)id;
|
|
|
|
/* If already running timer, pop it from active list for put again */
|
|
if (tm->running == 1)
|
|
_tm_remove(&(tm->tm_s->active_list), tm);
|
|
/* If not running, tm is in idle list. pop it */
|
|
else
|
|
_tm_remove(&(tm->tm_s->idle_list), tm);
|
|
|
|
/* Calculate expiration */
|
|
tm->expire_time = cur_time + tm->duration;
|
|
|
|
/* Push tm to active list */
|
|
_tm_add(&(tm->tm_s->active_list), tm);
|
|
|
|
tm->running = 1;
|
|
|
|
return CORE_OK;
|
|
}
|
|
|
|
status_t tm_stop(tm_block_id id)
|
|
{
|
|
tm_block_t *tm = (tm_block_t *)id;
|
|
|
|
/* If already stopped timer, no operations needed */
|
|
if (tm->running == 0)
|
|
return CORE_OK;
|
|
|
|
_tm_remove(&(tm->tm_s->active_list), tm);
|
|
_tm_add(&(tm->tm_s->idle_list), tm);
|
|
|
|
tm->running = 0;
|
|
|
|
return CORE_OK;
|
|
}
|