📄 tcs.c
字号:
/*************************************************************************/
/* */
/* Copyright (c) 1993-2001 Accelerated Technology, Inc. */
/* */
/* PROPRIETARY RIGHTS of Accelerated Technology are involved in the */
/* subject matter of this material. All manufacturing, reproduction, */
/* use, and sales rights pertaining to this subject matter are governed */
/* by the license agreement. The recipient of this software implicitly */
/* accepts the terms of the license. */
/* */
/*************************************************************************/
/*************************************************************************/
/* */
/* FILE NAME VERSION */
/* */
/* tcs.c PLUS 1.13 */
/* */
/* COMPONENT */
/* */
/* TC - Thread Control */
/* */
/* DESCRIPTION */
/* */
/* This file contains supplemental routines for the Thread Control */
/* component. */
/* */
/* AUTHOR */
/* */
/* Accelerated Technology, Inc. */
/* */
/* DATA STRUCTURES */
/* */
/* None */
/* */
/* FUNCTIONS */
/* */
/* TCS_Change_Priority Change task's priority */
/* TCS_Change_Preemption Change task's preemption */
/* TCS_Change_Time_Slice Change task's time-slice */
/* TCS_Control_Signals Control signals */
/* TCS_Receive_Signals Receive signals */
/* TCS_Register_Signal_Handler Register signal handler */
/* TCS_Send_Signals Send signals to a task */
/* */
/* */
/* DEPENDENCIES */
/* */
/* cs_extr.h Common Service functions */
/* tc_extr.h Thread Control functions */
/* in_extr.h Initialization/Interrupt */
/* functions */
/* tm_extr.h Timer Control function */
/* er_extr.h Error handling function */
/* hi_extr.h History functions */
/* */
/* HISTORY */
/* */
/* DATE REMARKS */
/* */
/* 03-01-1994 Created initial version 1.1 from */
/* previous version of TCC.C */
/* */
/* 03-18-1994 Verified version 1.1 */
/* 04-04-1996 Modified TCS_Send_Signals, */
/* resulting in version 1.1+ */
/* (spr 107) */
/* 04-17-1996 updated to version 1.2 */
/* 03-24-1998 Released version 1.3. */
/* */
/*************************************************************************/
#define NU_SOURCE_FILE
#include "cs_extr.h" /* Common service functions */
#include "tc_extr.h" /* Thread control functions */
#include "in_extr.h" /* Initialization/Interrupt */
/* functions */
#include "tm_extr.h" /* Timer control functions */
#include "er_extr.h" /* Error handling function */
#include "hi_extr.h" /* History functions */
/* Define external inner-component global data references. */
extern CS_NODE *TCD_Created_Tasks_List;
extern TC_TCB *TCD_Priority_List[TC_PRIORITIES];
extern UNSIGNED TCD_Priority_Groups;
extern DATA_ELEMENT TCD_Sub_Priority_Groups[TC_MAX_GROUPS];
extern UNSIGNED_CHAR TCD_Lowest_Set_Bit[];
extern INT TCD_Highest_Priority;
extern TC_TCB *TCD_Execute_Task;
extern VOID *TCD_Current_Thread;
extern TC_PROTECT TCD_System_Protect;
extern INT TMD_Time_Slice_State;
/* Define external inner-component function calls that are not available to
other components. */
VOID TCT_Build_Signal_Frame(TC_TCB *task_ptr);
VOID TCT_Protect_Switch(TC_TCB *task);
VOID TCT_Signal_Exit(VOID);
/* Define internal function calls. */
VOID TCC_Signal_Shell(VOID);
/*************************************************************************/
/* */
/* FUNCTION */
/* */
/* TCS_Change_Priority */
/* */
/* DESCRIPTION */
/* */
/* This function changes the priority of the specified task. The */
/* priority of a suspended or a ready task can be changed. If the */
/* new priority necessitates a context switch, control is */
/* transferred back to the system. */
/* */
/* AUTHOR */
/* */
/* Accelerated Technology, Inc. */
/* */
/* CALLED BY */
/* */
/* Application */
/* TCSE_Change_Priority Error checking shell */
/* */
/* CALLS */
/* */
/* [HIC_Make_History_Entry] Make entry in history log */
/* [TCT_Check_Stack] Stack checking function */
/* TCT_Control_To_System Transfer control to system */
/* TCT_Protect Protect scheduling data */
/* TCT_Set_Execute_Task Set TCD_Execute_Task pointer */
/* TCT_Unprotect Release protection of data */
/* */
/* INPUTS */
/* */
/* task_ptr Task control block pointer */
/* new_priority New priority for task */
/* */
/* OUTPUTS */
/* */
/* old_priority Original task priority */
/* */
/* HISTORY */
/* */
/* DATE REMARKS */
/* */
/* 03-01-1993 Created initial version 1.0 */
/* 04-19-1993 Verified version 1.0 */
/* 03-01-1994 Modified function interface, */
/* added register optimizations, */
/* modified protection logic, */
/* resulting in version 1.1 */
/* */
/* 03-18-1994 Verified version 1.1 */
/* */
/* 10-4-1999 Bug fixes - return if new */
/* priority equals old priority */
/* and don't move the head pointer */
/* unless the head node is changing */
/*************************************************************************/
OPTION TCS_Change_Priority(NU_TASK *task_ptr, OPTION new_priority)
{
R1 TC_TCB *task; /* Task control block ptr */
R2 TC_TCB *head; /* Head list pointer */
R3 INT index; /* Working index variable */
OPTION old_priority; /* Previous priority of task */
DATA_ELEMENT temp; /* Temporary variable */
/* Move task control block pointer into internal pointer. */
task = (TC_TCB *) task_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_CHANGE_PRIORITY_ID, (UNSIGNED) task,
(UNSIGNED) new_priority, (UNSIGNED) 0);
#endif
/* Protect against multiple access to the scheduling list. */
TCT_Protect(&TCD_System_Protect);
/* Save the old priority of the task. */
old_priority = task -> tc_priority;
/* BUG FIX this should probably go into an error checking routine instead of here */
if (!(task -> tc_priority == new_priority))
{
/* Check to see if the task is currently ready. */
if (task -> tc_status == NU_READY)
{
/* Remove the task from the ready list. */
/* Determine if the task is the only one on the list. */
if (task -> tc_ready_next == task)
{
/* Only task on the list. Clear the task's pointers and
clear the entry in the priority table. */
task -> tc_ready_next = NU_NULL;
task -> tc_ready_previous = NU_NULL;
*(task -> tc_priority_head) = NU_NULL;
/* Clear the sub-priority group. */
*(task -> tc_sub_priority_ptr) =
*(task -> tc_sub_priority_ptr) & ~(task -> tc_sub_priority);
/* Determine if the main priority group needs to be cleared.
This is only true if there are no other bits set in this
sub-priority. */
if (*(task -> tc_sub_priority_ptr) == 0)
/* Clear the main priority group bit. */
TCD_Priority_Groups =
TCD_Priority_Groups & ~(task -> tc_priority_group);
}
else
{
/* Not the only task ready at the same priority level. */
/* Remove from the linked-list. */
(task -> tc_ready_previous) -> tc_ready_next =
task -> tc_ready_next;
(task -> tc_ready_next) -> tc_ready_previous =
task -> tc_ready_previous;
/* Update the head pointer. */
/* BUG FIX - update head if head is changing priority - leave
it alone otherwise! */
if(*(task -> tc_priority_head) == task )
*(task -> tc_priority_head) = task -> tc_ready_next;
/* Clear the next and previous pointers. */
task -> tc_ready_next = NU_NULL;
task -> tc_ready_previous = NU_NULL;
}
/* Now add in the task at the new priority. */
task -> tc_priority = new_priority;
/* Build the other priority information. */
task -> tc_priority = new_priority;
task -> tc_priority_head = &(TCD_Priority_List[new_priority]);
task -> tc_sub_priority = (DATA_ELEMENT) (1 << (new_priority & 7));
task -> tc_priority_group = ((UNSIGNED) 1) << (new_priority >> 3);
task -> tc_sub_priority_ptr =
&(TCD_Sub_Priority_Groups[(new_priority >> 3)]);
#ifdef INCLUDE_PROVIEW
_RTProf_DumpTask(task,RT_PROF_CHANGE_PRIORITY);
#endif
/* Link the task into the new priority list. */
head = *(task -> tc_priority_head);
/* Determine if the list is non-empty. */
if (head)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -