diff options
author | qchang <qing.chang1@huawei.com> | 2018-03-08 17:39:22 -0800 |
---|---|---|
committer | qchang <qing.chang1@huawei.com> | 2018-03-08 17:39:22 -0800 |
commit | 697ade6190b23c80e7f60963983786e679759393 (patch) | |
tree | dd9782d1e936b8342163b26795e23571d4b1b415 /src/framework/ipc/ps/nsfw_recycle_module.c | |
parent | 71a4e2f34afa8018426f0e830050e50a1de6d375 (diff) |
dmm initial commit
Change-Id: I049ee277cf4efdb83f9c2ac439365fcd421c159b
Signed-off-by: qchang <qing.chang1@huawei.com>
Diffstat (limited to 'src/framework/ipc/ps/nsfw_recycle_module.c')
-rw-r--r-- | src/framework/ipc/ps/nsfw_recycle_module.c | 666 |
1 files changed, 666 insertions, 0 deletions
diff --git a/src/framework/ipc/ps/nsfw_recycle_module.c b/src/framework/ipc/ps/nsfw_recycle_module.c new file mode 100644 index 0000000..bb3844f --- /dev/null +++ b/src/framework/ipc/ps/nsfw_recycle_module.c @@ -0,0 +1,666 @@ +/* +* +* Copyright (c) 2018 Huawei Technologies Co.,Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at: +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include <stdlib.h> +#include "types.h" +#include "nstack_securec.h" +#include "nsfw_init.h" + +#include "nsfw_mgr_com_api.h" +#include "nsfw_mem_api.h" +#include "nsfw_ps_api.h" +#include "nsfw_ps_mem_api.h" +#include "nsfw_fd_timer_api.h" +#include "nsfw_recycle_module.h" +#include "nsfw_maintain_api.h" +#include "nstack_log.h" +#include "common_mem_api.h" + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C"{ +/* *INDENT-ON* */ +#endif /* __cplusplus */ + +/* only work on nStackMain*/ +nsfw_recycle_cfg g_rec_cfg; + +nsfw_recycle_fun g_rec_fun[NSFW_REC_TYPE_MAX] = { 0 }; + +nsfw_rec_fun_info g_rec_lock_fun[NSFW_REC_LOCK_REL_MAX_FUN]; + +/***************************************************************************** +* Prototype : nsfw_recycle_reg_fun +* Description : reg one recycle type recycle funciton +* Input : u16 rec_type +* nsfw_recycle_fun fun +* Output : None +* Return Value : u8 +* Calls : +* Called By : +*****************************************************************************/ +u8 +nsfw_recycle_reg_fun (u16 rec_type, nsfw_recycle_fun fun) +{ + if (NULL == fun || rec_type >= NSFW_REC_TYPE_MAX) + { + NSFW_LOGERR ("argv err]fun=%p,type=%u", fun, rec_type); + return FALSE; + } + + g_rec_fun[rec_type] = fun; + NSFW_LOGINF ("reg]fun=%d,type=%u", fun, rec_type); + return TRUE; +} + +/***************************************************************************** +* Prototype : nsfw_recycle_lock_rel_fun +* Description : reg lock release when app exit run +* Input : nsfw_recycle_fun fun +* void* data +* u8 proc_type: NULL as all +* Output : None +* Return Value : u8 +* Calls : +* Called By : +*****************************************************************************/ +u8 +nsfw_recycle_lock_rel_fun (nsfw_recycle_fun fun, void *data, u8 proc_type) +{ + if (NULL == fun) + { + NSFW_LOGERR ("argv err]fun=%p,data=%p", fun, data); + return FALSE; + } + + u32 i; + + for (i = 0; i < NSFW_REC_LOCK_REL_MAX_FUN; i++) + { + if (NULL == g_rec_lock_fun[i].rec_fun) + { + g_rec_lock_fun[i].rec_fun = fun; + g_rec_lock_fun[i].data = data; + g_rec_lock_fun[i].proc_type = proc_type; + NSFW_LOGINF ("reg mgr_msg fun suc]fun=%p,data=%p", fun, data); + return TRUE; + } + } + + NSFW_LOGINF ("reg]fun=%p,data=%p", fun, data); + return TRUE; +} + +/***************************************************************************** +* Prototype : nsfw_recycle_exit_pid_lock +* Description : release all lock fun +* Input : u32 pid +* Output : None +* Return Value : u8 +* Calls : +* Called By : +*****************************************************************************/ +int +nsfw_recycle_exit_pid_lock (u32 pid, u8 proc_type, void *argv) +{ + u32 i; + NSFW_LOGINF ("release lock]pid=%d,type=%d", pid, proc_type); + for (i = 0; i < NSFW_REC_LOCK_REL_MAX_FUN; i++) + { + if (NULL == g_rec_lock_fun[i].rec_fun) + { + break; + } + + if ((NSFW_PROC_NULL == g_rec_lock_fun[i].proc_type) + || (proc_type == g_rec_lock_fun[i].proc_type)) + { + (void) g_rec_lock_fun[i].rec_fun (pid, g_rec_lock_fun[i].data, 0); + } + } + + return 0; +} + +/***************************************************************************** +* Prototype : nsfw_recycle_obj_end +* Description : one recycle object process finished notify +* Input : u32 pid +* Output : None +* Return Value : u8 +* Calls : +* Called By : +*****************************************************************************/ +u8 +nsfw_recycle_obj_end (u32 pid) +{ + nsfw_mgr_msg *rsp_msg = + nsfw_mgr_msg_alloc (MGR_MSG_RCC_END_REQ, NSFW_PROC_MAIN); + if (NULL == rsp_msg) + { + NSFW_LOGERR ("alloc rsp msg failed]pid=%u", pid); + return FALSE; + } + + nsfw_ps_info_msg *ps_msg = GET_USER_MSG (nsfw_ps_info_msg, rsp_msg); + ps_msg->host_pid = pid; + (void) nsfw_mgr_send_msg (rsp_msg); + nsfw_mgr_msg_free (rsp_msg); + NSFW_LOGINF ("send obj end msg]pid=%d", pid); + return TRUE; +} + +/***************************************************************************** +* Prototype : nsfw_recycle_callback_all_obj +* Description : process all recycle object +* Input : u32 pid +* nsfw_recycle_pool *rec_pool +* Output : None +* Return Value : nsfw_rcc_stat +* Calls : +* Called By : +*****************************************************************************/ +nsfw_rcc_stat +nsfw_recycle_callback_all_obj (u32 pid, nsfw_recycle_pool * rec_pool) +{ + u32 match = 0; + nsfw_recycle_obj *obj = NULL; + if (NULL == rec_pool) + { + return NSFW_RCC_CONTINUE; + } + + nsfw_recycle_obj *p_start = rec_pool->obj; + u32 i; + u32 size = rec_pool->pool_size; + + nsfw_ps_info *pps_info; + pps_info = nsfw_ps_info_get (pid); + if (NULL == pps_info) + { + NSFW_LOGERR ("get ps_info falied!]pid=%d", pid); + return NSFW_RCC_CONTINUE; + } + + i32 cur_idx = (i32) (u64) nsfw_ps_get_uv (pps_info, NSFW_REC_IDX); + + if (-1 == cur_idx) + { + cur_idx = 0; + nsfw_ps_set_uv (pps_info, NSFW_REC_IDX, (void *) (u64) cur_idx); + (void) nsfw_recycle_exit_pid_lock (pid, NSFW_PROC_APP, NULL); + } + else + { + cur_idx++; + nsfw_ps_set_uv (pps_info, NSFW_REC_IDX, (void *) (u64) cur_idx); + } + + for (i = cur_idx; i < size; i++) + { + obj = &p_start[i]; + cur_idx = i; + nsfw_ps_set_uv (pps_info, NSFW_REC_IDX, (void *) (u64) cur_idx); + if (FALSE == obj->alloc_flag) + { + continue; + } + + if ((obj->rec_type < NSFW_REC_TYPE_MAX) + && (NULL != g_rec_fun[obj->rec_type])) + { + match++; + if (NSFW_RCC_SUSPEND == + g_rec_fun[obj->rec_type] (pid, obj->data, obj->rec_type)) + { + NSFW_LOGINF + ("call suspend]type=%d,obj_pid=%d,pid=%d,count=%d", + obj->rec_type, obj->host_pid, pid, match); + return NSFW_RCC_SUSPEND; + } + } + else + { + NSFW_LOGERR ("obj_error!drop]type=%d,obj_pid=%d,pid=%d", + obj->rec_type, obj->host_pid, pid); + } + } + + NSFW_LOGWAR ("rec obj]pid=%d,count=%d,cur_idx=%d", pid, match, cur_idx); + return NSFW_RCC_CONTINUE; +} + +/***************************************************************************** +* Prototype : nsfw_recycle_pid_obj +* Description : recycle object with pid +* Input : u32 pid +* Output : None +* Return Value : u8 +* Calls : +* Called By : +*****************************************************************************/ +u8 +nsfw_recycle_pid_obj (u32 pid) +{ + nsfw_ps_info *pps_info; + pps_info = nsfw_ps_info_get (pid); + if (NULL == pps_info) + { + NSFW_LOGERR ("get ps_info falied!]pid=%d", pid); + return FALSE; + } + + nsfw_recycle_pool *rec_pool = g_rec_cfg.mem_rec_obj_pool; + void *timer_ptr = nsfw_ps_get_uv (pps_info, NSFW_REC_TIMER); + if (NSFW_RCC_SUSPEND == nsfw_recycle_callback_all_obj (pid, rec_pool)) + { + if (NULL != timer_ptr) + { + nsfw_timer_rmv_timer (timer_ptr); + timer_ptr = NULL; + } + + struct timespec time_left = { NSFW_REC_WEND_TVLAUE, 0 }; + timer_ptr = + (void *) nsfw_timer_reg_timer (NSFW_REC_WEND_TIMER, + (void *) (u64) pid, + nsfw_recycle_obj_timeout, time_left); + nsfw_ps_set_uv (pps_info, NSFW_REC_TIMER, timer_ptr); + return TRUE; + } + + if (NULL != timer_ptr) + { + nsfw_timer_rmv_timer (timer_ptr); + nsfw_ps_set_uv (pps_info, NSFW_REC_TIMER, NULL); + } + + (void) nsfw_ps_exit_end_notify (pid); + nsfw_ps_info_free (pps_info); + return TRUE; +} + +/***************************************************************************** +* Prototype : nsfw_recycle_all_obj +* Description : +* Input : u32 pid +* nsfw_mem_addr_msg *addr_msg +* Output : None +* Return Value : u8 +* Calls : +* Called By : +*****************************************************************************/ +u8 +nsfw_recycle_all_obj (u32 pid) +{ + nsfw_ps_info *pps_info; + pps_info = nsfw_ps_info_get (pid); + if (NULL == pps_info) + { + pps_info = nsfw_ps_info_alloc (pid, NSFW_PROC_APP); + if (NULL == pps_info) + { + NSFW_LOGERR ("alloc ps_info falied!]pid=%u", pid); + return FALSE; + } + } + + nsfw_ps_set_uv (pps_info, NSFW_REC_IDX, (void *) (-1)); + nsfw_ps_set_uv (pps_info, NSFW_REC_TIMER, NULL); + return nsfw_recycle_pid_obj (pid); +} + +/***************************************************************************** +* Prototype : mem_app_exit_proc +* Description : exiting message process +* Input : nsfw_mgr_msg* msg +* Output : None +* Return Value : int +* Calls : +* Called By : +*****************************************************************************/ +int +mem_app_exit_proc (nsfw_mgr_msg * msg) +{ + if (NULL == msg) + { + NSFW_LOGERR ("msg nul"); + return FALSE; + } + + nsfw_ps_info_msg *ps_info_msg = GET_USER_MSG (nsfw_ps_info_msg, msg); + + /* look up the app rec memzone and release all resource */ + /* no need to send rsp for it will be send after stack process over */ + if (TRUE == nsfw_recycle_all_obj (ps_info_msg->host_pid)) + { + NSFW_LOGINF ("obj found!]pid=%d", ps_info_msg->host_pid); + return TRUE; + } + + (void) nsfw_ps_exit_end_notify (ps_info_msg->host_pid); + return FALSE; +} + +/***************************************************************************** +* Prototype : nsfw_recycle_obj_end_proc +* Description : obj recycle finished notify process +* Input : nsfw_mgr_msg* msg +* Output : None +* Return Value : int +* Calls : +* Called By : +*****************************************************************************/ +int +nsfw_recycle_obj_end_proc (nsfw_mgr_msg * msg) +{ + if (NULL == msg) + { + NSFW_LOGERR ("msg nul"); + return FALSE; + } + + nsfw_ps_info_msg *ps_info_msg = GET_USER_MSG (nsfw_ps_info_msg, msg); + + return nsfw_recycle_pid_obj (ps_info_msg->host_pid); +} + +/***************************************************************************** +* Prototype : nsfw_recycle_obj_timeout +* Description : recycle object timeout process +* Input : u32 timer_type +* void* data +* Output : None +* Return Value : int +* Calls : +* Called By : +*****************************************************************************/ +int +nsfw_recycle_obj_timeout (u32 timer_type, void *data) +{ + u32 pid = (u64) data; + void *timer_ptr = NULL; + NSFW_LOGINF ("ps_info timerout]pid=%u", pid); + + nsfw_ps_info *pps_info; + pps_info = nsfw_ps_info_get (pid); + if (NULL != pps_info) + { + nsfw_recycle_pool *rec_pool = g_rec_cfg.mem_rec_obj_pool; + if (NULL != rec_pool) + { + if (TRUE == g_hbt_switch) + { + struct timespec time_left = { NSFW_REC_WEND_TVLAUE, 0 }; + timer_ptr = + (void *) nsfw_timer_reg_timer (timer_type, data, + nsfw_recycle_obj_timeout, + time_left); + nsfw_ps_set_uv (pps_info, NSFW_REC_TIMER, timer_ptr); + return TRUE; + } + } + nsfw_ps_set_uv (pps_info, NSFW_REC_TIMER, timer_ptr); + } + + (void) nsfw_recycle_pid_obj (pid); + return TRUE; +} + +/***************************************************************************** +* Prototype : mem_rec_zone_init +* Description : init recycle zone in app, only work on App +* Input : None +* Output : None +* Return Value : u8 +* Calls : +* Called By : +*****************************************************************************/ +u8 +mem_rec_zone_init () +{ + nsfw_mem_mring pringinfo; + pringinfo.enmptype = NSFW_MRING_MPMC; + pringinfo.isocket_id = NSFW_SOCKET_ANY; + pringinfo.stname.entype = NSFW_NSHMEM; + pringinfo.usnum = MEM_RECYCLE_PER_PRO_QUE; + u32 i; + for (i = 0; i < NSFW_REC_PRO_MAX; i++) + { + if (-1 == + SPRINTF_S (pringinfo.stname.aname, NSFW_MEM_NAME_LENTH, "%s%d", + MEM_REC_QUEUE_NAME, i)) + { + NSFW_LOGERR ("SPRINTF_S failed]"); + return FALSE; + } + g_rec_cfg.mem_rec_pro[i] = nsfw_mem_ring_create (&pringinfo); + if (NULL == g_rec_cfg.mem_rec_pro[i]) + { + NSFW_LOGERR ("alloc rec ring nul!"); + return FALSE; + } + } + + MEM_STAT (NSFW_RECYCLE_MODULE, MEM_REC_QUEUE_NAME, NSFW_NSHMEM, + NSFW_REC_PRO_MAX * nsfw_mem_get_len (g_rec_cfg.mem_rec_pro[0], + NSFW_MEM_RING)); + + nsfw_mem_zone pzoneinfo; + pzoneinfo.isocket_id = NSFW_SOCKET_ANY; + pzoneinfo.stname.entype = NSFW_NSHMEM; + pzoneinfo.lenth = + MEM_RECYCLE_OBJ_MAX_NUM * sizeof (nsfw_recycle_obj) + + sizeof (nsfw_recycle_pool); + if (-1 == + SPRINTF_S (pzoneinfo.stname.aname, NSFW_MEM_NAME_LENTH, "%s", + MEM_REC_POOL_NAME)) + { + NSFW_LOGERR ("SPRINTF_S failed]"); + return FALSE; + } + + g_rec_cfg.mem_rec_obj_pool = nsfw_mem_zone_create (&pzoneinfo); + if (NULL == g_rec_cfg.mem_rec_obj_pool) + { + NSFW_LOGERR ("alloc rec pool nul!"); + return FALSE; + } + + MEM_STAT (NSFW_RECYCLE_MODULE, MEM_REC_POOL_NAME, NSFW_NSHMEM, + pzoneinfo.lenth); + + int retval; + retval = + MEMSET_S (g_rec_cfg.mem_rec_obj_pool, pzoneinfo.lenth, 0, + pzoneinfo.lenth); + if (EOK != retval) + { + NSFW_LOGERR ("mem set init failed!"); + return FALSE; + } + + i32 j; + nsfw_recycle_pool *rec_pool = + (nsfw_recycle_pool *) g_rec_cfg.mem_rec_obj_pool; + rec_pool->pool_size = MEM_RECYCLE_OBJ_MAX_NUM; + + nsfw_recycle_obj *p_start = rec_pool->obj; + for (i = 0; i < NSFW_REC_PRO_MAX; i++) + { + for (j = 0; j < MEM_RECYCLE_PER_PRO_QUE; j++) + { + if (FALSE == p_start[j].alloc_flag) + { + if (0 == + nsfw_mem_ring_enqueue (g_rec_cfg.mem_rec_pro[i], + &p_start[j])) + { + NSFW_LOGERR ("enqueue failed"); + break; + } + } + } + p_start = p_start + MEM_RECYCLE_PER_PRO_QUE; + } + + NSFW_LOGINF ("init rec pool and ring suc!"); + return TRUE; +} + +/***************************************************************************** +* Prototype : nsfw_recycle_reg_obj +* Description : reg one recycle object +* Input : u8 priority +* u16 rec_type +* void* data +* Output : None +* Return Value : void * +* Calls : +* Called By : +*****************************************************************************/ +void * +nsfw_recycle_reg_obj (u8 priority, u16 rec_type, void *data) +{ + if (NSFW_REC_PRO_MAX <= priority) + { + NSFW_LOGERR ("pro error]priority=%d,rec_type=%d,data=%p", priority, + rec_type, data); + return NULL; + } + + nsfw_recycle_obj *obj = NULL; + if (0 == + nsfw_mem_ring_dequeue (g_rec_cfg.mem_rec_pro[priority], (void *) &obj)) + { + NSFW_LOGERR ("dequeue error]priority=%d,rec_type=%d,data=%p", + priority, rec_type, data); + return NULL; + } + + if (EOK != MEMSET_S (obj, sizeof (*obj), 0, sizeof (*obj))) + { + if (0 == nsfw_mem_ring_enqueue (g_rec_cfg.mem_rec_pro[priority], obj)) + { + NSFW_LOGERR ("enqueue error]priority=%d,rec_type=%d,data=%p", + priority, rec_type, data); + } + + NSFW_LOGERR ("mem set error]priority=%d,rec_type=%d,data=%p", + priority, rec_type, data); + return NULL; + } + + obj->alloc_flag = TRUE; + obj->rec_type = rec_type; + obj->data = data; + obj->host_pid = get_sys_pid (); + obj->alloc_flag = TRUE; + NSFW_LOGINF ("en queue obj]priority=%d,rec_type=%d,data=%p", priority, + rec_type, data); + return obj; +} + +/***************************************************************************** +* Prototype : nsfw_recycle_rechk_lock +* Description : add for rechk lock +* Input : None +* Output : None +* Return Value : int +* Calls : +* Called By : +*****************************************************************************/ +int +nsfw_recycle_rechk_lock () +{ + return nsfw_ps_rechk_pid_exit (nsfw_recycle_exit_pid_lock, NULL); +} + +/***************************************************************************** +* Prototype : nsfw_recycle_module_init +* Description : module init +* Input : void* param +* Output : None +* Return Value : static int +* Calls : +* Called By : +*****************************************************************************/ +NSTACK_STATIC int nsfw_recycle_module_init (void *param); +NSTACK_STATIC int +nsfw_recycle_module_init (void *param) +{ + u32 proc_type = (u32) ((long long) param); + NSFW_LOGINF ("recycle module init]type=%d", proc_type); + g_rec_cfg.rec_waite_end_tvalue = NSFW_REC_WEND_TVLAUE_DEF; + switch (proc_type) + { + case NSFW_PROC_MASTER: + return 0; + case NSFW_PROC_MAIN: + (void) nsfw_mgr_reg_msg_fun (MGR_MSG_APP_EXIT_REQ, mem_app_exit_proc); + (void) nsfw_mgr_reg_msg_fun (MGR_MSG_RCC_END_REQ, + nsfw_recycle_obj_end_proc); + if (TRUE == mem_rec_zone_init ()) + { + return 0; + } + + return 0; + default: + if (proc_type < NSFW_PROC_MAX) + { + break; + } + return -1; + } + + return 0; +} + +/***************************************************************************** +* Prototype : nsfw_recycle_fork_init +* Description : fork init +* Input : None +* Output : None +* Return Value : u8 +* Calls : +* Called By : +*****************************************************************************/ +u8 +nsfw_recycle_fork_init () +{ + /* reconnect to master after fork in child proc */ + nsfw_mgr_close_dst_proc (NSFW_PROC_MAIN, 0); + nsfw_mgr_close_dst_proc (NSFW_PROC_MASTER, 0); + if (0 == nsfw_recycle_module_init ((void *) ((long long) NSFW_PROC_APP))) + { + return TRUE; + } + return FALSE; +} + +/* *INDENT-OFF* */ +NSFW_MODULE_NAME (NSFW_RECYCLE_MODULE) +NSFW_MODULE_PRIORITY (10) +NSFW_MODULE_DEPENDS (NSFW_PS_MEM_MODULE) +NSFW_MODULE_INIT (nsfw_recycle_module_init) +/* *INDENT-ON* */ + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif /* __cplusplus */ |