📄 skp.c
字号:
/*} */ /* end of SKP_Schedule */
/************************************************************************/
/* */
/* FUNCTION "SKP_Ready_Task" */
/* */
/* */
/* DESCRIPTION */
/* */
/* This function places the designated task on the ready list */
/* relative to its priority. */
/* */
/* AUTHOR */
/* */
/* William E. Lamie, Accelerated Technology */
/* */
/* CALLED FROM */
/* */
/* Any nucleus routine that lifts the suspension of a task. */
/* */
/* ROUTINES CALLED */
/* */
/* DS_Stop_Performance_Timer Stop suspended timer */
/* DS_Start_Performance_Timer Start wait timer */
/* DS_Make_History_Entry Make an history entry */
/* */
/* INPUTS */
/* */
/* task_id Task identification */
/* */
/* OUTPUTS */
/* */
/* Ready task list */
/* return(preempt) Preemption flag */
/* */
/************************************************************************/
signed int SKP_Ready_Task(signed int task_id)
{
struct SK_TASK_CONTROL_BLOCK_STRUCT
*new_tcb_ptr, /* New TCB pointer */
*next_tcb_ptr, /* Next tcb pointer */
*prev_tcb_ptr; /* Previous tcb pointer */
signed int preempt = NU_FALSE; /* Preempt flag */
/* Setup a pointer to the newly ready TCB. */
new_tcb_ptr = &SKP_TCB_List[task_id];
/* Check to make sure the designated task is suspended. */
if (new_tcb_ptr -> sk_suspend != NU_READY)
{
/* Start searching from the beginning of the ready list. */
prev_tcb_ptr = NU_NULL;
next_tcb_ptr = SKP_Ready_List_Ptr;
while ((next_tcb_ptr != NU_NULL) &&
(new_tcb_ptr -> sk_priority >= next_tcb_ptr -> sk_priority))
{
/* save off the previous TCB pointer and update the
current. */
prev_tcb_ptr = next_tcb_ptr;
next_tcb_ptr = next_tcb_ptr -> sk_ready_next;
}
/* At this point we have located where the new TCB needs to be
added. Update all the pointers. */
if (next_tcb_ptr != NU_NULL)
{
/* Link the new TCB and this TCB together. */
new_tcb_ptr -> sk_ready_next = next_tcb_ptr;
next_tcb_ptr -> sk_ready_prev = new_tcb_ptr;
}
if (prev_tcb_ptr != NU_NULL)
{
/* Link the previous TCB and the new TCB together. */
prev_tcb_ptr -> sk_ready_next = new_tcb_ptr;
new_tcb_ptr -> sk_ready_prev = prev_tcb_ptr;
}
else
{
/* Update the ready list pointer and indicate that there has
been a change in the highest priority task. */
SKP_Ready_List_Ptr = new_tcb_ptr;
}
/* Mark this task as ready. */
new_tcb_ptr -> sk_suspend = NU_READY;
/* Make an entry in the history log showing that this task is
now ready. */
#if defined(NU_ENABLE_HISTORY)
if (SKP_In_Init == NU_FALSE)
DS_Make_History_Entry(NU_HIST_TASK_READY, task_id, 0);
#endif
/* Stop the task suspended timer and start the ready and waiting
timer. If timing is enabled. */
#if defined(NU_ENABLE_TIMING)
if (SKP_In_Init == NU_FALSE)
{
DS_Stop_Performance_Timer(task_id, NU_SUSPENSION_TIME_TIMER);
DS_Start_Performance_Timer(task_id, NU_READY_WAIT_TIME_TIMER);
}
#endif
/* Check for possible context switching. */
if ((SKP_Current_Task_ID != NU_SYSTEM) &&
(SKP_TCB_List[SKP_Current_Task_ID].sk_ready_prev != NU_NULL) &&
(SKP_TCB_List[SKP_Current_Task_ID].sk_no_preempt == NU_FALSE))
{
/* Preempt condition is present. */
preempt = NU_TRUE;
}
}
/* Return the preemption flag. */
return(preempt);
} /* end of SKP_Ready_Task */
/************************************************************************/
/* */
/* FUNCTION "SKP_Suspend_Task" */
/* */
/* */
/* DESCRIPTION */
/* */
/* This function removes the designated task from the ready list */
/* and links together any neighbors. If the task selected is */
/* the currently active task, control is transferred back to the */
/* executive. */
/* */
/* AUTHOR */
/* */
/* William E. Lamie, Accelerated Technology */
/* */
/* CALLED FROM */
/* */
/* Any nucleus routine that suspends a task. */
/* */
/* ROUTINES CALLED */
/* */
/* SKD_Leave_Task Leave this task */
/* DS_Make_History_Entry Make a history entry */
/* DS_Start_Performance_Timer Start a suspension timer */
/* */
/* INPUTS */
/* */
/* task_id Task to suspend */
/* suspend_type Type of suspension */
/* */
/* OUTPUTS */
/* */
/* Ready task list */
/* return(status) Status of request */
/* */
/************************************************************************/
signed int SKP_Suspend_Task(signed int task_id, unsigned int suspend_type)
{
struct SK_TASK_CONTROL_BLOCK_STRUCT
*next_tcb_ptr, /* Next tcb pointer */
*curr_tcb_ptr, /* Current tcb pointer */
*prev_tcb_ptr; /* Previous tcb pointer */
signed int status; /* Return status */
/* Setup pointer to the TCB. */
curr_tcb_ptr = &SKP_TCB_List[task_id];
/* Check the TCB to see if this task is really ready. */
if (curr_tcb_ptr -> sk_suspend == NU_READY)
{
/* Stop the task suspended timer and start the ready and waiting
timer. If timing is enabled. */
#if defined(NU_ENABLE_TIMING)
DS_Start_Performance_Timer(task_id, NU_SUSPENSION_TIME_TIMER);
#endif
/* Make an entry in the history log showing that this task is
now suspended. */
#if defined(NU_ENABLE_HISTORY)
DS_Make_History_Entry(NU_HIST_TASK_SUSPEND, task_id, suspend_type);
#endif
/* Point to the current TCB neighbors. */
prev_tcb_ptr = curr_tcb_ptr -> sk_ready_prev;
next_tcb_ptr = curr_tcb_ptr -> sk_ready_next;
/* Update the pointers of this TCBs neighbors. */
if (next_tcb_ptr != NU_NULL)
{
/* Make the next TCB point to this TCBs previous. */
next_tcb_ptr -> sk_ready_prev = prev_tcb_ptr;
}
if (prev_tcb_ptr != NU_NULL)
{
/* Make the previous TCB point to this task's next TCB. */
prev_tcb_ptr -> sk_ready_next = next_tcb_ptr;
}
else
{
/* There is no previous, hence we are deleting the first
TCB in the ready list. */
SKP_Ready_List_Ptr = next_tcb_ptr;
}
/* Reset the next and previous pointers of this
TCB and store the suspended value. */
curr_tcb_ptr -> sk_ready_next = NU_NULL;
curr_tcb_ptr -> sk_ready_prev = NU_NULL;
curr_tcb_ptr -> sk_suspend = suspend_type;
/* If the current task is the active task, leave this task and
transfer back to the executive. */
if (SKP_Current_Task_ID == curr_tcb_ptr -> sk_task_id)
{
/* Call "SKD_Leave_Task" to save this tasks information on the
stack in the proper format. */
SKD_Leave_Task();
}
/* show a successful status. */
status = NU_SUCCESS;
}
else
/* return an error status. */
status = NU_NOT_ACTIVE;
/* return status to the caller. */
return(status);
} /* end of SKP_Suspend_Task */
/************************************************************************/
/* */
/* FUNCTION "SKP_Move_To_End" */
/* */
/* */
/* DESCRIPTION */
/* */
/* This function is used to place the task at the end of all other */
/* tasks of the same priority on the ready list. This routine is */
/* invoked as a result of an application task relinquish or a time */
/* slice. */
/* */
/* AUTHOR */
/* */
/* William E. Lamie, Accelerated Technology */
/* */
/* CALLED FROM */
/* */
/* SKP_Time_Slice Nucleus time slice routine */
/* NU_Relinquish Nucleus routines */
/* */
/* ROUTINES CALLED */
/* */
/* None */
/* */
/* INPUTS */
/* */
/* SKP_Current_TCB_Ptr Current TCB pointer */
/* */
/* OUTPUTS */
/* */
/* Ready task list */
/* return(preempt) Preemption flag */
/* */
/************************************************************************/
signed int SKP_Move_To_End()
{
register struct SK_TASK_CONTROL_BLOCK_STRUCT
*prev_tcb_ptr, /* Previous tcb pointer */
*next_tcb_ptr, /* Next tcb pointer */
*curr_tcb_ptr; /* Current tcb pointer */
signed int preempt = NU_FALSE; /* Preempt flag */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -