/* * Copyright (c) Hisilicon Technologies Co., Ltd. 2012-2019. All rights reserved. * Description: drv_rm * Author: sdk_video * Create: 2012-11-25 */ #include "drv_rm.h" #include "osal_ext.h" #include "soc_errno.h" #include "drv_rm_ext.h" #include "drv_win_ext.h" #include "drv_rm_define.h" #include "drv_rm_proc.h" #include "drv_rm_comm.h" static rm_drv_golbal_ctx g_st_rm_drv_golbal_ctx; static rm_drv_path_ctx g_st_rm_drv_path_ctx[RM_DRV_CHN_MAX_NUM + 1]; static td_u32 g_u32_reserve; osal_semaphore g_rm_drv_mutex; /* 初始化上下文 */ static td_void rm_drv_comm_de_init_path_ctx(td_u32 rm_path_id) { osal_wait_destroy(&g_st_rm_drv_path_ctx[rm_path_id].wait_queue); return; } static td_void rm_drv_comm_de_init_golbal_ctx(td_void) { osal_wait_destroy(&g_st_rm_drv_golbal_ctx.wait_queue); return; } static td_void rm_drv_comm_init_path_ctx(td_u32 rm_path_id) { errno_t err; err = memset_s(&g_st_rm_drv_path_ctx[rm_path_id], sizeof(g_st_rm_drv_path_ctx), 0, sizeof(rm_drv_path_ctx)); if (err != EOK) { soc_log_err("rm_drv_comm_init_path_ctx memset_s fail!\n"); return; } g_st_rm_drv_path_ctx[rm_path_id].rm_handle = TD_INVALID_HANDLE; osal_wait_init(&g_st_rm_drv_path_ctx[rm_path_id].wait_queue); return; } static td_void rm_drv_comm_init_golbal_ctx(td_void) { td_s32 i; memset_s(&g_st_rm_drv_golbal_ctx, sizeof(g_st_rm_drv_golbal_ctx), 0, sizeof(rm_drv_golbal_ctx)); g_st_rm_drv_golbal_ctx.wake_up_cnt = 0; g_st_rm_drv_golbal_ctx.path_recycle_cnt = 0; g_st_rm_drv_golbal_ctx.normal_cnt = 0; g_st_rm_drv_golbal_ctx.rm_path_count = 0; g_st_rm_drv_golbal_ctx.rm_available_win_count = RM_DRV_WIN_MAX_COUNT; g_st_rm_drv_golbal_ctx.wake_up_flags = TD_FALSE; g_st_rm_drv_golbal_ctx.waiting_event = TD_FALSE; g_st_rm_drv_golbal_ctx.wind_owner = EXT_DRV_WIN_OWNER_BUTT; g_st_rm_drv_golbal_ctx.win_owner_id = 0; for (i = 0; i < RM_DRV_CHN_MAX_NUM; i++) { g_st_rm_drv_golbal_ctx.chn_create_cnt[i] = 0; g_st_rm_drv_golbal_ctx.chn_destroy_cnt[i] = 0; } g_u32_reserve = 0; osal_wait_init(&g_st_rm_drv_golbal_ctx.wait_queue); return; } /* 获取上下文 */ td_void rm_drv_comm_get_path_ctx(td_u32 rm_path_id, rm_drv_path_ctx **rm_drv_path_ctx_p) { if (rm_drv_path_ctx_p == TD_NULL) { soc_log_err("rm_drv_path_ctx_p is null!\n"); return; } *rm_drv_path_ctx_p = &g_st_rm_drv_path_ctx[rm_path_id]; return; } /* 获取上下文 */ td_void rm_drv_comm_get_golbal_ctx(rm_drv_golbal_ctx **rm_drv_golbal_ctx_p) { if (rm_drv_golbal_ctx_p == TD_NULL) { soc_log_err("rm_drv_golbal_ctx_p is null!\n"); return; } *rm_drv_golbal_ctx_p = &g_st_rm_drv_golbal_ctx; return; } /* get current time */ td_void rm_drv_comm_get_cur_time(td_u32 *cur_time_us_p) { osal_timeval time; osal_gettimeofday(&time); if (cur_time_us_p == TD_NULL) { soc_log_err("cur_time_us_p is null!\n"); return; } if ((time.tv_sec * 1000000ULL + time.tv_usec) < 0xffffffff) { *cur_time_us_p = time.tv_sec * 1000000 + time.tv_usec; /* 1000000 uesed convert second to microsecond */ } else { *cur_time_us_p = 0; } return; } static td_s32 rm_drv_ctrl_put_win_event_to_list(ext_drv_rm_win_event win_event) { td_s32 ret; td_s32 result = TD_SUCCESS; td_u32 rm_path_id; rm_drv_path_ctx *rm_drv_path_ctx_p = TD_NULL; ext_drv_rm_event rm_event; for (rm_path_id = 0; rm_path_id < RM_DRV_CHN_MAX_NUM; rm_path_id++) { rm_drv_comm_get_path_ctx(rm_path_id, &rm_drv_path_ctx_p); if (rm_drv_path_ctx_p->rm_handle != TD_INVALID_HANDLE) { rm_event.win_event = win_event; ret = rm_drv_comm_put_event(rm_drv_path_ctx_p->rm_handle, rm_drv_path_ctx_p->event_handle_p, &rm_event); if (ret != TD_SUCCESS) { soc_log_dbg("put event in list failed!\n"); soc_dbg_print_u32(win_event); soc_dbg_print_u32(rm_path_id); result = TD_FAILURE; } rm_drv_path_ctx_p->list_empty = TD_FALSE; } } return result; } /* 获取空闲RM path id */ static td_s32 rm_drv_ctrl_get_free_path_id(td_u32 *rm_path_id_p) { td_u32 rm_path_id; rm_drv_path_ctx *rm_path_ctx_p = TD_NULL; for (rm_path_id = 0; rm_path_id < RM_DRV_CHN_MAX_NUM; rm_path_id++) { rm_path_ctx_p = &g_st_rm_drv_path_ctx[rm_path_id]; if (rm_path_ctx_p->rm_handle == TD_INVALID_HANDLE) { *rm_path_id_p = rm_path_id; return TD_SUCCESS; } } return SOC_ERR_RM_NOT_FREE_INST; } static td_s32 rm_drv_ctrl_wake_up_waiting_event(td_void) { rm_drv_golbal_ctx *rm_drv_golbal_ctx_p = TD_NULL; rm_drv_comm_get_golbal_ctx(&rm_drv_golbal_ctx_p); check_rm_null_ptr(rm_drv_golbal_ctx_p); rm_drv_golbal_ctx_p->wake_up_flags = TD_TRUE; osal_wait_wakeup(&rm_drv_golbal_ctx_p->wait_queue); return TD_SUCCESS; } static td_s32 rm_drv_ctrl_disable(td_handle rm_handle) { td_u32 rm_path_id = 0; rm_drv_path_ctx *rm_drv_path_ctx_p = TD_NULL; if (rm_handle == TD_INVALID_HANDLE) { soc_log_err("rm handle is invalid.\n"); return SOC_ERR_RM_INVALID_HANDLE; } if (((rm_path_id) = (rm_handle) & 0xff) >= RM_DRV_CHN_MAX_NUM) { soc_log_err("rm path id is over range.rm_id = 0x%08X\n", rm_path_id); return SOC_ERR_RM_INST_OVER_RANGE; } rm_drv_comm_get_path_ctx(rm_path_id, &rm_drv_path_ctx_p); check_rm_null_ptr(rm_drv_path_ctx_p); if (rm_handle != rm_drv_path_ctx_p->rm_handle) { soc_log_err("src_rm_handle is not equal dest_rm_handle.\n"); soc_err_print_h32(rm_handle); soc_err_print_h32(rm_drv_path_ctx_p->rm_handle); return SOC_ERR_RM_INVALID_HANDLE; } if (rm_drv_path_ctx_p->chn_enable != TD_FALSE) { rm_drv_path_ctx_p->chn_enable = TD_FALSE; } else { soc_log_err("path is already disable!\n"); soc_err_print_u32(rm_path_id); return SOC_ERR_RM_DISABLE_ERR; } return TD_SUCCESS; } static td_s32 rm_drv_ctrl_destroy(td_handle rm_handle) { td_s32 ret; td_u32 rm_path_id = 0; rm_drv_path_ctx *rm_drv_path_ctx_p = TD_NULL; rm_drv_golbal_ctx *rm_drv_golbal_ctx_p = TD_NULL; td_handle tmp_rm_handle; if (rm_handle == TD_INVALID_HANDLE) { soc_log_err("rm handle is invalid.\n"); return SOC_ERR_RM_INVALID_HANDLE; } if (((rm_path_id) = (rm_handle) & 0xff) >= RM_DRV_CHN_MAX_NUM) { soc_log_err("rm path id is over range.rm_id = 0x%08X\n", rm_path_id); return SOC_ERR_RM_INST_OVER_RANGE; } rm_drv_comm_get_path_ctx(rm_path_id, &rm_drv_path_ctx_p); check_rm_null_ptr(rm_drv_path_ctx_p); if (rm_handle != rm_drv_path_ctx_p->rm_handle) { soc_log_err("src_rm_handle is not equal dest_rm_handle.\n"); soc_err_print_h32(rm_handle); soc_err_print_h32(rm_drv_path_ctx_p->rm_handle); return SOC_ERR_RM_INVALID_HANDLE; } tmp_rm_handle = rm_drv_path_ctx_p->rm_handle; rm_drv_path_ctx_p->rm_handle = TD_INVALID_HANDLE; ret = rm_drv_comm_de_init_event_list(rm_drv_path_ctx_p->event_handle_p); if (ret != TD_SUCCESS) { soc_log_err("de_init event list failed.\n"); rm_drv_path_ctx_p->rm_handle = tmp_rm_handle; return SOC_ERR_RM_DESTROY_ERR; } rm_drv_path_ctx_p->chn_enable = TD_FALSE; rm_drv_path_ctx_p->event_handle_p = TD_NULL; rm_drv_path_ctx_p->queue_cnt = 1; rm_drv_path_ctx_p->try_queue_cnt = 0; rm_drv_path_ctx_p->cur_pid = 0; rm_drv_comm_get_golbal_ctx(&rm_drv_golbal_ctx_p); check_rm_null_ptr(rm_drv_golbal_ctx_p); rm_drv_golbal_ctx_p->rm_path_count--; rm_drv_golbal_ctx_p->chn_destroy_cnt[rm_path_id]++; return TD_SUCCESS; } /* avoid service crash cause path resource leak */ static td_void rm_drv_ctrl_recycle_path_resource(td_void) { td_s32 ret1; td_s32 ret2; td_u32 rm_path_id; td_u32 available_rm_path; rm_drv_path_ctx *rm_drv_path_ctx_p = TD_NULL; rm_drv_golbal_ctx *rm_drv_golbal_ctx_p = TD_NULL; rm_drv_comm_get_golbal_ctx(&rm_drv_golbal_ctx_p); if (rm_drv_golbal_ctx_p == TD_NULL) { soc_log_err("rm_drv_golbal_ctx_p is null ptr.\n"); return; } available_rm_path = RM_DRV_CHN_MAX_NUM - rm_drv_golbal_ctx_p->rm_path_count; if (available_rm_path > 1) { return; } soc_log_err("available rm path less than two!\n"); for (rm_path_id = 0; rm_path_id < RM_DRV_CHN_MAX_NUM; rm_path_id++) { rm_drv_comm_get_path_ctx(rm_path_id, &rm_drv_path_ctx_p); if (rm_drv_path_ctx_p->rm_handle == TD_INVALID_HANDLE) { continue; } if (rm_drv_path_ctx_p->used_node == RM_DRV_LIST_NODE_NUM && rm_drv_path_ctx_p->free_node == 0) { soc_log_err("path resource leak! recycle it \n"); soc_err_print_u32(rm_path_id); soc_err_print_u32(rm_drv_path_ctx_p->cur_pid); ret1 = rm_drv_ctrl_disable(rm_drv_path_ctx_p->rm_handle); ret2 = rm_drv_ctrl_destroy(rm_drv_path_ctx_p->rm_handle); if (ret1 != TD_SUCCESS || ret2 != TD_SUCCESS) { soc_log_err("path resource leak! recycle failed\n"); soc_err_print_u32(rm_path_id); } else { rm_drv_path_ctx_p->rm_handle = TD_INVALID_HANDLE; rm_drv_path_ctx_p->event_handle_p = TD_NULL; rm_drv_path_ctx_p->chn_enable = TD_FALSE; /* default colse the channel */ rm_drv_path_ctx_p->queue_cnt = 1; rm_drv_path_ctx_p->try_queue_cnt = 0; rm_drv_path_ctx_p->free_node = RM_DRV_LIST_NODE_NUM; rm_drv_path_ctx_p->used_node = 0; rm_drv_path_ctx_p->cur_index = 0; rm_drv_path_ctx_p->cur_pid = 0; rm_drv_golbal_ctx_p->path_recycle_cnt++; soc_log_dbg("path resource leak! recycle succeed!\n"); soc_dbg_print_u32(rm_path_id); } } } return; } /* check path is idle */ static td_void rm_drv_ctrl_check_idle_path(td_void) { td_u32 rm_path_id; td_u32 cur_sys_time = 0; td_u32 time_diff; rm_drv_path_ctx *rm_drv_path_ctx_p = TD_NULL; rm_drv_comm_get_cur_time(&cur_sys_time); for (rm_path_id = 0; rm_path_id < RM_DRV_CHN_MAX_NUM; rm_path_id++) { rm_drv_comm_get_path_ctx(rm_path_id, &rm_drv_path_ctx_p); if (rm_drv_path_ctx_p->rm_handle != TD_INVALID_HANDLE) { time_diff = cur_sys_time - rm_drv_path_ctx_p->lst_query_time; rm_drv_path_ctx_p->cur_query_time = cur_sys_time; if (rm_drv_path_ctx_p->idle == TD_TRUE) { continue; } if (time_diff > RM_DRV_IDLE_MAX_TIME_US && rm_drv_path_ctx_p->used_node >= RM_DRV_IDLE_MAX_USED_NODE) { rm_drv_path_ctx_p->idle = TD_TRUE; soc_warn_print_u32(rm_drv_path_ctx_p->cur_pid); soc_warn_print_bool(rm_drv_path_ctx_p->idle); } } } return; } /* avoid service crash cause path resource leak */ static td_void rm_drv_ctrl_recycle_idle_path(td_void) { td_s32 ret; td_u32 rm_path_id; rm_drv_path_ctx *rm_drv_path_ctx_p = TD_NULL; rm_drv_golbal_ctx *rm_drv_golbal_ctx_p = TD_NULL; rm_drv_comm_get_golbal_ctx(&rm_drv_golbal_ctx_p); for (rm_path_id = 0; rm_path_id < RM_DRV_CHN_MAX_NUM; rm_path_id++) { rm_drv_comm_get_path_ctx(rm_path_id, &rm_drv_path_ctx_p); if (rm_drv_path_ctx_p->rm_handle == TD_INVALID_HANDLE) { continue; } if (rm_drv_path_ctx_p->idle == TD_TRUE) { soc_log_err("path is idle! recycle it\n"); soc_err_print_u32(rm_path_id); soc_err_print_u32(rm_drv_path_ctx_p->cur_pid); ret = rm_drv_ctrl_disable(rm_drv_path_ctx_p->rm_handle); if (ret != TD_SUCCESS) { soc_err_print_call_fun_err(rm_drv_ctrl_disable, ret); soc_err_print_u32(rm_path_id); } ret = rm_drv_ctrl_destroy(rm_drv_path_ctx_p->rm_handle); if (ret != TD_SUCCESS) { soc_err_print_call_fun_err(rm_drv_ctrl_destroy, ret); soc_err_print_u32(rm_path_id); } else { rm_drv_path_ctx_p->rm_handle = TD_INVALID_HANDLE; rm_drv_path_ctx_p->event_handle_p = TD_NULL; rm_drv_path_ctx_p->chn_enable = TD_FALSE; /* default colse the channel */ rm_drv_path_ctx_p->queue_cnt = 1; rm_drv_path_ctx_p->try_queue_cnt = 0; rm_drv_path_ctx_p->free_node = RM_DRV_LIST_NODE_NUM; rm_drv_path_ctx_p->used_node = 0; rm_drv_path_ctx_p->cur_index = 0; rm_drv_path_ctx_p->cur_pid = 0; rm_drv_golbal_ctx_p->path_recycle_cnt++; soc_log_dbg("path resource leak! recycle succeed!\n"); soc_dbg_print_u32(rm_path_id); } } } return; } td_s32 rm_drv_ctrl_query_event(td_handle rm_handle, ext_drv_rm_event *rm_event_p) { td_s32 ret = TD_FAILURE; td_u32 rm_path_id = 0; rm_drv_path_ctx *rm_drv_path_ctx_p = TD_NULL; ext_drv_rm_event rm_event; if (rm_handle == TD_INVALID_HANDLE) { soc_log_err("rm handle is invalid.\n"); return SOC_ERR_RM_INVALID_HANDLE; } if (((rm_path_id) = (rm_handle) & 0xff) >= RM_DRV_CHN_MAX_NUM) { soc_log_err("rm path id is over range.rm_id = 0x%08X\n", rm_path_id); return SOC_ERR_RM_INST_OVER_RANGE; } rm_drv_comm_get_path_ctx(rm_path_id, &rm_drv_path_ctx_p); check_rm_null_ptr(rm_drv_path_ctx_p); if (rm_handle != rm_drv_path_ctx_p->rm_handle) { soc_log_err("src_rm_handle[%d] is not equal dest_rm_handle[%d].\n", rm_handle, rm_drv_path_ctx_p->rm_handle); soc_err_print_h32(rm_handle); soc_err_print_h32(rm_drv_path_ctx_p->rm_handle); return SOC_ERR_RM_INVALID_HANDLE; } rm_drv_path_ctx_p->try_queue_cnt++; rm_drv_path_ctx_p->lst_query_time = rm_drv_path_ctx_p->cur_query_time; rm_drv_comm_get_cur_time(&rm_drv_path_ctx_p->cur_query_time); rm_drv_path_ctx_p->query_time_diff = rm_drv_path_ctx_p->cur_query_time - rm_drv_path_ctx_p->lst_query_time; rm_drv_path_ctx_p->idle = TD_FALSE; if ((rm_drv_path_ctx_p->list_empty == TD_FALSE) && (rm_drv_path_ctx_p->chn_enable == TD_TRUE)) { ret = rm_drv_comm_get_event(rm_drv_path_ctx_p->rm_handle, rm_drv_path_ctx_p->event_handle_p, &rm_event); if (ret == TD_SUCCESS) { rm_drv_path_ctx_p->queue_cnt++; ret = memcpy_s(rm_event_p, sizeof(ext_drv_rm_event), &rm_event, sizeof(rm_event)); if (ret != TD_SUCCESS) { soc_log_err("call memcpy_s err!\n"); return ret; } soc_log_info("RM event:%d!\n", rm_event_p->win_event); } } return ret; } td_s32 ext_drv_rm_init(td_void) { td_u32 i; soc_info_func_enter(); /* 初始化上下文 */ for (i = 0; i < RM_DRV_CHN_MAX_NUM; i++) { rm_drv_comm_init_path_ctx(i); } rm_drv_comm_init_golbal_ctx(); (td_void)rm_drv_proc_add(); osal_sem_init(&g_rm_drv_mutex, 1); soc_info_func_exit(); return TD_SUCCESS; } td_void ext_drv_rm_de_init(td_void) { td_u32 i; soc_info_func_enter(); /* 初始化上下文 */ for (i = 0; i < RM_DRV_CHN_MAX_NUM; i++) { rm_drv_comm_de_init_path_ctx(i); } rm_drv_comm_de_init_golbal_ctx(); (td_void)rm_drv_proc_del(); osal_sem_destroy(&g_rm_drv_mutex); soc_info_func_exit(); return; } td_s32 ext_drv_rm_create(td_handle *rm_handle, td_u32 pid) { td_s32 ret; td_u32 rm_path_id = 0; td_void *list_handle_p = TD_NULL; rm_drv_path_ctx *rm_drv_path_ctx_p = TD_NULL; rm_drv_golbal_ctx *rm_drv_golbal_ctx_p = TD_NULL; rm_drv_list_attr list_attr; soc_info_func_enter(); check_rm_null_ptr(rm_handle); osal_sem_down(&g_rm_drv_mutex); ret = rm_drv_ctrl_get_free_path_id(&rm_path_id); /* 检查是否满足创建条件 */ if (ret != TD_SUCCESS) { soc_log_err("get free rm id failed\n"); osal_sem_up(&g_rm_drv_mutex); return SOC_ERR_RM_NOT_FREE_INST; } list_attr.list_node_num = RM_DRV_LIST_NODE_NUM; ret = rm_drv_comm_init_event_list(&list_attr, &list_handle_p); if (ret == TD_SUCCESS) { /* 返回生成的handle号 */ *rm_handle = ((SOC_ID_RM << 8) | rm_path_id); /* 8 means letf sheft 8 bit */ rm_drv_comm_get_path_ctx(rm_path_id, &rm_drv_path_ctx_p); check_rm_null_ptr(rm_drv_path_ctx_p); rm_drv_path_ctx_p->rm_handle = *rm_handle; rm_drv_path_ctx_p->event_handle_p = list_handle_p; rm_drv_path_ctx_p->chn_enable = TD_FALSE; /* default colse the channel */ rm_drv_path_ctx_p->queue_cnt = 1; rm_drv_path_ctx_p->try_queue_cnt = 0; rm_drv_path_ctx_p->free_node = RM_DRV_LIST_NODE_NUM; rm_drv_path_ctx_p->used_node = 0; rm_drv_path_ctx_p->cur_index = 0; rm_drv_path_ctx_p->cur_pid = pid; rm_drv_path_ctx_p->list_empty = TD_TRUE; rm_drv_path_ctx_p->idle = TD_FALSE; rm_drv_path_ctx_p->cur_query_time = 0; rm_drv_path_ctx_p->lst_query_time = 0; rm_drv_path_ctx_p->query_time_diff = 0; rm_drv_comm_get_golbal_ctx(&rm_drv_golbal_ctx_p); check_rm_null_ptr(rm_drv_golbal_ctx_p); rm_drv_golbal_ctx_p->rm_path_count++; rm_drv_golbal_ctx_p->chn_create_cnt[rm_path_id]++; } osal_sem_up(&g_rm_drv_mutex); soc_info_func_exit(); return ret; } td_s32 ext_drv_rm_destroy(td_handle rm_handle) { td_s32 ret; soc_info_func_enter(); osal_sem_down(&g_rm_drv_mutex); ret = rm_drv_ctrl_destroy(rm_handle); osal_sem_up(&g_rm_drv_mutex); soc_info_func_exit(); return ret; } td_s32 ext_drv_rm_enable(td_handle rm_handle) { td_u32 rm_path_id = 0; td_s32 ret = TD_SUCCESS; rm_drv_path_ctx *rm_drv_path_ctx_p = TD_NULL; soc_info_func_enter(); if (rm_handle == TD_INVALID_HANDLE) { soc_log_err("rm handle is invalid.\n"); return SOC_ERR_RM_INVALID_HANDLE; } if (((rm_path_id) = (rm_handle) & 0xff) >= RM_DRV_CHN_MAX_NUM) { soc_log_err("rm path id is over range.rm_id = 0x%08X\n", rm_path_id); return SOC_ERR_RM_INST_OVER_RANGE; } rm_drv_comm_get_path_ctx(rm_path_id, &rm_drv_path_ctx_p); check_rm_null_ptr(rm_drv_path_ctx_p); if (rm_handle != rm_drv_path_ctx_p->rm_handle) { soc_log_err("src_rm_handle[%d] is not equal dest_rm_handle[%d].\n", rm_handle, rm_drv_path_ctx_p->rm_handle); soc_err_print_h32(rm_handle); soc_err_print_h32(rm_drv_path_ctx_p->rm_handle); return SOC_ERR_RM_INVALID_HANDLE; } osal_sem_down(&g_rm_drv_mutex); if (rm_drv_path_ctx_p->chn_enable != TD_TRUE) { rm_drv_path_ctx_p->chn_enable = TD_TRUE; } else { soc_log_err("path is already enable!\n"); soc_err_print_u32(rm_path_id); ret = SOC_ERR_RM_ENABLE_ERR; } osal_sem_up(&g_rm_drv_mutex); soc_info_func_exit(); return ret; } td_s32 ext_drv_rm_disable(td_handle rm_handle) { td_s32 ret; soc_info_func_enter(); osal_sem_down(&g_rm_drv_mutex); ret = rm_drv_ctrl_disable(rm_handle); osal_sem_up(&g_rm_drv_mutex); soc_info_func_exit(); return ret; } td_s32 ext_drv_rm_query_event(td_handle rm_handle, ext_drv_rm_event *rm_event_p) { td_s32 ret; check_rm_null_ptr(rm_event_p); osal_sem_down(&g_rm_drv_mutex); ret = rm_drv_ctrl_query_event(rm_handle, rm_event_p); osal_sem_up(&g_rm_drv_mutex); return ret; } static td_s32 rm_wait_condition(const void *data) { if (*(td_bool *)data == TD_TRUE) { return 1; } return 0; } td_s32 ext_drv_rm_acquire_window_handle(td_u32 pid) { td_s32 remain_time = 10; td_s32 ret; rm_drv_golbal_ctx *rm_drv_golbal_ctx_p = TD_NULL; soc_info_func_enter(); rm_drv_comm_get_golbal_ctx(&rm_drv_golbal_ctx_p); check_rm_null_ptr(rm_drv_golbal_ctx_p); rm_drv_ctrl_check_idle_path(); osal_sem_down(&g_rm_drv_mutex); rm_drv_ctrl_recycle_idle_path(); osal_sem_up(&g_rm_drv_mutex); if (rm_drv_golbal_ctx_p->rm_available_win_count > 0) { rm_drv_golbal_ctx_p->normal_cnt++; rm_drv_golbal_ctx_p->win_owner_id = pid; soc_info_func_exit(); return TD_SUCCESS; } else { /* set waiting event flag true */ osal_sem_down(&g_rm_drv_mutex); rm_drv_golbal_ctx_p->waiting_event = TD_TRUE; ret = rm_drv_ctrl_put_win_event_to_list(EXT_DRV_RM_EVENT_WIN_LACK); if (ret != TD_SUCCESS) { soc_log_dbg("put event to list error!\n"); rm_drv_ctrl_recycle_path_resource(); } osal_sem_up(&g_rm_drv_mutex); remain_time = osal_wait_timeout_interruptible(&rm_drv_golbal_ctx_p->wait_queue, rm_wait_condition, &rm_drv_golbal_ctx_p->wake_up_flags, (HZ * 5)); /* (HZ * 5) means the max sleep time */ if (remain_time > 0) { /* 大于零表示非timeout */ rm_drv_golbal_ctx_p->wake_up_cnt++; rm_drv_golbal_ctx_p->wake_up_time = remain_time; rm_drv_golbal_ctx_p->wake_up_flags = TD_FALSE; rm_drv_golbal_ctx_p->waiting_event = TD_FALSE; rm_drv_golbal_ctx_p->win_owner_id = pid; soc_info_func_exit(); return TD_SUCCESS; } } soc_log_err("acquire window resource failed,waiting time out.\n"); soc_err_print_u32(remain_time); soc_info_func_exit(); return SOC_ERR_RM_NOT_RESOURCE; } td_s32 ext_drv_rm_notify_wind_created(td_handle win_handle) { td_s32 ret; rm_drv_golbal_ctx *rm_drv_golbal_ctx_p = TD_NULL; soc_info_func_enter(); osal_sem_down(&g_rm_drv_mutex); rm_drv_comm_get_golbal_ctx(&rm_drv_golbal_ctx_p); check_rm_null_ptr(rm_drv_golbal_ctx_p); rm_drv_golbal_ctx_p->rm_available_win_count--; soc_info_print_s32(rm_drv_golbal_ctx_p->rm_available_win_count); ret = rm_drv_ctrl_put_win_event_to_list(EXT_DRV_RM_EVENT_WIN_CREATED); if (ret != TD_SUCCESS) { soc_log_dbg("put event to list error!\n"); rm_drv_ctrl_recycle_path_resource(); } osal_sem_up(&g_rm_drv_mutex); soc_info_func_exit(); return ret; } td_s32 ext_drv_rm_notify_wind_destroyed(td_handle win_handle) { td_s32 ret; rm_drv_golbal_ctx *rm_drv_golbal_ctx_p = TD_NULL; soc_info_func_enter(); osal_sem_down(&g_rm_drv_mutex); rm_drv_comm_get_golbal_ctx(&rm_drv_golbal_ctx_p); check_rm_null_ptr(rm_drv_golbal_ctx_p); rm_drv_golbal_ctx_p->rm_available_win_count++; soc_info_print_s32(rm_drv_golbal_ctx_p->rm_available_win_count); rm_drv_golbal_ctx_p->wake_up_flags = TD_FALSE; if (rm_drv_golbal_ctx_p->waiting_event) { rm_drv_ctrl_wake_up_waiting_event(); } ret = rm_drv_ctrl_put_win_event_to_list(EXT_DRV_RM_EVENT_WIN_DESTROYED); if (ret != TD_SUCCESS) { soc_log_dbg("put event to list error!\n"); rm_drv_ctrl_recycle_path_resource(); } osal_sem_up(&g_rm_drv_mutex); soc_info_func_exit(); return ret; }