📄 smc.c
字号:
/* *//* 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_Delete_Semaphore(NU_SEMAPHORE *semaphore_ptr){R1 SM_SCB *semaphore; /* Semaphore control blk ptr */SM_SUSPEND *suspend_ptr; /* Suspend block pointer */SM_SUSPEND *next_ptr; /* Next suspend block */STATUS preempt; /* Status for resume call */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_DELETE_SEMAPHORE_ID, (UNSIGNED) semaphore, (UNSIGNED) 0, (UNSIGNED) 0);#endif /* Protect against access to the semaphore. */ TCT_System_Protect();#ifdef INCLUDE_PROVIEW _RTProf_DumpSema(RT_PROF_DELETE_SEMAPHORE,semaphore, RT_PROF_OK);#endif /* Clear the semaphore ID. */ semaphore -> sm_id = 0; /* Release protection. */ TCT_Unprotect(); /* Protect against access to the list of created semaphores. */ TCT_Protect(&SMD_List_Protect); /* Remove the semaphore from the list of created semaphores. */ CSC_Remove_From_List(&SMD_Created_Semaphores_List, &(semaphore -> sm_created)); /* Decrement the total number of created semaphores. */ SMD_Total_Semaphores--; /* Pickup the suspended task pointer list. */ suspend_ptr = semaphore -> sm_suspension_list; /* Walk the chain task(s) currently suspended on the semaphore. */ preempt = 0; while (suspend_ptr) { /* Protect against system access. */ TCT_System_Protect(); /* Resume the suspended task. Insure that the status returned is NU_SEMAPHORE_DELETED. */ suspend_ptr -> sm_return_status = NU_SEMAPHORE_DELETED; /* Point to the next suspend structure in the link. */ next_ptr = (SM_SUSPEND *) (suspend_ptr -> sm_suspend_link.cs_next); /* Resume the specified task. */ preempt = preempt | TCC_Resume_Task((NU_TASK *) suspend_ptr -> sm_suspended_task, NU_SEMAPHORE_SUSPEND); /* Determine if the next is the same as the current pointer. */ if (next_ptr == semaphore -> sm_suspension_list) /* Clear the suspension pointer to signal the end of the list traversal. */ suspend_ptr = NU_NULL; else /* Move the next pointer into the suspend block pointer. */ suspend_ptr = next_ptr; /* Modify current protection. */ TCT_Set_Current_Protect(&SMD_List_Protect); /* Clear the system protection. */ TCT_System_Unprotect(); } /* Determine if preemption needs to occur. */ if (preempt) /* Transfer control to system to facilitate preemption. */ TCT_Control_To_System(); /* Release protection against access to the list of created semaphores. */ TCT_Unprotect(); /* Return to user mode */ NU_USER_MODE(); /* Return a successful completion. */ return(NU_SUCCESS);}/*************************************************************************//* *//* FUNCTION *//* *//* SMC_Obtain_Semaphore *//* *//* DESCRIPTION *//* *//* This function obtains an instance of the semaphore. An instance *//* corresponds to decrementing the counter by 1. If the counter is *//* greater than zero at the time of this call, this function can be *//* completed immediately. Otherwise, suspension is possible. *//* *//* CALLED BY *//* *//* Application *//* SMCE_Obtain_Semaphore Error checking shell *//* *//* CALLS *//* *//* CSC_Place_On_List Place on suspend list *//* CSC_Priority_Place_On_List Place on priority list *//* [HIC_Make_History_Entry] Make entry in history log *//* TCC_Suspend_Task Suspend calling task *//* TCC_Task_Priority Obtain task's priority *//* [TCT_Check_Stack] Stack checking function *//* TCT_Current_Thread Pickup current thread pointer*//* TCT_System_Protect Protect semaphore *//* TCT_Unprotect Release protection *//* *//* INPUTS *//* *//* semaphore_ptr Semaphore control block ptr *//* suspend Suspension option if full *//* *//* OUTPUTS *//* *//* NU_SUCCESS If service is successful *//* NU_UNAVAILABLE If an instance of the *//* semaphore is not available *//* NU_TIMEOUT If timeout on service *//* NU_SEMAPHORE_DELETED If semaphore deleted during *//* suspension *//* NU_SEMAPHORE_RESET If semaphore reset during *//* suspension *//* *//* 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_Obtain_Semaphore(NU_SEMAPHORE *semaphore_ptr, UNSIGNED suspend){R1 SM_SCB *semaphore; /* Semaphore control blk ptr */R2 SM_SUSPEND *suspend_ptr; /* Suspend block pointer */SM_SUSPEND suspend_block; /* Allocate suspension block */TC_TCB *task; /* Task pointer */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_OBTAIN_SEMAPHORE_ID, (UNSIGNED) semaphore, (UNSIGNED) suspend, (UNSIGNED) 0);#endif /* Initialize the status as successful. */ status = NU_SUCCESS; /* Protect against simultaneous access to the semaphore. */ TCT_System_Protect(); /* Determine if the semaphore has an instance (can be decremented). */ if (semaphore -> sm_semaphore_count) { /* Semaphore available. Decrement and return to the caller. */ semaphore -> sm_semaphore_count--;#ifdef INCLUDE_PROVIEW _RTProf_DumpSema(RT_PROF_OBTAIN_SEMAPHORE,semaphore, RT_PROF_OK);#endif } else { /* Semaphore is not available. Determine if suspension is required. */ if (suspend) { /* Suspension is selected. */ /* Increment the number of tasks waiting. */ semaphore -> sm_tasks_waiting++;#ifdef INCLUDE_PROVIEW _RTProf_DumpSema(RT_PROF_OBTAIN_SEMAPHORE,semaphore , RT_PROF_WAIT);#endif /* Setup the suspend block and suspend the calling task. */ suspend_ptr = &suspend_block; suspend_ptr -> sm_semaphore = semaphore; suspend_ptr -> sm_suspend_link.cs_next = NU_NULL; suspend_ptr -> sm_suspend_link.cs_previous = NU_NULL; task = (TC_TCB *) TCT_Current_Thread(); suspend_ptr -> sm_suspended_task = task; /* Determine if priority or FIFO suspension is associated with the semaphore. */ if (semaphore -> sm_fifo_suspend) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -