/* * Copyright (c) Hisilicon Technologies Co., Ltd. 2012-2019. All rights reserved. * Description: mpi_rm.c * Author: sm_rm * Create: 2012-12-01 */ #include #include "securec.h" #include "soc_errno.h" #include "mpi_rm_ext.h" #include "drv_ioctl_rm.h" #include "mpi_rm_define.h" #include "mpi_rm.h" /********************************************************************************/ /* Global */ /********************************************************************************/ static td_s32 g_rm_dev_fd = -1; static td_u32 g_rm_dev_init_cnt = 0; static td_bool g_rm_check_open = TD_FALSE; #define SOC_DEV_RM_NAME "soc_rm" static const td_char g_rm_dev_name[] = "/dev/" SOC_DEV_RM_NAME; static ext_rm_ctx g_rm_ctx; static pthread_mutex_t g_rm_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t g_rm_cb_inst_mutex = PTHREAD_MUTEX_INITIALIZER; static ext_rm_cb_instance g_rm_cb_instance[MAX_CALLBACK_NUM]; /********************************************************************************/ /* Define */ /********************************************************************************/ #define ext_rm_lock() (td_void)pthread_mutex_lock(&g_rm_mutex) #define ext_rm_unlock() (td_void)pthread_mutex_unlock(&g_rm_mutex) #define ext_rm_list_lock() (td_void)pthread_mutex_lock(&g_rm_cb_inst_mutex) #define ext_rm_list_unlock() (td_void)pthread_mutex_unlock(&g_rm_cb_inst_mutex) /********************************************************************************/ /* Array */ /********************************************************************************/ td_char *g_pen_rm_event[EXT_RM_EVENT_MAX + 1] = { "undefine", "LACK", "CREATED", "undefine", "DESTROYED", "BUTT" }; /* Private API */ static td_s32 rm_mpi_convert_event_drv_to_iapi(ext_drv_rm_win_event drv_rm_event, ext_rm_event *pen_iapi_rm_event) { if (pen_iapi_rm_event == NULL) { soc_log_err("rm_mpi_convert_event_drv_to_iapi pen_iapi_rm_event is null pointer.\n"); return SOC_ERR_RM_NULL_PTR; } switch (drv_rm_event) { case EXT_DRV_RM_EVENT_WIN_LACK: *pen_iapi_rm_event = EXT_RM_EVENT_WIN_LACK; break; case EXT_DRV_RM_EVENT_WIN_CREATED: *pen_iapi_rm_event = EXT_RM_EVENT_WIN_CREATED; break; case EXT_DRV_RM_EVENT_WIN_DESTROYED: *pen_iapi_rm_event = EXT_RM_EVENT_WIN_DESTROYED; break; default: *pen_iapi_rm_event = EXT_RM_EVENT_MAX; } return TD_SUCCESS; } static td_s32 rm_mpi_create_event_path(td_u32 pid) { td_s32 ret; rm_create create; create.rm_handle = TD_INVALID_HANDLE; create.pid = pid; ret = ioctl(g_rm_dev_fd, CMD_RM_CREATE, &create); if (ret != TD_SUCCESS) { soc_log_err("call RM ioctl CMD:CMD_RM_CREATE failed, ret: [0x%08X].\n", ret); return ret; } if (create.rm_handle == TD_INVALID_HANDLE) { soc_log_err("create.rm_handle is invalid.\n"); return SOC_ERR_RM_INVALID_HANDLE; } g_rm_ctx.rm_handle = create.rm_handle; return TD_SUCCESS; } static td_s32 rm_mpi_destroy_event_path(td_void) { td_s32 ret; if (g_rm_ctx.rm_handle == TD_INVALID_HANDLE) { soc_log_err("rm handle is invalid.\n"); return SOC_ERR_RM_INVALID_HANDLE; } ret = ioctl(g_rm_dev_fd, CMD_RM_DESTROY, &g_rm_ctx.rm_handle); if (ret != TD_SUCCESS) { soc_log_err("call RM ioctl CMD:CMD_RM_DESTROY failed, ret: [0x%08X].\n", ret); return ret; } return TD_SUCCESS; } static td_s32 rm_mpi_enable_event_path(td_void) { td_s32 ret; if (g_rm_ctx.rm_handle == TD_INVALID_HANDLE) { soc_log_err("rm handle is invalid.\n"); return SOC_ERR_RM_INVALID_HANDLE; } ret = ioctl(g_rm_dev_fd, CMD_RM_ENABLE, &g_rm_ctx.rm_handle); if (ret != TD_SUCCESS) { soc_log_err("call RM ioctl CMD:CMD_RM_ENABLE failed, ret: [0x%08X].\n", ret); return ret; } return TD_SUCCESS; } static td_s32 rm_mpi_disable_event_path(td_void) { td_s32 ret; if (g_rm_ctx.rm_handle == TD_INVALID_HANDLE) { soc_log_err("rm handle is invalid.\n"); return SOC_ERR_RM_INVALID_HANDLE; } ret = ioctl(g_rm_dev_fd, CMD_RM_DISABLE, &g_rm_ctx.rm_handle); if (ret != TD_SUCCESS) { soc_log_err("call RM ioctl CMD:CMD_RM_DISABLE failed, ret: [0x%08X].\n", ret); return ret; } return TD_SUCCESS; } static td_s32 rm_mpi_query_event(ext_rm_event *pen_iapi_rm_event) { td_s32 ret; rm_event rm_query; ext_drv_rm_win_event drv_rm_event; g_rm_ctx.event_querying = TD_TRUE; if (g_rm_ctx.rm_handle == TD_INVALID_HANDLE) { soc_log_err("rm handle is invalid.\n"); return SOC_ERR_RM_INVALID_HANDLE; } memset_s(&rm_query, sizeof(rm_query), 0x0, sizeof(rm_event)); rm_query.rm_handle = g_rm_ctx.rm_handle; ret = ioctl(g_rm_dev_fd, CMD_RM_QUERY, &rm_query); if (ret != TD_SUCCESS) { soc_func_trace_low_freq_cnt_begin(LOW_FREQ_CNT); soc_log_dbg("query event is failed.\n"); soc_func_trace_low_freq_cnt_end(); g_rm_ctx.event_querying = TD_FALSE; return ret; } drv_rm_event = rm_query.rm_event.win_event; ret = rm_mpi_convert_event_drv_to_iapi(drv_rm_event, pen_iapi_rm_event); if (ret != TD_SUCCESS) { soc_log_err("rm_mpi_convert_event_drv_to_iapi error, %d!\n", ret); } g_rm_ctx.event_querying = TD_FALSE; return TD_SUCCESS; } static td_void rm_mpi_event_call_back(ext_rm_event iapi_rm_event) { td_u32 i; td_s32 ret; td_u32 event = 0; ext_rm_cb_instance rm_cb_instance[MAX_CALLBACK_NUM]; soc_dbg_func_enter(); ext_rm_list_lock(); g_rm_ctx.instance_copying = TD_TRUE; for (i = 0; i < MAX_CALLBACK_NUM; i++) { rm_cb_instance[i].client = g_rm_cb_instance[i].client; rm_cb_instance[i].event = g_rm_cb_instance[i].event; rm_cb_instance[i].pid = g_rm_cb_instance[i].pid; rm_cb_instance[i].pfn_rm_event_callback = g_rm_cb_instance[i].pfn_rm_event_callback; } g_rm_ctx.instance_copying = TD_FALSE; ext_rm_list_unlock(); soc_dbg_func_enter(); for (i = 0; i < MAX_CALLBACK_NUM; i++) { event = rm_cb_instance[i].event; if ((rm_cb_instance[i].pfn_rm_event_callback == TD_NULL) || (iapi_rm_event == EXT_RM_EVENT_MAX)) { soc_log_err("rm_event_callback is NULL or iapi_rm_event(%d) invalid.\n", iapi_rm_event); continue; } if (((event & (td_u32)EXT_RM_EVENT_WIN_LACK) == iapi_rm_event) || ((event & (td_u32)EXT_RM_EVENT_WIN_CREATED) == iapi_rm_event) || ((event & (td_u32)EXT_RM_EVENT_WIN_DESTROYED) == iapi_rm_event)) { soc_log_info("***not a bug,only for debug.***\n"); soc_info_print_u32(g_rm_ctx.pid); soc_notice_print_u32(rm_cb_instance[i].pid); soc_notice_print_str(g_pen_rm_event[iapi_rm_event]); g_rm_ctx.call_backing = TD_TRUE; ret = rm_cb_instance[i].pfn_rm_event_callback(rm_cb_instance[i].client, iapi_rm_event, 0); if (ret != TD_SUCCESS) { soc_log_err("call_back function execute error!\n"); } g_rm_ctx.call_backing = TD_FALSE; } } soc_dbg_func_exit(); return; } static td_void *rm_mpi_event_process_thread(td_void *arg) { td_s32 ret; td_u32 cnt = 0; td_u32 pid = 0; ext_rm_event rm_event = EXT_RM_EVENT_MAX; TD_UNUSED(arg); TD_UNUSED(pid); while (g_rm_ctx.thread_run) { if (g_rm_ctx.task_start == TD_TRUE) { ret = rm_mpi_query_event(&rm_event); if (ret != TD_SUCCESS) { ext_usleep(THREAT_SLEEP_TIME); } else { rm_mpi_event_call_back(rm_event); } cnt++; if (cnt >= 500) { /* 500 uesd to reduce print freq */ pid = (td_u32)getpid(); soc_dbg_print_u32(pid); soc_dbg_print_str(g_pen_rm_event[rm_event]); cnt = 0; } g_rm_ctx.task_status = EXT_RM_TASK_STATUS_RUNNING; } else { g_rm_ctx.task_status = EXT_RM_TASK_STATUS_PAUSED; ext_usleep(THREAT_SLEEP_TIME); continue; } } return TD_NULL; } static td_s32 rm_mpi_create_query_thread(td_void) { td_s32 ret; g_rm_ctx.thread_run = TD_TRUE; (td_void)pthread_attr_init(&g_rm_ctx.rm_query_thread_attr); (td_void)pthread_attr_setschedpolicy(&g_rm_ctx.rm_query_thread_attr, SCHED_OTHER); /* create rm event query process thread */ ret = pthread_create(&g_rm_ctx.rm_query_thd_inst, &g_rm_ctx.rm_query_thread_attr, rm_mpi_event_process_thread, TD_NULL); if (ret != TD_SUCCESS) { pthread_attr_destroy(&g_rm_ctx.rm_query_thread_attr); soc_err_print_call_fun_err(pthread_create, ret); return TD_FAILURE; } return TD_SUCCESS; } static td_void rm_mpi_destroy_query_thread(td_void) { td_s32 ret; g_rm_ctx.thread_run = TD_FALSE; ret = pthread_join(g_rm_ctx.rm_query_thd_inst, TD_NULL); if (ret != TD_SUCCESS) { soc_err_print_call_fun_err(pthread_join, ret); } ret = pthread_attr_destroy(&g_rm_ctx.rm_query_thread_attr); if (ret != TD_SUCCESS) { soc_err_print_call_fun_err(pthread_attr_destroy, ret); } g_rm_ctx.rm_query_thd_inst = 0; } static td_void rm_mpi_task_suspend(td_void) { td_u32 suspend_time = 0; if (g_rm_ctx.thread_run == TD_TRUE) { g_rm_ctx.task_start = TD_FALSE; while (g_rm_ctx.task_status != EXT_RM_TASK_STATUS_PAUSED) { ext_usleep(THREAT_SLEEP_TIME); /* wait task paused */ suspend_time += THREAT_SLEEP_TIME; /* THREAT_SLEEP_TIME * 1000 means dead lock */ if (suspend_time > (THREAT_SLEEP_TIME * 1000)) { soc_func_trace_low_freq_cnt_begin(LOW_FREQ_CNT); soc_log_err("dead lock, prohibit calling other RM interfaces in callback function!!!\n"); soc_err_print_bool(g_rm_ctx.call_backing); soc_err_print_bool(g_rm_ctx.instance_copying); soc_err_print_bool(g_rm_ctx.event_querying); soc_err_print_bool(g_rm_ctx.task_start); soc_err_print_u32(g_rm_ctx.pid); soc_func_trace_low_freq_cnt_end(); } continue; } } soc_log_dbg("suspend_time = %u(us)\n", suspend_time); return; } static td_void rm_mpi_task_resume(td_void) { if (g_rm_ctx.thread_run == TD_TRUE && g_rm_ctx.query_path_exist == TD_TRUE) { g_rm_ctx.task_start = TD_TRUE; soc_info_print_bool(g_rm_ctx.task_start); } soc_log_dbg("task resume ok\n"); return; } static td_void rm_mpi_init_instance(td_void) { td_u32 i; ext_rm_list_lock(); for (i = 0; i < MAX_CALLBACK_NUM; i++) { g_rm_cb_instance[i].client = TD_NULL; g_rm_cb_instance[i].pfn_rm_event_callback = TD_NULL; g_rm_cb_instance[i].event = 0; g_rm_cb_instance[i].pid = 0; } ext_rm_list_unlock(); return; } static td_void rm_mpi_init_ctx(td_void) { g_rm_ctx.rm_handle = TD_INVALID_HANDLE; g_rm_ctx.task_start = TD_FALSE; g_rm_ctx.thread_run = TD_FALSE; g_rm_ctx.task_status = EXT_RM_TASK_STATUS_PAUSED; g_rm_ctx.query_path_exist = TD_FALSE; g_rm_ctx.rm_query_thd_inst = 0; g_rm_ctx.pid = 0; g_rm_ctx.call_backing = TD_FALSE; return; } static td_s32 rm_mpi_create_query_path(td_void) { td_s32 ret; td_u32 pid; pid = (td_u32)getpid(); g_rm_ctx.pid = pid; ret = rm_mpi_create_event_path(pid); if (ret != TD_SUCCESS) { soc_err_print_call_fun_err(rm_mpi_create_event_path, ret); return TD_FAILURE; } ret = rm_mpi_create_query_thread(); if (ret != TD_SUCCESS) { soc_err_print_call_fun_err(rm_mpi_create_query_thread, ret); goto DESTROY_PATH; } ret = rm_mpi_enable_event_path(); if (ret != TD_SUCCESS) { soc_err_print_call_fun_err(rm_mpi_enable_event_path, ret); goto DESTROY_THREAD; } return TD_SUCCESS; DESTROY_THREAD: rm_mpi_destroy_query_thread(); DESTROY_PATH: ret = rm_mpi_destroy_event_path(); if (ret != TD_SUCCESS) { soc_err_print_call_fun_err(rm_mpi_destroy_event_path, ret); } return TD_FAILURE; } static td_s32 rm_mpi_destroy_query_path(td_void) { td_s32 ret; rm_mpi_destroy_query_thread(); ret = rm_mpi_disable_event_path(); if (ret != TD_SUCCESS) { soc_err_print_call_fun_err(rm_mpi_disable_event_path, ret); } ret = rm_mpi_destroy_event_path(); if (ret != TD_SUCCESS) { soc_err_print_call_fun_err(rm_mpi_destroy_event_path, ret); return TD_FAILURE; } rm_mpi_init_instance(); g_rm_ctx.query_path_exist = TD_FALSE; return TD_SUCCESS; } static td_s32 rm_mpi_get_free_instance(td_u32 *instance_id_p) { td_u32 i; ext_rm_list_lock(); for (i = 0; i < MAX_CALLBACK_NUM; i++) { if (g_rm_cb_instance[i].pfn_rm_event_callback == TD_NULL) { *instance_id_p = i; break; } } ext_rm_list_unlock(); if (i == MAX_CALLBACK_NUM) { return TD_FAILURE; } return TD_SUCCESS; } static td_bool rm_mpi_find_instance_by_client(const td_void *client, td_u32 *instance_id_p) { td_u32 i; ext_rm_list_lock(); for (i = 0; i < MAX_CALLBACK_NUM; i++) { if (client == g_rm_cb_instance[i].client) { *instance_id_p = i; break; } } ext_rm_list_unlock(); if (i == MAX_CALLBACK_NUM) { return TD_FALSE; } return TD_TRUE; } static td_bool rm_mpi_need_destroy_path(td_void) { td_u32 i; ext_rm_list_lock(); for (i = 0; i < MAX_CALLBACK_NUM; i++) { if (g_rm_cb_instance[i].pfn_rm_event_callback != TD_NULL) { break; } } ext_rm_list_unlock(); if (i == MAX_CALLBACK_NUM) { return TD_TRUE; } return TD_FALSE; } static td_s32 rm_mpi_check_and_open(td_void) { td_char path[PATH_MAX] = {0}; if (g_rm_dev_fd < 0) { soc_log_info("current RM not open, open it\n"); if (realpath(g_rm_dev_name, path) == TD_NULL) { soc_log_err("get realpath error!\n"); return TD_FAILURE; } g_rm_dev_fd = open(path, O_RDWR | O_NONBLOCK, 0); if (g_rm_dev_fd < 0) { soc_log_err("open RM err.\n"); return SOC_ERR_RM_DEV_OPEN_ERR; } g_rm_check_open = TD_TRUE; } return TD_SUCCESS; } static td_s32 rm_mpi_reg_callback(const td_void *client, ext_rm_event_cb_fn fn, td_u32 event) { td_s32 ret = TD_SUCCESS; td_u32 instance = 0; td_bool instance_exist; if (g_rm_ctx.query_path_exist == TD_FALSE) { ret = rm_mpi_create_query_path(); if (ret == TD_FAILURE) { soc_err_print_call_fun_err(rm_mpi_create_query_path, ret); rm_mpi_task_resume(); return SOC_ERR_RM_CREATE_ERR; } ret = rm_mpi_get_free_instance(&instance); if (ret == TD_FAILURE) { soc_err_print_call_fun_err(rm_mpi_get_free_instance, ret); ret = rm_mpi_destroy_query_path(); if (ret == TD_FAILURE) { soc_err_print_call_fun_err(rm_mpi_destroy_query_path, ret); } else { g_rm_ctx.query_path_exist = TD_FALSE; } rm_mpi_task_resume(); return SOC_ERR_RM_NOT_FREE_CB_INST; } g_rm_ctx.query_path_exist = TD_TRUE; soc_log_dbg("register callback succeed\n"); } else { instance_exist = rm_mpi_find_instance_by_client(client, &instance); if (instance_exist != TD_TRUE) { ret = rm_mpi_get_free_instance(&instance); if (ret == TD_FAILURE) { soc_err_print_call_fun_err(rm_mpi_get_free_instance, ret); rm_mpi_task_resume(); return SOC_ERR_RM_NOT_FREE_CB_INST; } } soc_log_dbg("repeat register succeed.\n"); } soc_log_notice("g_rm_ctx.pid = %u, event = %d \n", g_rm_ctx.pid, event); ext_rm_list_lock(); g_rm_cb_instance[instance].pfn_rm_event_callback = fn; g_rm_cb_instance[instance].client = (td_void *)client; g_rm_cb_instance[instance].event = event; g_rm_cb_instance[instance].pid = (td_u32)getpid(); ext_rm_list_unlock(); return ret; } static td_s32 rm_mpi_unregister_callback_pre_check(const td_void *client, ext_rm_event_cb_fn fn) { if (client == NULL) { soc_log_err("ext_mpi_rm_un_register_callback client_p is null pointer.\n"); return SOC_ERR_RM_NULL_PTR; } if (fn == NULL) { soc_log_err("ext_mpi_rm_un_register_callback fn is null pointer.\n"); return SOC_ERR_RM_NULL_PTR; } return TD_SUCCESS; } static td_void rm_mpi_reset_callback_instance(td_u32 cb_index) { g_rm_cb_instance[cb_index].event = 0; g_rm_cb_instance[cb_index].pid = 0; g_rm_cb_instance[cb_index].client = TD_NULL; g_rm_cb_instance[cb_index].pfn_rm_event_callback = TD_NULL; return; } /* Public API */ td_s32 ext_mpi_rm_init(td_void) { td_char path[PATH_MAX] = {0}; soc_info_func_enter(); ext_rm_lock(); if (g_rm_dev_fd > 0) { g_rm_dev_init_cnt++; soc_log_warn("RM be inited, query path be exist.\n"); soc_info_print_u32(g_rm_dev_init_cnt); soc_info_func_exit(); ext_rm_unlock(); return TD_SUCCESS; } if (realpath(g_rm_dev_name, path) == TD_NULL) { soc_log_err("get realpath error!\n"); ext_rm_unlock(); return TD_FAILURE; } g_rm_dev_fd = open(path, O_RDWR | O_NONBLOCK, 0); if (g_rm_dev_fd < 0) { soc_log_err("open RM err.\n"); ext_rm_unlock(); return SOC_ERR_RM_DEV_OPEN_ERR; } rm_mpi_init_ctx(); rm_mpi_init_instance(); g_rm_dev_init_cnt++; soc_info_print_u32(g_rm_dev_init_cnt); ext_rm_unlock(); soc_info_func_exit(); return TD_SUCCESS; } td_s32 ext_mpi_rm_deinit(td_void) { td_s32 ret; soc_info_func_enter(); if (g_rm_ctx.call_backing == TD_TRUE) { soc_log_warn("the callback function is not finished\n"); } ext_rm_lock(); rm_mpi_task_suspend(); if (g_rm_dev_init_cnt > 1) { soc_log_warn("RM reference count not zero.\n"); soc_info_func_exit(); g_rm_dev_init_cnt--; soc_info_print_u32(g_rm_dev_init_cnt); ext_rm_unlock(); return TD_SUCCESS; } if ((g_rm_dev_fd < 0) || (g_rm_dev_init_cnt == 0)) { ext_rm_unlock(); soc_log_warn("RM be de_inited.\n"); soc_info_func_exit(); return TD_SUCCESS; } if (g_rm_ctx.query_path_exist == TD_TRUE) { soc_log_warn("query path is exist,destroy it.\n"); ret = rm_mpi_destroy_query_path(); if (ret != TD_SUCCESS) { ext_rm_unlock(); soc_err_print_call_fun_err(rm_mpi_destroy_query_path, ret); return TD_FAILURE; } } else { rm_mpi_init_instance(); } close(g_rm_dev_fd); g_rm_dev_fd = -1; g_rm_dev_init_cnt--; soc_info_print_u32(g_rm_dev_init_cnt); rm_mpi_init_ctx(); ext_rm_unlock(); soc_info_func_exit(); return TD_SUCCESS; } td_s32 ext_mpi_rm_register_callback(const td_void *client, ext_rm_event_cb_fn fn, td_u32 event_mask) { td_s32 ret; soc_info_func_enter(); if (client == NULL) { soc_log_err("ext_mpi_rm_register_callback client_p is null pointer.\n"); return SOC_ERR_RM_NULL_PTR; } if (fn == NULL) { soc_log_err("ext_mpi_rm_register_callback fn is null pointer.\n"); return SOC_ERR_RM_NULL_PTR; } if ((event_mask & (td_u32)(EXT_RM_EVENT_WIN_LACK | EXT_RM_EVENT_WIN_CREATED | EXT_RM_EVENT_WIN_DESTROYED)) == 0) { soc_log_err("event:%d is invalid.\n", event_mask); return SOC_ERR_RM_INVALID_PARA; } if (g_rm_ctx.call_backing == TD_TRUE) { soc_log_warn("the callback function is not finished\n"); } ext_rm_lock(); rm_mpi_task_suspend(); if (g_rm_dev_fd < 0) { rm_mpi_task_resume(); ext_rm_unlock(); soc_log_err("please init firstly.\n"); return SOC_ERR_RM_DEV_NOT_INIT; } ret = rm_mpi_reg_callback(client, fn, event_mask); if (ret != TD_SUCCESS) { ext_rm_unlock(); soc_err_print_call_fun_err(rm_mpi_reg_callback, ret); return ret; } rm_mpi_task_resume(); ext_rm_unlock(); soc_info_func_exit(); return TD_SUCCESS; } td_s32 ext_mpi_rm_unregister_callback(const td_void *client, ext_rm_event_cb_fn fn) { td_s32 ret; td_u32 cb_index; td_bool need_destroy_path; td_bool instance_exist; soc_info_func_enter(); ret = rm_mpi_unregister_callback_pre_check(client, fn); if (ret != TD_SUCCESS) { return ret; } ext_rm_lock(); rm_mpi_task_suspend(); if (g_rm_dev_fd < 0) { rm_mpi_task_resume(); ext_rm_unlock(); soc_log_err("please init firstly.\n"); return SOC_ERR_RM_DEV_NO_INIT; } instance_exist = rm_mpi_find_instance_by_client(client, &cb_index); if (instance_exist == TD_FALSE) { soc_log_err("find instance by client_p error!\n"); rm_mpi_task_resume(); ext_rm_unlock(); return SOC_ERR_RM_INVALID_PARA; } soc_log_info("try to un_register callback.\n"); soc_dbg_print_u32(g_rm_ctx.pid); soc_dbg_print_void(client); ext_rm_list_lock(); rm_mpi_reset_callback_instance(cb_index); ext_rm_list_unlock(); need_destroy_path = rm_mpi_need_destroy_path(); if (need_destroy_path == TD_TRUE) { ret = rm_mpi_destroy_query_path(); if (ret != TD_SUCCESS) { rm_mpi_task_resume(); ext_rm_unlock(); soc_err_print_call_fun_err(rm_mpi_destroy_query_path, ret); return SOC_ERR_RM_DESTROY_ERR; } } rm_mpi_task_resume(); ext_rm_unlock(); soc_log_info("un_register callback OK.\n"); soc_info_func_exit(); return TD_SUCCESS; } td_s32 ext_mpi_rm_acquire_window_handle(td_void) { td_s32 ret; rm_win_info rm_win_info = {TD_INVALID_HANDLE, 0}; soc_info_func_enter(); ext_rm_lock(); ret = rm_mpi_check_and_open(); if (ret != TD_SUCCESS) { ext_rm_unlock(); soc_log_err("this instance is not init,please init firstly.\n"); return SOC_ERR_RM_DEV_NOT_INIT; } ext_rm_unlock(); rm_win_info.win_handle = TD_INVALID_HANDLE; rm_win_info.pid = (td_u32)getpid(); soc_log_notice("try to acquire window resource, current acquire window PID:%u\n", rm_win_info.pid); ret = ioctl(g_rm_dev_fd, CMD_RM_ACQUIREWIN, &rm_win_info); if (ret != TD_SUCCESS) { soc_log_err("call RM ioctl CMD:CMD_RM_ACQUIREWIN failed, ret: [0x%08X].\n", ret); return ret; } soc_log_notice("current process check_open:%s\n", g_rm_check_open == TD_TRUE ? "true" : "false"); soc_info_func_exit(); return TD_SUCCESS; }