diff options
Diffstat (limited to 'src/framework/ipc/ps/nsfw_fd_timer.c')
-rw-r--r-- | src/framework/ipc/ps/nsfw_fd_timer.c | 374 |
1 files changed, 199 insertions, 175 deletions
diff --git a/src/framework/ipc/ps/nsfw_fd_timer.c b/src/framework/ipc/ps/nsfw_fd_timer.c index cea2486..fc71748 100644 --- a/src/framework/ipc/ps/nsfw_fd_timer.c +++ b/src/framework/ipc/ps/nsfw_fd_timer.c @@ -22,10 +22,8 @@ #include "types.h" #include "list.h" -#include "common_mem_common.h" - #include "nstack_securec.h" -#include "nsfw_init.h" +#include "nsfw_init_api.h" #include "nsfw_mgr_com_api.h" #include "nsfw_mem_api.h" #include "nstack_log.h" @@ -42,11 +40,10 @@ extern "C"{ #define NSFW_TIMER_CYCLE 1 #define NSFW_TIMER_INFO_MAX_COUNT_DEF 8191 #define NSFW_TIMER_INFO_MAX_COUNT (g_timer_cfg.timer_info_size) -/* *INDENT-OFF* */ + nsfw_timer_init_cfg g_timer_cfg; u8 g_hbt_switch = FALSE; -/* *INDENT-ON* */ /***************************************************************************** * Prototype : nsfw_timer_reg_timer @@ -59,38 +56,39 @@ u8 g_hbt_switch = FALSE; * Return Value : nsfw_timer_info* * Calls : * Called By : -* *****************************************************************************/ -nsfw_timer_info * -nsfw_timer_reg_timer (u32 timer_type, void *data, - nsfw_timer_proc_fun fun, struct timespec time_left) +nsfw_timer_info *nsfw_timer_reg_timer(u32 timer_type, void *data, + nsfw_timer_proc_fun fun, + struct timespec time_left) { - nsfw_timer_info *tm_info = NULL; - if (0 == - nsfw_mem_ring_dequeue (g_timer_cfg.timer_info_pool, (void *) &tm_info)) + nsfw_timer_info *tm_info = NULL; + if (0 == + nsfw_mem_ring_dequeue(g_timer_cfg.timer_info_pool, (void *) &tm_info)) { - NSFW_LOGERR ("dequeue error]data=%p,fun=%p", data, fun); - return NULL; + NSFW_LOGERR("dequeue error]data=%p,fun=%p", data, fun); + return NULL; } - if (EOK != MEMSET_S (tm_info, sizeof (*tm_info), 0, sizeof (*tm_info))) + if (EOK != memset_s(tm_info, sizeof(*tm_info), 0, sizeof(*tm_info))) { - if (0 == nsfw_mem_ring_enqueue (g_timer_cfg.timer_info_pool, tm_info)) + if (0 == nsfw_mem_ring_enqueue(g_timer_cfg.timer_info_pool, tm_info)) { - NSFW_LOGERR ("enqueue error]data=%p,fun=%p", data, fun); + NSFW_LOGERR("enqueue error]data=%p,fun=%p", data, fun); } - NSFW_LOGERR ("mem set error]data=%p,fun=%p", data, fun); - return NULL; + NSFW_LOGERR("mem set error]data=%p,fun=%p", data, fun); + return NULL; } - tm_info->fun = fun; - tm_info->argv = data; - tm_info->time_left = time_left; - //tm_info->time_left.tv_sec += NSFW_TIMER_CYCLE; - tm_info->timer_type = timer_type; - list_add_tail (&tm_info->node, &g_timer_cfg.timer_head); - tm_info->alloc_flag = TRUE; - return tm_info; + tm_info->fun = fun; + tm_info->argv = data; + tm_info->time_left = time_left; + tm_info->timer_type = timer_type; + tm_info->alloc_flag = TRUE; + /* it can start timer after only finish all timer reg, or else it have multi-thread issue */ + dmm_spin_lock(&g_timer_cfg.timer_lock); + list_add_tail(&tm_info->node, &g_timer_cfg.timer_head); + dmm_spin_unlock(&g_timer_cfg.timer_lock); + return tm_info; } /***************************************************************************** @@ -101,32 +99,34 @@ nsfw_timer_reg_timer (u32 timer_type, void *data, * Return Value : void * Calls : * Called By : -* *****************************************************************************/ -void -nsfw_timer_rmv_timer (nsfw_timer_info * tm_info) +void nsfw_timer_rmv_timer(nsfw_timer_info * tm_info) { - if (NULL == tm_info) + if (NULL == tm_info) { - NSFW_LOGWAR ("tm_info nul"); - return; + NSFW_LOGWAR("tm_info nul"); + return; } + /* it can start timer after only finish all timer reg, or else it have multi-thread issue */ + dmm_spin_lock(&g_timer_cfg.timer_lock); - if (FALSE == tm_info->alloc_flag) + if (FALSE == tm_info->alloc_flag) { - NSFW_LOGERR ("tm_info refree]tm_info=%p,argv=%p,fun=%p", tm_info, - tm_info->argv, tm_info->fun); - return; + dmm_spin_unlock(&g_timer_cfg.timer_lock); + NSFW_LOGERR("tm_info refree]tm_info=%p,argv=%p,fun=%p", tm_info, + tm_info->argv, tm_info->fun); + return; } - tm_info->alloc_flag = FALSE; - list_del (&tm_info->node); - if (0 == nsfw_mem_ring_enqueue (g_timer_cfg.timer_info_pool, tm_info)) + tm_info->alloc_flag = FALSE; + list_del(&tm_info->node); + if (0 == nsfw_mem_ring_enqueue(g_timer_cfg.timer_info_pool, tm_info)) { - NSFW_LOGERR ("tm_info free failed]tm_info=%p,argv=%p,fun=%p", tm_info, - tm_info->argv, tm_info->fun); + NSFW_LOGERR("tm_info free failed]tm_info=%p,argv=%p,fun=%p", tm_info, + tm_info->argv, tm_info->fun); } - return; + dmm_spin_unlock(&g_timer_cfg.timer_lock); + return; } /***************************************************************************** @@ -137,41 +137,59 @@ nsfw_timer_rmv_timer (nsfw_timer_info * tm_info) * Return Value : u8 * Calls : * Called By : -* *****************************************************************************/ -void -nsfw_timer_exp (u64 count) +void nsfw_timer_exp(u64 count) { - nsfw_timer_info *tm_info = NULL; - struct list_head *tNode; - struct list_head *tPretNode; - - LINT_LIST ()list_for_each_entry (tm_info, tNode, (&g_timer_cfg.timer_head), - node) - { - tPretNode = tm_info->node.prev; - if (tm_info->time_left.tv_sec > (long) count * NSFW_TIMER_CYCLE) - { - tm_info->time_left.tv_sec -= count * NSFW_TIMER_CYCLE; - continue; - } - - list_del (&tm_info->node); - list_add_tail (&tm_info->node, &g_timer_cfg.exp_timer_head); - tNode = tPretNode; - } - - u32 i = 0; - while (!list_empty (&g_timer_cfg.exp_timer_head) - && i++ < NSFW_TIMER_INFO_MAX_COUNT) + nsfw_timer_info *tm_info = NULL; + struct list_head *tNode; + struct list_head *tPretNode; + + /* it can start timer after only finish all timer reg, or else it have multi-thread issue */ + dmm_spin_lock(&g_timer_cfg.timer_lock); + + list_for_each_entry(tm_info, tNode, (&g_timer_cfg.timer_head), node) + { + + tPretNode = tm_info->node.prev; + if (tm_info->time_left.tv_sec > (long) count * NSFW_TIMER_CYCLE) + { + tm_info->time_left.tv_sec -= count * NSFW_TIMER_CYCLE; + continue; + } + + list_del(&tm_info->node); + list_add_tail(&tm_info->node, &g_timer_cfg.exp_timer_head); + tNode = tPretNode; + } + dmm_spin_unlock(&g_timer_cfg.timer_lock); + + u32 i = 0; + while (!list_empty(&g_timer_cfg.exp_timer_head) + && i++ < NSFW_TIMER_INFO_MAX_COUNT) { - tm_info = - (nsfw_timer_info *) list_get_first (&g_timer_cfg.exp_timer_head); - if (NULL != tm_info->fun) + dmm_spin_lock(&g_timer_cfg.timer_lock); + tm_info = + (nsfw_timer_info *) list_get_first(&g_timer_cfg.exp_timer_head); + if (NULL == tm_info) + { + dmm_spin_unlock(&g_timer_cfg.timer_lock); + continue; + } + tm_info->alloc_flag = FALSE; + list_del(&tm_info->node); + dmm_spin_unlock(&g_timer_cfg.timer_lock); + /* here can't lock that it is possible that the tm_info->fun call reg timer or remove timer, which will cause deadlock */ + if (NULL != tm_info->fun) + { + (void) tm_info->fun(tm_info->timer_type, tm_info->argv); + } + /* only after finish handle tm_info->fun, it can put it into timer_info_pool, avoid that it is applied by other timer */ + if (0 == nsfw_mem_ring_enqueue(g_timer_cfg.timer_info_pool, tm_info)) { - (void) tm_info->fun (tm_info->timer_type, tm_info->argv); + NSFW_LOGERR("tm_info free failed]tm_info=%p,argv=%p,fun=%p", + tm_info, tm_info->argv, tm_info->fun); } - nsfw_timer_rmv_timer (tm_info); + } } @@ -185,38 +203,32 @@ nsfw_timer_exp (u64 count) * Calls : * Called By : *****************************************************************************/ -i32 -nsfw_get_timer_socket () +i32 nsfw_get_timer_socket() { - i32 tfd = timerfd_create (CLOCK_MONOTONIC, TFD_NONBLOCK); - if (tfd == -1) + + i32 tfd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK); + if (tfd == -1) { - NSFW_LOGERR ("timerfd_create failed!]errno=%d\n", errno); - return -1; + NSFW_LOGERR("timerfd_create failed!]errno=%d\n", errno); + return -1; } - /* close on exe */ - if (-1 == nsfw_set_close_on_exec (tfd)) + /* close on exec */ + if (-1 == nsfw_set_close_on_exec(tfd)) { - (void) nsfw_base_close (tfd); - NSFW_LOGERR ("set exec err]fd=%d, errno=%d", tfd, errno); - return -1; + (void) nsfw_base_close(tfd); + NSFW_LOGERR("set exec err]fd=%d, errno=%d", tfd, errno); + return -1; } - struct itimerspec ts; - ts.it_interval.tv_sec = NSFW_TIMER_CYCLE; - ts.it_interval.tv_nsec = 0; - ts.it_value.tv_sec = 0; - ts.it_value.tv_nsec = NSFW_TIMER_CYCLE; - - if (timerfd_settime (tfd, 0, &ts, NULL) < 0) + if (timerfd_settime(tfd, 0, &g_timer_cfg.ts, NULL) < 0) { - NSFW_LOGERR ("timerfd_settime failed] errno=%d", errno); - close (tfd); - return -1; + NSFW_LOGERR("timerfd_settime failed] errno=%d", errno); + close(tfd); + return -1; } - return tfd; + return tfd; } /***************************************************************************** @@ -230,53 +242,52 @@ nsfw_get_timer_socket () * Calls : * Called By : *****************************************************************************/ -int -nsfw_timer_notify_fun (i32 epfd, i32 fd, u32 events) +int nsfw_timer_notify_fun(i32 epfd, i32 fd, u32 events) { - i32 rc; + i32 rc; - if ((events & EPOLLERR) || (events & EPOLLHUP) || (!(events & EPOLLIN))) + if ((events & EPOLLERR) || (events & EPOLLHUP) || (!(events & EPOLLIN))) { - (void) nsfw_base_close (fd); - NSFW_LOGWAR ("timer disconnect!]epfd=%d,timer=%d,event=0x%x", epfd, - fd, events); + (void) nsfw_base_close(fd); + NSFW_LOGWAR("timer disconnect!]epfd=%d,timer=%d,event=0x%x", epfd, + fd, events); - (void) nsfw_mgr_unreg_sock_fun (fd); - i32 timer_fd = nsfw_get_timer_socket (); - if (timer_fd < 0) + (void) nsfw_mgr_unreg_sock_fun(fd); + i32 timer_fd = nsfw_get_timer_socket(); + if (timer_fd < 0) { - NSFW_LOGERR ("get timer_fd failed!]epfd=%d,timer_fd=%d,event=0x%x", - epfd, fd, events); - return FALSE; + NSFW_LOGERR("get timer_fd faied!]epfd=%d,timer_fd=%d,event=0x%x", + epfd, fd, events); + return FALSE; } - (void) nsfw_mgr_reg_sock_fun (timer_fd, nsfw_timer_notify_fun); - return TRUE; + (void) nsfw_mgr_reg_sock_fun(timer_fd, nsfw_timer_notify_fun); + return TRUE; } - u64 data; - while (1) + u64 data; + while (1) { - rc = nsfw_base_read (fd, &data, sizeof (data)); - if (rc == 0) + rc = nsfw_base_read(fd, &data, sizeof(data)); + if (rc == 0) { - NSFW_LOGERR ("timer_fd recv 0]timer_fd=%d,errno=%d", fd, errno); - break; + NSFW_LOGERR("timer_fd recv 0]timer_fd=%d,errno=%d", fd, errno); + break; } - else if (rc == -1) + else if (rc == -1) { - if (errno == EINTR || errno == EAGAIN) + if (errno == EINTR || errno == EAGAIN) { - break; + break; } - NSMON_LOGERR ("timer_fd recv]timer_fd=%d,errno=%d", fd, errno); - break; + NSMON_LOGERR("timer_fd recv]timer_fd=%d,errno=%d", fd, errno); + break; } - nsfw_timer_exp (data); + nsfw_timer_exp(data); } - return TRUE; + return TRUE; } /***************************************************************************** @@ -287,21 +298,19 @@ nsfw_timer_notify_fun (i32 epfd, i32 fd, u32 events) * Return Value : u8 * Calls : * Called By : -* *****************************************************************************/ -u8 -nsfw_timer_start () +u8 nsfw_timer_start() { - i32 timer_fd = nsfw_get_timer_socket (); - if (timer_fd < 0) + i32 timer_fd = nsfw_get_timer_socket(); + if (timer_fd < 0) { - NSFW_LOGERR ("get timer_fd failed!"); - return FALSE; + NSFW_LOGERR("get timer_fd fail"); + return FALSE; } - NSFW_LOGINF ("start timer_fd module!]timer_fd=%d", timer_fd); - (void) nsfw_mgr_reg_sock_fun (timer_fd, nsfw_timer_notify_fun); - return TRUE; + NSFW_LOGINF("start timer_fd module]timer_fd=%d", timer_fd); + (void) nsfw_mgr_reg_sock_fun(timer_fd, nsfw_timer_notify_fun); + return TRUE; } /***************************************************************************** @@ -312,64 +321,79 @@ nsfw_timer_start () * Return Value : int * Calls : * Called By : -* *****************************************************************************/ -int -nsfw_timer_module_init (void *param) +int nsfw_timer_module_init(void *param) { - u32 proc_type = (u32) ((long long) param); - nsfw_timer_init_cfg *timer_cfg = &g_timer_cfg; - NSFW_LOGINF ("ps module init]type=%u", proc_type); - switch (proc_type) + u32 proc_type = (u32) ((long long) param); + nsfw_timer_init_cfg *timer_cfg = &g_timer_cfg; + if (proc_type != NSFW_PROC_CTRL) { - case NSFW_PROC_MAIN: - (void) NSFW_REG_SOFT_INT (NSFW_DBG_MODE_PARAM, g_hbt_switch, 0, 1); - break; - case NSFW_PROC_TOOLS: - case NSFW_PROC_CTRL: - break; - default: - return 0; + NSFW_LOGINF("ps module init]type=%u", proc_type); } - timer_cfg->timer_info_size = NSFW_TIMER_INFO_MAX_COUNT_DEF; - - nsfw_mem_sppool pmpinfo; - pmpinfo.enmptype = NSFW_MRING_MPMC; - pmpinfo.usnum = timer_cfg->timer_info_size; - pmpinfo.useltsize = sizeof (nsfw_timer_info); - pmpinfo.isocket_id = NSFW_SOCKET_ANY; - pmpinfo.stname.entype = NSFW_NSHMEM; - if (-1 == - SPRINTF_S (pmpinfo.stname.aname, NSFW_MEM_NAME_LENGTH, "%s", - "MS_TM_INFOPOOL")) + /* The first expiration should be the same as the cyclic interval. This fixs the bug of skipping one beat */ + timer_cfg->ts.it_interval.tv_sec = NSFW_TIMER_CYCLE; + timer_cfg->ts.it_interval.tv_nsec = 0; + timer_cfg->ts.it_value.tv_sec = timer_cfg->ts.it_interval.tv_sec; + timer_cfg->ts.it_value.tv_nsec = timer_cfg->ts.it_interval.tv_nsec; + + switch (proc_type) { - NSFW_LOGERR ("SPRINTF_S failed"); - return -1; + case NSFW_PROC_MASTER: + /** For nMaster, we call nsfw_mgr_ep_start() after every other module is inited, + ** so the first expiration is set to 1 nanosecond for nMaster to bring up nMain ASAP */ + timer_cfg->ts.it_value.tv_sec = 0; + timer_cfg->ts.it_value.tv_nsec = 1; + case NSFW_PROC_MAIN: + (void) NSFW_REG_SOFT_INT(NSFW_DBG_MODE_PARAM, g_hbt_switch, 0, 1); + break; + case NSFW_PROC_TOOLS: + case NSFW_PROC_CTRL: + break; + default: + return 0; } - timer_cfg->timer_info_pool = nsfw_mem_sp_create (&pmpinfo); - if (!timer_cfg->timer_info_pool) + timer_cfg->timer_info_size = NSFW_TIMER_INFO_MAX_COUNT_DEF; + + nsfw_mem_sppool pmpinfo; + pmpinfo.enmptype = NSFW_MRING_MPMC; + pmpinfo.usnum = timer_cfg->timer_info_size; + pmpinfo.useltsize = sizeof(nsfw_timer_info); + pmpinfo.isocket_id = NSFW_SOCKET_ANY; + pmpinfo.stname.entype = NSFW_NSHMEM; + if (-1 == + sprintf_s(pmpinfo.stname.aname, NSFW_MEM_NAME_LENTH, "%s", + "MS_TM_INFOPOOL")) { - NSFW_LOGERR ("alloc timer info pool_err"); - return -1; + NSFW_LOGERR("sprintf_s fail"); + return -1; } + timer_cfg->timer_info_pool = nsfw_mem_sp_create(&pmpinfo); + + if (!timer_cfg->timer_info_pool) + { + NSFW_LOGERR("alloc timer info pool_err"); + return -1; + } + + MEM_STAT(NSFW_TIMER_MODULE, pmpinfo.stname.aname, NSFW_NSHMEM, + nsfw_mem_get_len(timer_cfg->timer_info_pool, NSFW_MEM_SPOOL)); - MEM_STAT (NSFW_TIMER_MODULE, pmpinfo.stname.aname, NSFW_NSHMEM, - nsfw_mem_get_len (timer_cfg->timer_info_pool, NSFW_MEM_SPOOL)); + INIT_LIST_HEAD(&(timer_cfg->timer_head)); + INIT_LIST_HEAD(&(timer_cfg->exp_timer_head)); - INIT_LIST_HEAD (&(timer_cfg->timer_head)); - INIT_LIST_HEAD (&(timer_cfg->exp_timer_head)); + dmm_spin_init(&g_timer_cfg.timer_lock); + (void) nsfw_timer_start(); - (void) nsfw_timer_start (); - return 0; + return 0; } /* *INDENT-OFF* */ -NSFW_MODULE_NAME (NSFW_TIMER_MODULE) -NSFW_MODULE_PRIORITY (10) -NSFW_MODULE_DEPENDS (NSFW_MGR_COM_MODULE) -NSFW_MODULE_INIT (nsfw_timer_module_init) +NSFW_MODULE_NAME(NSFW_TIMER_MODULE) +NSFW_MODULE_PRIORITY(10) +NSFW_MODULE_DEPENDS(NSFW_MGR_COM_MODULE) +NSFW_MODULE_INIT(nsfw_timer_module_init) /* *INDENT-ON* */ #ifdef __cplusplus |