📄 smc.c
字号:
/* FIFO suspension is required. Link the suspend block into the list of suspended tasks on this semaphore. */ CSC_Place_On_List((CS_NODE **) &(semaphore -> sm_suspension_list), &(suspend_ptr -> sm_suspend_link)); } else { /* Get the priority of the current thread so the suspend block can be placed in the appropriate place. */ suspend_ptr -> sm_suspend_link.cs_priority = TCC_Task_Priority(task); CSC_Priority_Place_On_List((CS_NODE **) &(semaphore -> sm_suspension_list), &(suspend_ptr -> sm_suspend_link)); } /* Finally, suspend the calling task. Note that the suspension call automatically clears the protection on the semaphore. */ TCC_Suspend_Task((NU_TASK *) task, NU_SEMAPHORE_SUSPEND, SMC_Cleanup, suspend_ptr, suspend); /* Pickup the return status. */ status = suspend_ptr -> sm_return_status; } else { /* No suspension requested. Simply return an error status. */ status = NU_UNAVAILABLE;#ifdef INCLUDE_PROVIEW _RTProf_DumpSema(RT_PROF_OBTAIN_SEMAPHORE, semaphore,RT_PROF_FAIL);#endif } } /* Release protection against access to the semaphore. */ TCT_Unprotect(); /* Return to user mode */ NU_USER_MODE(); /* Return the completion status. */ return(status);}/*************************************************************************//* *//* FUNCTION *//* *//* SMC_Release_Semaphore *//* *//* DESCRIPTION *//* *//* This function releases a previously obtained semaphore. If one *//* or more tasks are waiting, the first task is given the released *//* instance of the semaphore. Otherwise, the semaphore instance *//* counter is simply incremented. *//* *//* CALLED BY *//* *//* Application *//* SMCE_Release_Semaphore Error checking shell *//* *//* CALLS *//* *//* CSC_Remove_From_List Remove from suspend list *//* [HIC_Make_History_Entry] Make entry in history log *//* TCC_Resume_Task Resume a suspended task *//* [TCT_Check_Stack] Stack checking function *//* TCT_Control_To_System Transfer control to system *//* TCT_System_Protect Protect semaphore *//* TCT_Unprotect Release protection *//* *//* INPUTS *//* *//* semaphore_ptr Semaphore control block ptr *//* *//* OUTPUTS *//* *//* NU_SUCCESS *//* *//* HISTORY *//* *//* DATE REMARKS *//* *//* 03-01-1993 Created initial version 1.0 *//* 04-19-1993 Verified version 1.0 *//* 03-01-1994 Changed function interfaces to *//* match those in prototype, *//* added register options, changed *//* protection logic to reduce *//* overhead, resulting in *//* version 1.1 *//* *//* 03-18-1994 Verified version 1.1 *//* *//*************************************************************************/STATUS SMC_Release_Semaphore(NU_SEMAPHORE *semaphore_ptr){R1 SM_SCB *semaphore; /* Semaphore control blk ptr */R2 SM_SUSPEND *suspend_ptr; /* Pointer to suspend block */STATUS preempt; /* Preemption flag */STATUS status; /* Completion status */NU_SUPERV_USER_VARIABLES /* Switch to supervisor mode */ NU_SUPERVISOR_MODE(); /* Move input semaphore pointer into internal pointer. */ semaphore = (SM_SCB *) semaphore_ptr;#ifdef NU_ENABLE_STACK_CHECK /* Call stack checking function to check for an overflow condition. */ TCT_Check_Stack();#endif#ifdef NU_ENABLE_HISTORY /* Make an entry that corresponds to this function in the system history log. */ HIC_Make_History_Entry(NU_RELEASE_SEMAPHORE_ID, (UNSIGNED) semaphore, (UNSIGNED) 0, (UNSIGNED) 0);#endif /* Initialize the status as successful. */ status = NU_SUCCESS; /* Protect against simultaneous access to the semaphore. */ TCT_System_Protect(); /* Determine if another task is waiting on the semaphore. */ if (semaphore -> sm_tasks_waiting) { /* Yes, another task is waiting for an instance of the semaphore. */ /* Decrement the number of tasks waiting counter. */ semaphore -> sm_tasks_waiting--;#ifdef INCLUDE_PROVIEW _RTProf_DumpSema(RT_PROF_RELEASE_SEMAPHORE, semaphore,RT_PROF_OK);#endif /* Remove the first suspended block from the list. */ suspend_ptr = semaphore -> sm_suspension_list; CSC_Remove_From_List((CS_NODE **) &(semaphore -> sm_suspension_list), &(suspend_ptr -> sm_suspend_link)); /* Setup the appropriate return value. */ suspend_ptr -> sm_return_status = NU_SUCCESS; /* Resume the suspended task. */ preempt = TCC_Resume_Task((NU_TASK *) suspend_ptr -> sm_suspended_task, NU_SEMAPHORE_SUSPEND); /* Determine if a preempt condition is present. */ if (preempt) /* Transfer control to the system if the resumed task function detects a preemption condition. */ TCT_Control_To_System(); } else { /* Increment the semaphore instance counter. */ semaphore -> sm_semaphore_count++;#ifdef INCLUDE_PROVIEW _RTProf_DumpSema(RT_PROF_RELEASE_SEMAPHORE, semaphore,RT_PROF_OK);#endif } /* Release protection against access to the semaphore. */ TCT_Unprotect(); /* Return to user mode */ NU_USER_MODE(); /* Return the completion status. */ return(status);}/*************************************************************************//* *//* FUNCTION *//* *//* SMC_Cleanup *//* *//* DESCRIPTION *//* *//* This function is responsible for removing a suspension block *//* from a semaphore. It is not called unless a timeout or a task *//* terminate is in progress. Note that protection is already in *//* effect - the same protection at suspension time. This routine *//* must be called from Supervisor mode in Supervisor/User mode *//* switching kernels. *//* *//* CALLED BY *//* *//* TCC_Timeout Task timeout *//* TCC_Terminate Task terminate *//* *//* CALLS *//* *//* CSC_Remove_From_List Remove suspend block from *//* the suspension list *//* *//* INPUTS *//* *//* information Pointer to suspend block *//* *//* OUTPUTS *//* *//* None *//* *//* HISTORY *//* *//* DATE REMARKS *//* *//* 03-01-1993 Created initial version 1.0 *//* 04-19-1993 Verified version 1.0 *//* *//*************************************************************************/VOID SMC_Cleanup(VOID *information){SM_SUSPEND *suspend_ptr; /* Suspension block pointer */NU_SUPERV_USER_VARIABLES /* Switch to supervisor mode */ NU_SUPERVISOR_MODE(); /* Use the information pointer as a suspend pointer. */ suspend_ptr = (SM_SUSPEND *) information; /* By default, indicate that the service timed-out. It really does not matter if this function is called from a terminate request since the task does not resume. */ suspend_ptr -> sm_return_status = NU_TIMEOUT; /* Decrement the number of tasks waiting counter. */ (suspend_ptr -> sm_semaphore) -> sm_tasks_waiting--; /* Unlink the suspend block from the suspension list. */ CSC_Remove_From_List((CS_NODE **) &((suspend_ptr -> sm_semaphore) -> sm_suspension_list), &(suspend_ptr -> sm_suspend_link)); /* Return to user mode */ NU_USER_MODE();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -