OS_OBJ_QTY OSSemDel (OS_SEM *p_sem, OS_OPT opt, OS_ERR *p_err) { OS_OBJ_QTY cnt; OS_OBJ_QTY nbr_tasks; OS_PEND_DATA *p_pend_data; OS_PEND_LIST *p_pend_list; OS_TCB *p_tcb; CPU_TS ts; CPU_SR_ALLOC(); #ifdef OS_SAFETY_CRITICAL if (p_err == (OS_ERR *)0) { OS_SAFETY_CRITICAL_EXCEPTION(); return ((OS_OBJ_QTY)0); } #endif #if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u if (OSIntNestingCtr > (OS_NESTING_CTR)0) { /* Not allowed to delete a semaphore from an ISR */ *p_err = OS_ERR_DEL_ISR; return ((OS_OBJ_QTY)0); } #endif #if OS_CFG_ARG_CHK_EN > 0u if (p_sem == (OS_SEM *)0) { /* Validate 'p_sem' */ *p_err = OS_ERR_OBJ_PTR_NULL; return ((OS_OBJ_QTY)0); } switch (opt) { /* Validate 'opt' */ case OS_OPT_DEL_NO_PEND: case OS_OPT_DEL_ALWAYS: break; default: *p_err = OS_ERR_OPT_INVALID; return ((OS_OBJ_QTY)0); } #endif #if OS_CFG_OBJ_TYPE_CHK_EN > 0u if (p_sem->Type != OS_OBJ_TYPE_SEM) { /* Make sure semaphore was created */ *p_err = OS_ERR_OBJ_TYPE; return ((OS_OBJ_QTY)0); } #endif CPU_CRITICAL_ENTER(); p_pend_list = &p_sem->PendList; cnt = p_pend_list->NbrEntries; nbr_tasks = cnt; switch (opt) { case OS_OPT_DEL_NO_PEND: /* Delete semaphore only if no task waiting */ if (nbr_tasks == (OS_OBJ_QTY)0) { #if OS_CFG_DBG_EN > 0u OS_SemDbgListRemove(p_sem); #endif OSSemQty--; #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_SEM_DEL(p_sem); /* Record the event. */ #endif OS_SemClr(p_sem); CPU_CRITICAL_EXIT(); *p_err = OS_ERR_NONE; } else { CPU_CRITICAL_EXIT(); *p_err = OS_ERR_TASK_WAITING; } break; case OS_OPT_DEL_ALWAYS: /* Always delete the semaphore */ OS_CRITICAL_ENTER_CPU_EXIT(); ts = OS_TS_GET(); /* Get local time stamp so all tasks get the same time */ while (cnt > 0u) { /* Remove all tasks on the pend list */ p_pend_data = p_pend_list->HeadPtr; p_tcb = p_pend_data->TCBPtr; OS_PendObjDel((OS_PEND_OBJ *)((void *)p_sem), p_tcb, ts); cnt--; } #if OS_CFG_DBG_EN > 0u OS_SemDbgListRemove(p_sem); #endif OSSemQty--; #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_SEM_DEL(p_sem); /* Record the event. */ #endif OS_SemClr(p_sem); OS_CRITICAL_EXIT_NO_SCHED(); OSSched(); /* Find highest priority task ready to run */ *p_err = OS_ERR_NONE; break; default: CPU_CRITICAL_EXIT(); *p_err = OS_ERR_OPT_INVALID; break; } return ((OS_OBJ_QTY)nbr_tasks); }
OS_OBJ_QTY OSSemDel (OS_SEM *p_sem, OS_OPT opt, OS_ERR *p_err) { OS_OBJ_QTY nbr_tasks; OS_PEND_DATA *p_pend_data; OS_PEND_LIST *p_pend_list; OS_TCB *p_tcb; CPU_TS ts; CPU_SR_ALLOC(); #ifdef OS_SAFETY_CRITICAL if (p_err == DEF_NULL) { OS_SAFETY_CRITICAL_EXCEPTION(); return (0u); } #endif #ifdef OS_SAFETY_CRITICAL_IEC61508 if (OSSafetyCriticalStartFlag == DEF_TRUE) { *p_err = OS_ERR_ILLEGAL_DEL_RUN_TIME; return (0u); } #endif #if (OS_CFG_CALLED_FROM_ISR_CHK_EN == DEF_ENABLED) if (OSIntNestingCtr > 0u) { /* Not allowed to delete a semaphore from an ISR */ *p_err = OS_ERR_DEL_ISR; return (0u); } #endif #if (OS_CFG_INVALID_OS_CALLS_CHK_EN == DEF_ENABLED) /* Is the kernel running? */ if (OSRunning != OS_STATE_OS_RUNNING) { *p_err = OS_ERR_OS_NOT_RUNNING; return (0u); } #endif #if (OS_CFG_ARG_CHK_EN == DEF_ENABLED) if (p_sem == DEF_NULL) { /* Validate 'p_sem' */ *p_err = OS_ERR_OBJ_PTR_NULL; return (0u); } #endif #if (OS_CFG_OBJ_TYPE_CHK_EN == DEF_ENABLED) if (p_sem->Type != OS_OBJ_TYPE_SEM) { /* Make sure semaphore was created */ *p_err = OS_ERR_OBJ_TYPE; return (0u); } #endif CPU_CRITICAL_ENTER(); p_pend_list = &p_sem->PendList; nbr_tasks = 0u; switch (opt) { case OS_OPT_DEL_NO_PEND: /* Delete semaphore only if no task waiting */ if (p_pend_list->HeadPtr == DEF_NULL) { #if (OS_CFG_DBG_EN == DEF_ENABLED) OS_SemDbgListRemove(p_sem); OSSemQty--; #endif #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN == DEF_ENABLED)) TRACE_OS_SEM_DEL(p_sem); /* Record the event. */ #endif OS_SemClr(p_sem); CPU_CRITICAL_EXIT(); *p_err = OS_ERR_NONE; } else { CPU_CRITICAL_EXIT(); *p_err = OS_ERR_TASK_WAITING; } break; case OS_OPT_DEL_ALWAYS: /* Always delete the semaphore */ OS_CRITICAL_ENTER_CPU_EXIT(); #if (OS_CFG_TS_EN == DEF_ENABLED) ts = OS_TS_GET(); /* Get local time stamp so all tasks get the same time */ #else ts = 0u; #endif while (p_pend_list->HeadPtr != DEF_NULL) { /* Remove all tasks on the pend list */ p_pend_data = p_pend_list->HeadPtr; p_tcb = p_pend_data->TCBPtr; OS_PendObjDel((OS_PEND_OBJ *)((void *)p_sem), p_tcb, ts); nbr_tasks++; } #if (OS_CFG_DBG_EN == DEF_ENABLED) OS_SemDbgListRemove(p_sem); OSSemQty--; #endif #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN == DEF_ENABLED)) TRACE_OS_SEM_DEL(p_sem); /* Record the event. */ #endif OS_SemClr(p_sem); OS_CRITICAL_EXIT_NO_SCHED(); OSSched(); /* Find highest priority task ready to run */ *p_err = OS_ERR_NONE; break; default: CPU_CRITICAL_EXIT(); *p_err = OS_ERR_OPT_INVALID; break; } return (nbr_tasks); }