📄 tcs.c
字号:
/* */
/* CALLED BY */
/* */
/* Application */
/* TCSE_Register_Signal_Handler Error checking shell */
/* */
/* CALLS */
/* */
/* [HIC_Make_History_Entry] Make entry in history log */
/* TCC_Signal_Shell Signal execution shell */
/* [TCT_Check_Stack] Stack checking function */
/* TCT_Protect Protect against other access */
/* TCT_Unprotect Release protection */
/* */
/* INPUTS */
/* */
/* signal_handler Signal execution shell */
/* */
/* OUTPUTS */
/* */
/* NU_SUCCESS */
/* */
/* HISTORY */
/* */
/* DATE REMARKS */
/* */
/* 03-01-1993 Created initial version 1.0 */
/* 04-19-1993 Verified version 1.0 */
/* 05-15-1993 Corrected problem with a comment */
/* 05-15-1993 Verified comment repair */
/* 03-01-1994 Added register optimizations, */
/* modified protection logic, */
/* resulting in version 1.1 */
/* */
/* 03-18-1994 Verified version 1.1 */
/* */
/*************************************************************************/
STATUS TCS_Register_Signal_Handler(VOID (*signal_handler)(UNSIGNED))
{
R1 TC_TCB *task; /* Task pointer */
#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_REGISTER_SIGNAL_HANDLER_ID,
(UNSIGNED) signal_handler, (UNSIGNED) 0, (UNSIGNED) 0);
#endif
/* Pickup the task pointer. */
task = (TC_TCB *) TCD_Current_Thread;
/* Protect against simultaneous access. */
TCT_Protect(&TCD_System_Protect);
/* Put the new signal handler in. */
task -> tc_signal_handler = signal_handler;
/* Now, determine if the signal handler needs to be invoked. */
if ((task -> tc_enabled_signals & task -> tc_signals) &&
(!task -> tc_signal_active) &&
(task -> tc_signal_handler))
{
/* Signal processing is required. */
/* Indicate that signal processing is in progress. */
task -> tc_signal_active = NU_TRUE;
/* Clear the saved stack pointer to indicate that this is an
in line signal handler call. */
task -> tc_saved_stack_ptr = NU_NULL;
/* Release protection from multiple access. */
TCT_Unprotect();
/* Call the signal handling shell. */
TCC_Signal_Shell();
}
else
/* Release protection. */
TCT_Unprotect();
/* Return success. */
return(NU_SUCCESS);
}
/*************************************************************************/
/* */
/* FUNCTION */
/* */
/* TCS_Send_Signals */
/* */
/* DESCRIPTION */
/* */
/* This function sends the specified task the specified signals. */
/* If enabled, the specified task is setup in order to process the */
/* signals. */
/* */
/* AUTHOR */
/* */
/* Accelerated Technology, Inc. */
/* */
/* CALLED BY */
/* */
/* Application */
/* TCSE_Send_Signals Error checking shell */
/* */
/* CALLS */
/* */
/* [HIC_Make_History_Entry] Make entry in history log */
/* TCC_Resume_Task Resume task that is suspended*/
/* TCC_Signal_Shell Signal execution shell */
/* TCT_Build_Signal_Frame Build a signal frame */
/* [TCT_Check_Stack] Stack checking function */
/* TCT_Control_To_System Control to system */
/* TCT_Protect Protect against other access */
/* TCT_Unprotect Release protection */
/* */
/* INPUTS */
/* */
/* task_ptr Task pointer */
/* signals Signals to send to the task */
/* */
/* OUTPUTS */
/* */
/* NU_SUCCESS */
/* */
/* 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 */
/* 04-04-1996 On line 995, changed tc_signals */
/* to tc_enabled_signals, */
/* resulting in version 1.1+ */
/* (spr 107) */
/* */
/*************************************************************************/
STATUS TCS_Send_Signals(NU_TASK *task_ptr, UNSIGNED signals)
{
R1 TC_TCB *task; /* Task control block ptr */
/* Move input 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_SEND_SIGNALS_ID, (UNSIGNED) signals,
(UNSIGNED) 0, (UNSIGNED) 0);
#endif
/* Protect against simultaneous access. */
TCT_Protect(&TCD_System_Protect);
/* Or the new signals into the current signals. */
task -> tc_signals = task -> tc_signals | signals;
#ifdef INCLUDE_PROVIEW
_RTProf_DumpTask(task,RT_PROF_SEND_SIGNALS);
#endif
/* Now, determine if the signal handler needs to be invoked. */
if ((task -> tc_signals & task -> tc_enabled_signals) &&
(!task -> tc_signal_active) &&
(task -> tc_status != NU_TERMINATED) &&
(task -> tc_status != NU_FINISHED) &&
(task -> tc_signal_handler))
{
/* Indicate that signal processing is in progress. */
task -> tc_signal_active = NU_TRUE;
/* Signal processing is required. Determine if the task is sending
signals to itself or if the calling thread is not the current
task. */
if (task == (TC_TCB *) TCD_Current_Thread)
{
/* Task sending signals to itself. */
/* Clear the saved stack pointer to indicate that this is an
in line signal handler call. */
task -> tc_saved_stack_ptr = NU_NULL;
/* Release protection from multiple access. */
TCT_Unprotect();
/* Call the signal handling shell. */
TCC_Signal_Shell();
}
else
{
/* Target task must be prepared to receive the signals. */
/* First, insure that the target task is not in a protected
area. */
do
{
/* Check for protection. Remember that protection is still
in effect. */
if (task -> tc_current_protect)
{
/* Yes, target task is in a protected mode. Release
the protection on the scheduling list and transfer
control briefly to the target task. */
TCT_Unprotect();
/* Switch to the protected task and wait until the
task is not protected. */
TCT_Protect_Switch(task);
/* Restore protection on the scheduling structures. */
TCT_Protect(&TCD_System_Protect);
}
} while (task -> tc_current_protect);
/* Copy the current status and stack pointer to the signal save
areas. */
task -> tc_saved_status = task -> tc_status;
task -> tc_saved_stack_ptr = task -> tc_stack_pointer;
/* Build a stack frame for the signal handling shell function. */
TCT_Build_Signal_Frame(task);
/* Determine if the target task is currently suspended. If it is
suspended for any other reason than a pure suspend, resume
it. */
if ((task -> tc_status != NU_READY) &&
(task -> tc_status != NU_PURE_SUSPEND))
{
/* Resume the target task and check for preemption. */
if (TCC_Resume_Task(task_ptr, task -> tc_status))
/* Preemption needs to take place. */
TCT_Control_To_System();
}
}
}
/* Release protection, no signals are currently enabled. */
TCT_Unprotect();
/* Return a successful status. */
return(NU_SUCCESS);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -