FreeCalypso > hg > ffs-editor
comparison src/nucleus/tcs.c @ 0:92470e5d0b9e
src: partial import from FC Selenite
| author | Mychaela Falconia <falcon@freecalypso.org> |
|---|---|
| date | Fri, 15 May 2020 01:28:16 +0000 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:92470e5d0b9e |
|---|---|
| 1 /*************************************************************************/ | |
| 2 /* */ | |
| 3 /* Copyright Mentor Graphics Corporation 2002 */ | |
| 4 /* All Rights Reserved. */ | |
| 5 /* */ | |
| 6 /* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ | |
| 7 /* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ | |
| 8 /* SUBJECT TO LICENSE TERMS. */ | |
| 9 /* */ | |
| 10 /*************************************************************************/ | |
| 11 | |
| 12 /*************************************************************************/ | |
| 13 /* */ | |
| 14 /* FILE NAME VERSION */ | |
| 15 /* */ | |
| 16 /* tcs.c Nucleus PLUS 1.14 */ | |
| 17 /* */ | |
| 18 /* COMPONENT */ | |
| 19 /* */ | |
| 20 /* TC - Thread Control */ | |
| 21 /* */ | |
| 22 /* DESCRIPTION */ | |
| 23 /* */ | |
| 24 /* This file contains supplemental routines for the Thread Control */ | |
| 25 /* component. */ | |
| 26 /* */ | |
| 27 /* DATA STRUCTURES */ | |
| 28 /* */ | |
| 29 /* None */ | |
| 30 /* */ | |
| 31 /* FUNCTIONS */ | |
| 32 /* */ | |
| 33 /* TCS_Change_Priority Change task's priority */ | |
| 34 /* TCS_Change_Preemption Change task's preemption */ | |
| 35 /* TCS_Change_Time_Slice Change task's time-slice */ | |
| 36 /* TCS_Control_Signals Control signals */ | |
| 37 /* TCS_Receive_Signals Receive signals */ | |
| 38 /* TCS_Register_Signal_Handler Register signal handler */ | |
| 39 /* TCS_Send_Signals Send signals to a task */ | |
| 40 /* */ | |
| 41 /* */ | |
| 42 /* DEPENDENCIES */ | |
| 43 /* */ | |
| 44 /* cs_extr.h Common Service functions */ | |
| 45 /* tc_extr.h Thread Control functions */ | |
| 46 /* in_extr.h Initialization/Interrupt */ | |
| 47 /* functions */ | |
| 48 /* tm_extr.h Timer Control function */ | |
| 49 /* er_extr.h Error handling function */ | |
| 50 /* hi_extr.h History functions */ | |
| 51 /* */ | |
| 52 /* HISTORY */ | |
| 53 /* */ | |
| 54 /* DATE REMARKS */ | |
| 55 /* */ | |
| 56 /* 03-01-1994 Created initial version 1.1 from */ | |
| 57 /* previous version of TCC.C */ | |
| 58 /* */ | |
| 59 /* 03-18-1994 Verified version 1.1 */ | |
| 60 /* 04-04-1996 Modified TCS_Send_Signals, */ | |
| 61 /* resulting in version 1.1+ */ | |
| 62 /* (spr 107) */ | |
| 63 /* 04-17-1996 updated to version 1.2 */ | |
| 64 /* 03-24-1998 Released version 1.3. */ | |
| 65 /* 03-26-1999 Released 1.11m (new release */ | |
| 66 /* numbering scheme) */ | |
| 67 /* 04-17-2002 Released version 1.13m */ | |
| 68 /* 11-07-2002 Released version 1.14 */ | |
| 69 /*************************************************************************/ | |
| 70 #define NU_SOURCE_FILE | |
| 71 | |
| 72 | |
| 73 #include "cs_extr.h" /* Common service functions */ | |
| 74 #include "tc_extr.h" /* Thread control functions */ | |
| 75 #include "in_extr.h" /* Initialization/Interrupt */ | |
| 76 /* functions */ | |
| 77 #include "tm_extr.h" /* Timer control functions */ | |
| 78 #include "er_extr.h" /* Error handling function */ | |
| 79 #include "hi_extr.h" /* History functions */ | |
| 80 #include "profiler.h" /* ProView interface */ | |
| 81 | |
| 82 | |
| 83 /* Define external inner-component global data references. */ | |
| 84 | |
| 85 extern CS_NODE *TCD_Created_Tasks_List; | |
| 86 extern TC_TCB *TCD_Priority_List[TC_PRIORITIES]; | |
| 87 extern UNSIGNED TCD_Priority_Groups; | |
| 88 extern DATA_ELEMENT TCD_Sub_Priority_Groups[TC_MAX_GROUPS]; | |
| 89 extern UNSIGNED_CHAR TCD_Lowest_Set_Bit[]; | |
| 90 extern INT TCD_Highest_Priority; | |
| 91 extern TC_TCB *TCD_Execute_Task; | |
| 92 extern VOID *TCD_Current_Thread; | |
| 93 extern TC_PROTECT TCD_System_Protect; | |
| 94 extern INT TMD_Time_Slice_State; | |
| 95 | |
| 96 | |
| 97 | |
| 98 /* Define external inner-component function calls that are not available to | |
| 99 other components. */ | |
| 100 | |
| 101 VOID TCT_Build_Signal_Frame(TC_TCB *task_ptr); | |
| 102 VOID TCT_Protect_Switch(TC_TCB *task); | |
| 103 VOID TCT_Signal_Exit(VOID); | |
| 104 | |
| 105 | |
| 106 /* Define internal function calls. */ | |
| 107 | |
| 108 VOID TCC_Signal_Shell(VOID); | |
| 109 | |
| 110 | |
| 111 /*************************************************************************/ | |
| 112 /* */ | |
| 113 /* FUNCTION */ | |
| 114 /* */ | |
| 115 /* TCS_Change_Priority */ | |
| 116 /* */ | |
| 117 /* DESCRIPTION */ | |
| 118 /* */ | |
| 119 /* This function changes the priority of the specified task. The */ | |
| 120 /* priority of a suspended or a ready task can be changed. If the */ | |
| 121 /* new priority necessitates a context switch, control is */ | |
| 122 /* transferred back to the system. */ | |
| 123 /* */ | |
| 124 /* CALLED BY */ | |
| 125 /* */ | |
| 126 /* Application */ | |
| 127 /* TCSE_Change_Priority Error checking shell */ | |
| 128 /* */ | |
| 129 /* CALLS */ | |
| 130 /* */ | |
| 131 /* [HIC_Make_History_Entry] Make entry in history log */ | |
| 132 /* [TCT_Check_Stack] Stack checking function */ | |
| 133 /* TCT_Control_To_System Transfer control to system */ | |
| 134 /* TCT_Protect Protect scheduling data */ | |
| 135 /* TCT_Set_Execute_Task Set TCD_Execute_Task pointer */ | |
| 136 /* TCT_Unprotect Release protection of data */ | |
| 137 /* */ | |
| 138 /* INPUTS */ | |
| 139 /* */ | |
| 140 /* task_ptr Task control block pointer */ | |
| 141 /* new_priority New priority for task */ | |
| 142 /* */ | |
| 143 /* OUTPUTS */ | |
| 144 /* */ | |
| 145 /* old_priority Original task priority */ | |
| 146 /* */ | |
| 147 /* HISTORY */ | |
| 148 /* */ | |
| 149 /* DATE REMARKS */ | |
| 150 /* */ | |
| 151 /* 03-01-1993 Created initial version 1.0 */ | |
| 152 /* 04-19-1993 Verified version 1.0 */ | |
| 153 /* 03-01-1994 Modified function interface, */ | |
| 154 /* added register optimizations, */ | |
| 155 /* modified protection logic, */ | |
| 156 /* resulting in version 1.1 */ | |
| 157 /* */ | |
| 158 /* 03-18-1994 Verified version 1.1 */ | |
| 159 /* */ | |
| 160 /* 10-4-1999 Bug fixes - return if new */ | |
| 161 /* priority equals old priority */ | |
| 162 /* and don't move the head pointer */ | |
| 163 /* unless the head node is changing */ | |
| 164 /*************************************************************************/ | |
| 165 OPTION TCS_Change_Priority(NU_TASK *task_ptr, OPTION new_priority) | |
| 166 { | |
| 167 | |
| 168 R1 TC_TCB *task; /* Task control block ptr */ | |
| 169 R2 TC_TCB *head; /* Head list pointer */ | |
| 170 R3 INT index; /* Working index variable */ | |
| 171 OPTION old_priority; /* Previous priority of task */ | |
| 172 DATA_ELEMENT temp; /* Temporary variable */ | |
| 173 NU_SUPERV_USER_VARIABLES | |
| 174 | |
| 175 /* Switch to supervisor mode */ | |
| 176 NU_SUPERVISOR_MODE(); | |
| 177 | |
| 178 /* Move task control block pointer into internal pointer. */ | |
| 179 task = (TC_TCB *) task_ptr; | |
| 180 | |
| 181 | |
| 182 #ifdef NU_ENABLE_STACK_CHECK | |
| 183 | |
| 184 /* Call stack checking function to check for an overflow condition. */ | |
| 185 TCT_Check_Stack(); | |
| 186 | |
| 187 #endif | |
| 188 | |
| 189 #ifdef NU_ENABLE_HISTORY | |
| 190 | |
| 191 /* Make an entry that corresponds to this function in the system history | |
| 192 log. */ | |
| 193 HIC_Make_History_Entry(NU_CHANGE_PRIORITY_ID, (UNSIGNED) task, | |
| 194 (UNSIGNED) new_priority, (UNSIGNED) 0); | |
| 195 | |
| 196 #endif | |
| 197 | |
| 198 /* Protect against multiple access to the scheduling list. */ | |
| 199 TCT_Protect(&TCD_System_Protect); | |
| 200 | |
| 201 /* Save the old priority of the task. */ | |
| 202 old_priority = task -> tc_priority; | |
| 203 | |
| 204 | |
| 205 /* BUG FIX this should probably go into an error checking routine instead of here */ | |
| 206 if (!(task -> tc_priority == new_priority)) | |
| 207 { | |
| 208 | |
| 209 | |
| 210 /* Check to see if the task is currently ready. */ | |
| 211 if (task -> tc_status == NU_READY) | |
| 212 { | |
| 213 | |
| 214 /* Remove the task from the ready list. */ | |
| 215 | |
| 216 /* Determine if the task is the only one on the list. */ | |
| 217 if (task -> tc_ready_next == task) | |
| 218 { | |
| 219 | |
| 220 /* Only task on the list. Clear the task's pointers and | |
| 221 clear the entry in the priority table. */ | |
| 222 task -> tc_ready_next = NU_NULL; | |
| 223 task -> tc_ready_previous = NU_NULL; | |
| 224 *(task -> tc_priority_head) = NU_NULL; | |
| 225 | |
| 226 /* Clear the sub-priority group. */ | |
| 227 *(task -> tc_sub_priority_ptr) = | |
| 228 *(task -> tc_sub_priority_ptr) & ~(task -> tc_sub_priority); | |
| 229 | |
| 230 /* Determine if the main priority group needs to be cleared. | |
| 231 This is only true if there are no other bits set in this | |
| 232 sub-priority. */ | |
| 233 if (*(task -> tc_sub_priority_ptr) == 0) | |
| 234 | |
| 235 /* Clear the main priority group bit. */ | |
| 236 TCD_Priority_Groups = | |
| 237 TCD_Priority_Groups & ~(task -> tc_priority_group); | |
| 238 } | |
| 239 else | |
| 240 { | |
| 241 | |
| 242 /* Not the only task ready at the same priority level. */ | |
| 243 | |
| 244 /* Remove from the linked-list. */ | |
| 245 (task -> tc_ready_previous) -> tc_ready_next = | |
| 246 task -> tc_ready_next; | |
| 247 (task -> tc_ready_next) -> tc_ready_previous = | |
| 248 task -> tc_ready_previous; | |
| 249 | |
| 250 | |
| 251 | |
| 252 /* Update the head pointer. */ | |
| 253 /* BUG FIX - update head if head is changing priority - leave | |
| 254 it alone otherwise! */ | |
| 255 if(*(task -> tc_priority_head) == task ) | |
| 256 *(task -> tc_priority_head) = task -> tc_ready_next; | |
| 257 | |
| 258 /* Clear the next and previous pointers. */ | |
| 259 task -> tc_ready_next = NU_NULL; | |
| 260 task -> tc_ready_previous = NU_NULL; | |
| 261 } | |
| 262 | |
| 263 /* Now add in the task at the new priority. */ | |
| 264 task -> tc_priority = new_priority; | |
| 265 | |
| 266 /* Build the other priority information. */ | |
| 267 task -> tc_priority = new_priority; | |
| 268 task -> tc_priority_head = &(TCD_Priority_List[new_priority]); | |
| 269 task -> tc_sub_priority = (DATA_ELEMENT) (1 << (new_priority & 7)); | |
| 270 task -> tc_priority_group = ((UNSIGNED) 1) << (new_priority >> 3); | |
| 271 task -> tc_sub_priority_ptr = | |
| 272 &(TCD_Sub_Priority_Groups[(new_priority >> 3)]); | |
| 273 | |
| 274 #ifdef INCLUDE_PROVIEW | |
| 275 _RTProf_DumpTask(task,RT_PROF_CHANGE_PRIORITY); | |
| 276 #endif | |
| 277 /* Link the task into the new priority list. */ | |
| 278 head = *(task -> tc_priority_head); | |
| 279 | |
| 280 /* Determine if the list is non-empty. */ | |
| 281 if (head) | |
| 282 { | |
| 283 | |
| 284 /* Add the TCB to the end of the ready list. */ | |
| 285 task -> tc_ready_previous = head -> tc_ready_previous; | |
| 286 (task -> tc_ready_previous) -> tc_ready_next = task; | |
| 287 task -> tc_ready_next = head; | |
| 288 (task -> tc_ready_next) -> tc_ready_previous = task; | |
| 289 | |
| 290 /* Note that the priority bit map does not need to be | |
| 291 modified since there are other active tasks at the | |
| 292 same priority. */ | |
| 293 } | |
| 294 else | |
| 295 { | |
| 296 | |
| 297 /* Add the TCB to an empty list. */ | |
| 298 task -> tc_ready_previous = task; | |
| 299 task -> tc_ready_next = task; | |
| 300 *(task -> tc_priority_head)= task; | |
| 301 | |
| 302 /* Update the priority group bit map to indicate that this | |
| 303 priority now has a task ready. */ | |
| 304 TCD_Priority_Groups = | |
| 305 TCD_Priority_Groups | (task -> tc_priority_group); | |
| 306 | |
| 307 /* Update the sub-priority bit map to show that this priority | |
| 308 is ready. */ | |
| 309 *(task -> tc_sub_priority_ptr) = | |
| 310 (*(task -> tc_sub_priority_ptr)) | task -> tc_sub_priority; | |
| 311 } | |
| 312 | |
| 313 /* Determine the highest priority task in the system. */ | |
| 314 if (TCD_Priority_Groups & TC_HIGHEST_MASK) | |
| 315 | |
| 316 /* Base of sub-group is 0. */ | |
| 317 index = 0; | |
| 318 | |
| 319 else if (TCD_Priority_Groups & TC_NEXT_HIGHEST_MASK) | |
| 320 | |
| 321 /* Base of sub-group is 8. */ | |
| 322 index = 8; | |
| 323 | |
| 324 else if (TCD_Priority_Groups & TC_NEXT_LOWEST_MASK) | |
| 325 | |
| 326 /* Base of sub-group is 16. */ | |
| 327 index = 16; | |
| 328 else | |
| 329 | |
| 330 /* Base of sub-group is 24. */ | |
| 331 index = 24; | |
| 332 | |
| 333 /* Calculate the highest available priority. */ | |
| 334 index = index + TCD_Lowest_Set_Bit[(INT) | |
| 335 ((TCD_Priority_Groups >> index) & TC_HIGHEST_MASK)]; | |
| 336 | |
| 337 /* Get the mask of the priority within the group of 8 priorities. */ | |
| 338 temp = TCD_Sub_Priority_Groups[index]; | |
| 339 | |
| 340 /* Calculate the actual priority. */ | |
| 341 TCD_Highest_Priority = (index << 3) + TCD_Lowest_Set_Bit[temp]; | |
| 342 | |
| 343 /* Check for preemption. */ | |
| 344 if ((TCD_Highest_Priority <= ((INT) TCD_Execute_Task -> tc_priority)) | |
| 345 && (TCD_Execute_Task -> tc_preemption)) | |
| 346 { | |
| 347 | |
| 348 /* Update the current task pointer. */ | |
| 349 TCT_Set_Execute_Task(TCD_Priority_List[TCD_Highest_Priority]); | |
| 350 | |
| 351 /* Now, check and see if the current thread is a task. | |
| 352 If so, return a status that indicates a context | |
| 353 switch is needed. */ | |
| 354 if ((TCD_Current_Thread) && | |
| 355 (((TC_TCB *) TCD_Current_Thread) -> tc_id == TC_TASK_ID)) | |
| 356 | |
| 357 /* Transfer control to the system. */ | |
| 358 TCT_Control_To_System(); | |
| 359 } | |
| 360 } | |
| 361 else | |
| 362 { | |
| 363 | |
| 364 /* Just modify the priority. */ | |
| 365 task -> tc_priority = new_priority; | |
| 366 | |
| 367 /* Build the other priority information. */ | |
| 368 task -> tc_priority = new_priority; | |
| 369 task -> tc_priority_head = &(TCD_Priority_List[new_priority]); | |
| 370 task -> tc_sub_priority = (DATA_ELEMENT) (1 << (new_priority & 7)); | |
| 371 task -> tc_priority_group = ((UNSIGNED) 1) << (new_priority >> 3); | |
| 372 task -> tc_sub_priority_ptr = | |
| 373 &(TCD_Sub_Priority_Groups[(new_priority >> 3)]); | |
| 374 } | |
| 375 #ifdef INCLUDE_PROVIEW | |
| 376 _RTProf_DumpTask(task,RT_PROF_CHANGE_PRIORITY); | |
| 377 #endif | |
| 378 } | |
| 379 | |
| 380 /* Release the protection of the scheduling list. */ | |
| 381 TCT_Unprotect(); | |
| 382 | |
| 383 /* Return to user mode */ | |
| 384 NU_USER_MODE(); | |
| 385 | |
| 386 /* Return the old priority. */ | |
| 387 return(old_priority); | |
| 388 } | |
| 389 | |
| 390 | |
| 391 /*************************************************************************/ | |
| 392 /* */ | |
| 393 /* FUNCTION */ | |
| 394 /* */ | |
| 395 /* TCS_Change_Preemption */ | |
| 396 /* */ | |
| 397 /* DESCRIPTION */ | |
| 398 /* */ | |
| 399 /* This function changes the preemption posture of the calling */ | |
| 400 /* task. Preemption for a task may be enabled or disabled. If */ | |
| 401 /* it is disabled, the task runs until it suspends or relinquishes. */ | |
| 402 /* If a preemption is pending, a call to this function to enable */ | |
| 403 /* preemption causes a context switch. */ | |
| 404 /* */ | |
| 405 /* CALLED BY */ | |
| 406 /* */ | |
| 407 /* Application */ | |
| 408 /* TCSE_Change_Preemption Error checking function */ | |
| 409 /* */ | |
| 410 /* CALLS */ | |
| 411 /* */ | |
| 412 /* [HIC_Make_History_Entry] Make entry in history log */ | |
| 413 /* [TCT_Check_Stack] Stack checking function */ | |
| 414 /* TCT_Control_To_System Transfer control to system */ | |
| 415 /* TCT_Protect Protect scheduling info */ | |
| 416 /* TCT_Set_Execute_Task Set TCD_Execute_Task pointer */ | |
| 417 /* TCT_Unprotect Release protection of info */ | |
| 418 /* */ | |
| 419 /* INPUTS */ | |
| 420 /* */ | |
| 421 /* preempt Preempt selection parameter */ | |
| 422 /* */ | |
| 423 /* OUTPUTS */ | |
| 424 /* */ | |
| 425 /* old_preempt Original preempt value */ | |
| 426 /* */ | |
| 427 /* HISTORY */ | |
| 428 /* */ | |
| 429 /* DATE REMARKS */ | |
| 430 /* */ | |
| 431 /* 03-01-1993 Created initial version 1.0 */ | |
| 432 /* 04-19-1993 Verified version 1.0 */ | |
| 433 /* 03-01-1994 Modified protection logic, */ | |
| 434 /* resulting in version 1.1 */ | |
| 435 /* */ | |
| 436 /* 03-18-1994 Verified version 1.1 */ | |
| 437 /* */ | |
| 438 /*************************************************************************/ | |
| 439 OPTION TCS_Change_Preemption(OPTION preempt) | |
| 440 { | |
| 441 | |
| 442 TC_TCB *task; /* Pointer to task */ | |
| 443 OPTION old_preempt; | |
| 444 NU_SUPERV_USER_VARIABLES | |
| 445 | |
| 446 /* Switch to supervisor mode */ | |
| 447 NU_SUPERVISOR_MODE(); | |
| 448 | |
| 449 #ifdef NU_ENABLE_STACK_CHECK | |
| 450 | |
| 451 /* Call stack checking function to check for an overflow condition. */ | |
| 452 TCT_Check_Stack(); | |
| 453 | |
| 454 #endif | |
| 455 | |
| 456 #ifdef NU_ENABLE_HISTORY | |
| 457 | |
| 458 /* Make an entry that corresponds to this function in the system history | |
| 459 log. */ | |
| 460 HIC_Make_History_Entry(NU_CHANGE_PREEMPTION_ID, (UNSIGNED) preempt, | |
| 461 (UNSIGNED) 0, (UNSIGNED) 0); | |
| 462 | |
| 463 #endif | |
| 464 | |
| 465 /* Protect the scheduling information. */ | |
| 466 TCT_Protect(&TCD_System_Protect); | |
| 467 | |
| 468 /* Pickup the current thread and place it in the task pointer. */ | |
| 469 task = (TC_TCB *) TCD_Current_Thread; | |
| 470 | |
| 471 /* Save the old preempt value. */ | |
| 472 if (task -> tc_preemption) | |
| 473 | |
| 474 /* Previously enabled. */ | |
| 475 old_preempt = NU_PREEMPT; | |
| 476 else | |
| 477 | |
| 478 /* Previously disabled. */ | |
| 479 old_preempt = NU_NO_PREEMPT; | |
| 480 | |
| 481 /* Process the new value. */ | |
| 482 if (preempt == NU_NO_PREEMPT) | |
| 483 | |
| 484 /* Disable preemption. */ | |
| 485 TCD_Execute_Task -> tc_preemption = NU_FALSE; | |
| 486 else | |
| 487 { | |
| 488 | |
| 489 /* Enable preemption. */ | |
| 490 task -> tc_preemption = NU_TRUE; | |
| 491 | |
| 492 /* Check for a preemption condition. */ | |
| 493 if ((task == TCD_Execute_Task) && | |
| 494 (TCD_Highest_Priority < ((INT) TCD_Execute_Task -> tc_priority))) | |
| 495 { | |
| 496 | |
| 497 /* Preempt the current task. */ | |
| 498 TCT_Set_Execute_Task(TCD_Priority_List[TCD_Highest_Priority]); | |
| 499 | |
| 500 /* Transfer control to the system. */ | |
| 501 TCT_Control_To_System(); | |
| 502 } | |
| 503 } | |
| 504 | |
| 505 #ifdef INCLUDE_PROVIEW | |
| 506 _RTProf_DumpTask(task,RT_PROF_CHANGE_PREEMPTION); | |
| 507 #endif | |
| 508 | |
| 509 /* Release protection of information. */ | |
| 510 TCT_Unprotect(); | |
| 511 | |
| 512 /* Return to user mode */ | |
| 513 NU_USER_MODE(); | |
| 514 | |
| 515 /* Return the previous preemption posture. */ | |
| 516 return(old_preempt); | |
| 517 } | |
| 518 | |
| 519 | |
| 520 /*************************************************************************/ | |
| 521 /* */ | |
| 522 /* FUNCTION */ | |
| 523 /* */ | |
| 524 /* TCS_Change_Time_Slice */ | |
| 525 /* */ | |
| 526 /* DESCRIPTION */ | |
| 527 /* */ | |
| 528 /* This function changes the time slice of the specified task. A */ | |
| 529 /* time slice value of 0 disables time slicing. */ | |
| 530 /* */ | |
| 531 /* CALLED BY */ | |
| 532 /* */ | |
| 533 /* Application */ | |
| 534 /* TCES_Change_Preemption Error checking function */ | |
| 535 /* */ | |
| 536 /* CALLS */ | |
| 537 /* */ | |
| 538 /* [HIC_Make_History_Entry] Make entry in history log */ | |
| 539 /* [TCT_Check_Stack] Stack checking function */ | |
| 540 /* TCT_Protect Protect scheduling info */ | |
| 541 /* TCT_Unprotect Release protection of info */ | |
| 542 /* */ | |
| 543 /* INPUTS */ | |
| 544 /* */ | |
| 545 /* task_ptr Task control block pointer */ | |
| 546 /* time_slice New time slice value */ | |
| 547 /* */ | |
| 548 /* OUTPUTS */ | |
| 549 /* */ | |
| 550 /* old_time_slice Original time slice value */ | |
| 551 /* */ | |
| 552 /* HISTORY */ | |
| 553 /* */ | |
| 554 /* DATE REMARKS */ | |
| 555 /* */ | |
| 556 /* 03-01-1993 Created initial version 1.0 */ | |
| 557 /* 04-19-1993 Verified version 1.0 */ | |
| 558 /* 03-01-1994 Modified function interface, */ | |
| 559 /* added register optimizations, */ | |
| 560 /* modified protection logic, */ | |
| 561 /* resulting in version 1.1 */ | |
| 562 /* */ | |
| 563 /* 03-18-1994 Verified version 1.1 */ | |
| 564 /* */ | |
| 565 /*************************************************************************/ | |
| 566 UNSIGNED TCS_Change_Time_Slice(NU_TASK *task_ptr, UNSIGNED time_slice) | |
| 567 { | |
| 568 | |
| 569 TC_TCB *task; /* Task control block ptr */ | |
| 570 UNSIGNED old_time_slice; /* Old time slice value */ | |
| 571 NU_SUPERV_USER_VARIABLES | |
| 572 | |
| 573 /* Switch to supervisor mode */ | |
| 574 NU_SUPERVISOR_MODE(); | |
| 575 | |
| 576 /* Move input task control block pointer into internal pointer. */ | |
| 577 task = (TC_TCB *) task_ptr; | |
| 578 | |
| 579 | |
| 580 #ifdef NU_ENABLE_STACK_CHECK | |
| 581 | |
| 582 /* Call stack checking function to check for an overflow condition. */ | |
| 583 TCT_Check_Stack(); | |
| 584 | |
| 585 #endif | |
| 586 | |
| 587 #ifdef NU_ENABLE_HISTORY | |
| 588 | |
| 589 /* Make an entry that corresponds to this function in the system history | |
| 590 log. */ | |
| 591 HIC_Make_History_Entry(NU_CHANGE_TIME_SLICE_ID, (UNSIGNED) task, | |
| 592 (UNSIGNED) time_slice, (UNSIGNED) 0); | |
| 593 | |
| 594 #endif | |
| 595 | |
| 596 /* Protect the scheduling information. */ | |
| 597 TCT_Protect(&TCD_System_Protect); | |
| 598 | |
| 599 /* Save the old time slice value. */ | |
| 600 old_time_slice = task -> tc_time_slice; | |
| 601 | |
| 602 /* Store the new time slice value. */ | |
| 603 task -> tc_time_slice = time_slice; | |
| 604 task -> tc_cur_time_slice = time_slice; | |
| 605 | |
| 606 /* Bug fix. Let the system know we have started a new time slice */ | |
| 607 TMD_Time_Slice_State = TM_ACTIVE; | |
| 608 | |
| 609 #ifdef INCLUDE_PROVIEW | |
| 610 _RTProf_DumpTask(task,RT_PROF_CHANGE_TIME_SLICE); | |
| 611 #endif | |
| 612 /* Release protection of information. */ | |
| 613 TCT_Unprotect(); | |
| 614 | |
| 615 /* Return to user mode */ | |
| 616 NU_USER_MODE(); | |
| 617 | |
| 618 /* Return the previous time slice value. */ | |
| 619 return(old_time_slice); | |
| 620 } | |
| 621 | |
| 622 | |
| 623 /*************************************************************************/ | |
| 624 /* */ | |
| 625 /* FUNCTION */ | |
| 626 /* */ | |
| 627 /* TCS_Control_Signals */ | |
| 628 /* */ | |
| 629 /* DESCRIPTION */ | |
| 630 /* */ | |
| 631 /* This function enables the specified signals and returns the */ | |
| 632 /* previous enable signal value back to the caller. If a newly */ | |
| 633 /* enabled signal is present and a signal handler is registered, */ | |
| 634 /* signal handling is started. */ | |
| 635 /* */ | |
| 636 /* CALLED BY */ | |
| 637 /* */ | |
| 638 /* Application */ | |
| 639 /* TCSE_Control_Signals Error checking shell */ | |
| 640 /* */ | |
| 641 /* CALLS */ | |
| 642 /* */ | |
| 643 /* [HIC_Make_History_Entry] Make entry in history log */ | |
| 644 /* TCC_Signal_Shell Task signal execution */ | |
| 645 /* [TCT_Check_Stack] Stack checking function */ | |
| 646 /* TCT_Protect Protect against other access */ | |
| 647 /* TCT_Unprotect Release protection */ | |
| 648 /* */ | |
| 649 /* INPUTS */ | |
| 650 /* */ | |
| 651 /* enable_signal_mask Enable signal mask */ | |
| 652 /* */ | |
| 653 /* OUTPUTS */ | |
| 654 /* */ | |
| 655 /* Previous signal enable mask */ | |
| 656 /* */ | |
| 657 /* HISTORY */ | |
| 658 /* */ | |
| 659 /* DATE REMARKS */ | |
| 660 /* */ | |
| 661 /* 03-01-1993 Created initial version 1.0 */ | |
| 662 /* 04-19-1993 Verified version 1.0 */ | |
| 663 /* 05-15-1993 Corrected problem with a comment */ | |
| 664 /* 05-15-1993 Verified comment repair */ | |
| 665 /* 03-01-1994 Added register optimizations, */ | |
| 666 /* modified protection logic, */ | |
| 667 /* resulting in version 1.1 */ | |
| 668 /* */ | |
| 669 /* 03-18-1994 Verified version 1.1 */ | |
| 670 /* */ | |
| 671 /*************************************************************************/ | |
| 672 UNSIGNED TCS_Control_Signals(UNSIGNED enable_signal_mask) | |
| 673 { | |
| 674 | |
| 675 R1 TC_TCB *task; /* Task pointer */ | |
| 676 UNSIGNED old_enable_mask; /* Old enable signal mask */ | |
| 677 NU_SUPERV_USER_VARIABLES | |
| 678 | |
| 679 /* Switch to supervisor mode */ | |
| 680 NU_SUPERVISOR_MODE(); | |
| 681 | |
| 682 #ifdef NU_ENABLE_STACK_CHECK | |
| 683 | |
| 684 /* Call stack checking function to check for an overflow condition. */ | |
| 685 TCT_Check_Stack(); | |
| 686 | |
| 687 #endif | |
| 688 | |
| 689 #ifdef NU_ENABLE_HISTORY | |
| 690 | |
| 691 /* Make an entry that corresponds to this function in the system history | |
| 692 log. */ | |
| 693 HIC_Make_History_Entry(NU_CONTROL_SIGNALS_ID,(UNSIGNED) enable_signal_mask, | |
| 694 (UNSIGNED) 0, (UNSIGNED) 0); | |
| 695 | |
| 696 #endif | |
| 697 | |
| 698 /* Pickup the task pointer. */ | |
| 699 task = (TC_TCB *) TCD_Current_Thread; | |
| 700 | |
| 701 /* Protect against simultaneous access. */ | |
| 702 TCT_Protect(&TCD_System_Protect); | |
| 703 | |
| 704 /* Pickup the old signal mask. */ | |
| 705 old_enable_mask = task -> tc_enabled_signals; | |
| 706 | |
| 707 /* Put the new mask in. */ | |
| 708 task -> tc_enabled_signals = enable_signal_mask; | |
| 709 | |
| 710 /* Now, determine if the signal handler needs to be invoked. */ | |
| 711 if ((enable_signal_mask & task -> tc_signals) && | |
| 712 (!task -> tc_signal_active) && | |
| 713 (task -> tc_signal_handler)) | |
| 714 { | |
| 715 | |
| 716 /* Signal processing is required. */ | |
| 717 | |
| 718 /* Indicate that signal processing is in progress. */ | |
| 719 task -> tc_signal_active = NU_TRUE; | |
| 720 | |
| 721 /* Clear the saved stack pointer to indicate that this is an | |
| 722 in line signal handler call. */ | |
| 723 task -> tc_saved_stack_ptr = NU_NULL; | |
| 724 | |
| 725 #ifdef INCLUDE_PROVIEW | |
| 726 _RTProf_DumpTask(task,RT_PROF_CONTROL_SIGNALS); | |
| 727 #endif | |
| 728 | |
| 729 /* Release protection from multiple access. */ | |
| 730 TCT_Unprotect(); | |
| 731 | |
| 732 /* Call the signal handling shell. */ | |
| 733 TCC_Signal_Shell(); | |
| 734 } | |
| 735 else | |
| 736 { | |
| 737 | |
| 738 #ifdef INCLUDE_PROVIEW | |
| 739 _RTProf_DumpTask(task,RT_PROF_CONTROL_SIGNALS); | |
| 740 #endif | |
| 741 | |
| 742 /* Release protection. */ | |
| 743 TCT_Unprotect(); | |
| 744 } | |
| 745 | |
| 746 /* Return to user mode */ | |
| 747 NU_USER_MODE(); | |
| 748 | |
| 749 /* Return the old enable mask. */ | |
| 750 return(old_enable_mask); | |
| 751 } | |
| 752 | |
| 753 | |
| 754 /*************************************************************************/ | |
| 755 /* */ | |
| 756 /* FUNCTION */ | |
| 757 /* */ | |
| 758 /* TCS_Receive_Signals */ | |
| 759 /* */ | |
| 760 /* DESCRIPTION */ | |
| 761 /* */ | |
| 762 /* This function returns the current signals back to the caller. */ | |
| 763 /* Note that the signals are cleared automatically. */ | |
| 764 /* */ | |
| 765 /* CALLED BY */ | |
| 766 /* */ | |
| 767 /* Application */ | |
| 768 /* TCSE_Receive_Signals Error checking shell */ | |
| 769 /* */ | |
| 770 /* CALLS */ | |
| 771 /* */ | |
| 772 /* [HIC_Make_History_Entry] Make entry in history log */ | |
| 773 /* [TCT_Check_Stack] Stack checking function */ | |
| 774 /* TCT_Protect Protect against other access */ | |
| 775 /* TCT_Unprotect Release protection */ | |
| 776 /* */ | |
| 777 /* INPUTS */ | |
| 778 /* */ | |
| 779 /* None */ | |
| 780 /* */ | |
| 781 /* OUTPUTS */ | |
| 782 /* */ | |
| 783 /* Current signals */ | |
| 784 /* */ | |
| 785 /* HISTORY */ | |
| 786 /* */ | |
| 787 /* DATE REMARKS */ | |
| 788 /* */ | |
| 789 /* 03-01-1993 Created initial version 1.0 */ | |
| 790 /* 04-19-1993 Verified version 1.0 */ | |
| 791 /* 03-01-1994 Modified protection logic, */ | |
| 792 /* resulting in version 1.1 */ | |
| 793 /* */ | |
| 794 /* 03-18-1994 Verified version 1.1 */ | |
| 795 /* */ | |
| 796 /*************************************************************************/ | |
| 797 UNSIGNED TCS_Receive_Signals(VOID) | |
| 798 { | |
| 799 | |
| 800 TC_TCB *task; /* Task pointer */ | |
| 801 UNSIGNED signals; /* Current signals */ | |
| 802 NU_SUPERV_USER_VARIABLES | |
| 803 | |
| 804 /* Switch to supervisor mode */ | |
| 805 NU_SUPERVISOR_MODE(); | |
| 806 | |
| 807 #ifdef NU_ENABLE_STACK_CHECK | |
| 808 | |
| 809 /* Call stack checking function to check for an overflow condition. */ | |
| 810 TCT_Check_Stack(); | |
| 811 | |
| 812 #endif | |
| 813 | |
| 814 #ifdef NU_ENABLE_HISTORY | |
| 815 | |
| 816 /* Make an entry that corresponds to this function in the system history | |
| 817 log. */ | |
| 818 HIC_Make_History_Entry(NU_RECEIVE_SIGNALS_ID, (UNSIGNED) 0, | |
| 819 (UNSIGNED) 0, (UNSIGNED) 0); | |
| 820 | |
| 821 #endif | |
| 822 | |
| 823 /* Pickup the task pointer. */ | |
| 824 task = (TC_TCB *) TCD_Current_Thread; | |
| 825 | |
| 826 /* Protect against simultaneous access. */ | |
| 827 TCT_Protect(&TCD_System_Protect); | |
| 828 | |
| 829 /* Pickup the current events. */ | |
| 830 signals = task -> tc_signals; | |
| 831 | |
| 832 /* Clear the current signals. */ | |
| 833 task -> tc_signals = 0; | |
| 834 | |
| 835 #ifdef INCLUDE_PROVIEW | |
| 836 _RTProf_DumpTask(task,RT_PROF_RECEIVE_SIGNALS); | |
| 837 #endif | |
| 838 | |
| 839 /* Release protection. */ | |
| 840 TCT_Unprotect(); | |
| 841 | |
| 842 /* Return to user mode */ | |
| 843 NU_USER_MODE(); | |
| 844 | |
| 845 /* Return the signals to the caller. */ | |
| 846 return(signals); | |
| 847 } | |
| 848 | |
| 849 | |
| 850 /*************************************************************************/ | |
| 851 /* */ | |
| 852 /* FUNCTION */ | |
| 853 /* */ | |
| 854 /* TCS_Register_Signal_Handler */ | |
| 855 /* */ | |
| 856 /* DESCRIPTION */ | |
| 857 /* */ | |
| 858 /* This function registers a signal handler for the calling task. */ | |
| 859 /* Note that if an enabled signal is present and this is the first */ | |
| 860 /* registered signal handler call, the signal is processed */ | |
| 861 /* immediately. */ | |
| 862 /* */ | |
| 863 /* CALLED BY */ | |
| 864 /* */ | |
| 865 /* Application */ | |
| 866 /* TCSE_Register_Signal_Handler Error checking shell */ | |
| 867 /* */ | |
| 868 /* CALLS */ | |
| 869 /* */ | |
| 870 /* [HIC_Make_History_Entry] Make entry in history log */ | |
| 871 /* TCC_Signal_Shell Signal execution shell */ | |
| 872 /* [TCT_Check_Stack] Stack checking function */ | |
| 873 /* TCT_Protect Protect against other access */ | |
| 874 /* TCT_Unprotect Release protection */ | |
| 875 /* */ | |
| 876 /* INPUTS */ | |
| 877 /* */ | |
| 878 /* signal_handler Signal execution shell */ | |
| 879 /* */ | |
| 880 /* OUTPUTS */ | |
| 881 /* */ | |
| 882 /* NU_SUCCESS */ | |
| 883 /* */ | |
| 884 /* HISTORY */ | |
| 885 /* */ | |
| 886 /* DATE REMARKS */ | |
| 887 /* */ | |
| 888 /* 03-01-1993 Created initial version 1.0 */ | |
| 889 /* 04-19-1993 Verified version 1.0 */ | |
| 890 /* 05-15-1993 Corrected problem with a comment */ | |
| 891 /* 05-15-1993 Verified comment repair */ | |
| 892 /* 03-01-1994 Added register optimizations, */ | |
| 893 /* modified protection logic, */ | |
| 894 /* resulting in version 1.1 */ | |
| 895 /* */ | |
| 896 /* 03-18-1994 Verified version 1.1 */ | |
| 897 /* */ | |
| 898 /*************************************************************************/ | |
| 899 STATUS TCS_Register_Signal_Handler(VOID (*signal_handler)(UNSIGNED)) | |
| 900 { | |
| 901 | |
| 902 R1 TC_TCB *task; /* Task pointer */ | |
| 903 NU_SUPERV_USER_VARIABLES | |
| 904 | |
| 905 /* Switch to supervisor mode */ | |
| 906 NU_SUPERVISOR_MODE(); | |
| 907 | |
| 908 #ifdef NU_ENABLE_STACK_CHECK | |
| 909 | |
| 910 /* Call stack checking function to check for an overflow condition. */ | |
| 911 TCT_Check_Stack(); | |
| 912 | |
| 913 #endif | |
| 914 | |
| 915 #ifdef NU_ENABLE_HISTORY | |
| 916 | |
| 917 /* Make an entry that corresponds to this function in the system history | |
| 918 log. */ | |
| 919 HIC_Make_History_Entry(NU_REGISTER_SIGNAL_HANDLER_ID, | |
| 920 (UNSIGNED) signal_handler, (UNSIGNED) 0, (UNSIGNED) 0); | |
| 921 | |
| 922 #endif | |
| 923 | |
| 924 /* Pickup the task pointer. */ | |
| 925 task = (TC_TCB *) TCD_Current_Thread; | |
| 926 | |
| 927 /* Protect against simultaneous access. */ | |
| 928 TCT_Protect(&TCD_System_Protect); | |
| 929 | |
| 930 /* Put the new signal handler in. */ | |
| 931 task -> tc_signal_handler = signal_handler; | |
| 932 | |
| 933 /* Now, determine if the signal handler needs to be invoked. */ | |
| 934 if ((task -> tc_enabled_signals & task -> tc_signals) && | |
| 935 (!task -> tc_signal_active) && | |
| 936 (task -> tc_signal_handler)) | |
| 937 { | |
| 938 | |
| 939 /* Signal processing is required. */ | |
| 940 | |
| 941 /* Indicate that signal processing is in progress. */ | |
| 942 task -> tc_signal_active = NU_TRUE; | |
| 943 | |
| 944 /* Clear the saved stack pointer to indicate that this is an | |
| 945 in line signal handler call. */ | |
| 946 task -> tc_saved_stack_ptr = NU_NULL; | |
| 947 | |
| 948 /* Release protection from multiple access. */ | |
| 949 TCT_Unprotect(); | |
| 950 | |
| 951 /* Call the signal handling shell. */ | |
| 952 TCC_Signal_Shell(); | |
| 953 } | |
| 954 else | |
| 955 | |
| 956 /* Release protection. */ | |
| 957 TCT_Unprotect(); | |
| 958 | |
| 959 /* Return to user mode */ | |
| 960 NU_USER_MODE(); | |
| 961 | |
| 962 /* Return success. */ | |
| 963 return(NU_SUCCESS); | |
| 964 } | |
| 965 | |
| 966 | |
| 967 /*************************************************************************/ | |
| 968 /* */ | |
| 969 /* FUNCTION */ | |
| 970 /* */ | |
| 971 /* TCS_Send_Signals */ | |
| 972 /* */ | |
| 973 /* DESCRIPTION */ | |
| 974 /* */ | |
| 975 /* This function sends the specified task the specified signals. */ | |
| 976 /* If enabled, the specified task is setup in order to process the */ | |
| 977 /* signals. */ | |
| 978 /* */ | |
| 979 /* CALLED BY */ | |
| 980 /* */ | |
| 981 /* Application */ | |
| 982 /* TCSE_Send_Signals Error checking shell */ | |
| 983 /* */ | |
| 984 /* CALLS */ | |
| 985 /* */ | |
| 986 /* [HIC_Make_History_Entry] Make entry in history log */ | |
| 987 /* TCC_Resume_Task Resume task that is suspended*/ | |
| 988 /* TCC_Signal_Shell Signal execution shell */ | |
| 989 /* TCT_Build_Signal_Frame Build a signal frame */ | |
| 990 /* [TCT_Check_Stack] Stack checking function */ | |
| 991 /* TCT_Control_To_System Control to system */ | |
| 992 /* TCT_Protect Protect against other access */ | |
| 993 /* TCT_Unprotect Release protection */ | |
| 994 /* */ | |
| 995 /* INPUTS */ | |
| 996 /* */ | |
| 997 /* task_ptr Task pointer */ | |
| 998 /* signals Signals to send to the task */ | |
| 999 /* */ | |
| 1000 /* OUTPUTS */ | |
| 1001 /* */ | |
| 1002 /* NU_SUCCESS */ | |
| 1003 /* */ | |
| 1004 /* HISTORY */ | |
| 1005 /* */ | |
| 1006 /* DATE REMARKS */ | |
| 1007 /* */ | |
| 1008 /* 03-01-1993 Created initial version 1.0 */ | |
| 1009 /* 04-19-1993 Verified version 1.0 */ | |
| 1010 /* 03-01-1994 Modified function interface, */ | |
| 1011 /* added register optimizations, */ | |
| 1012 /* modified protection logic, */ | |
| 1013 /* resulting in version 1.1 */ | |
| 1014 /* */ | |
| 1015 /* 03-18-1994 Verified version 1.1 */ | |
| 1016 /* 04-04-1996 On line 995, changed tc_signals */ | |
| 1017 /* to tc_enabled_signals, */ | |
| 1018 /* resulting in version 1.1+ */ | |
| 1019 /* (spr 107) */ | |
| 1020 /* */ | |
| 1021 /*************************************************************************/ | |
| 1022 STATUS TCS_Send_Signals(NU_TASK *task_ptr, UNSIGNED signals) | |
| 1023 { | |
| 1024 | |
| 1025 R1 TC_TCB *task; /* Task control block ptr */ | |
| 1026 NU_SUPERV_USER_VARIABLES | |
| 1027 | |
| 1028 /* Switch to supervisor mode */ | |
| 1029 NU_SUPERVISOR_MODE(); | |
| 1030 | |
| 1031 /* Move input task control block pointer into internal pointer. */ | |
| 1032 task = (TC_TCB *) task_ptr; | |
| 1033 | |
| 1034 | |
| 1035 #ifdef NU_ENABLE_STACK_CHECK | |
| 1036 | |
| 1037 /* Call stack checking function to check for an overflow condition. */ | |
| 1038 TCT_Check_Stack(); | |
| 1039 | |
| 1040 #endif | |
| 1041 | |
| 1042 #ifdef NU_ENABLE_HISTORY | |
| 1043 | |
| 1044 /* Make an entry that corresponds to this function in the system history | |
| 1045 log. */ | |
| 1046 HIC_Make_History_Entry(NU_SEND_SIGNALS_ID, (UNSIGNED) signals, | |
| 1047 (UNSIGNED) 0, (UNSIGNED) 0); | |
| 1048 | |
| 1049 #endif | |
| 1050 | |
| 1051 /* Protect against simultaneous access. */ | |
| 1052 TCT_Protect(&TCD_System_Protect); | |
| 1053 | |
| 1054 /* Or the new signals into the current signals. */ | |
| 1055 task -> tc_signals = task -> tc_signals | signals; | |
| 1056 | |
| 1057 #ifdef INCLUDE_PROVIEW | |
| 1058 _RTProf_DumpTask(task,RT_PROF_SEND_SIGNALS); | |
| 1059 #endif | |
| 1060 /* Now, determine if the signal handler needs to be invoked. */ | |
| 1061 if ((task -> tc_signals & task -> tc_enabled_signals) && | |
| 1062 (!task -> tc_signal_active) && | |
| 1063 (task -> tc_status != NU_TERMINATED) && | |
| 1064 (task -> tc_status != NU_FINISHED) && | |
| 1065 (task -> tc_signal_handler)) | |
| 1066 { | |
| 1067 | |
| 1068 /* Indicate that signal processing is in progress. */ | |
| 1069 task -> tc_signal_active = NU_TRUE; | |
| 1070 | |
| 1071 /* Signal processing is required. Determine if the task is sending | |
| 1072 signals to itself or if the calling thread is not the current | |
| 1073 task. */ | |
| 1074 if (task == (TC_TCB *) TCD_Current_Thread) | |
| 1075 { | |
| 1076 | |
| 1077 /* Task sending signals to itself. */ | |
| 1078 | |
| 1079 /* Clear the saved stack pointer to indicate that this is an | |
| 1080 in line signal handler call. */ | |
| 1081 task -> tc_saved_stack_ptr = NU_NULL; | |
| 1082 | |
| 1083 /* Release protection from multiple access. */ | |
| 1084 TCT_Unprotect(); | |
| 1085 | |
| 1086 /* Call the signal handling shell. */ | |
| 1087 TCC_Signal_Shell(); | |
| 1088 } | |
| 1089 else | |
| 1090 { | |
| 1091 | |
| 1092 /* Target task must be prepared to receive the signals. */ | |
| 1093 | |
| 1094 /* First, insure that the target task is not in a protected | |
| 1095 area. */ | |
| 1096 do | |
| 1097 { | |
| 1098 | |
| 1099 /* Check for protection. Remember that protection is still | |
| 1100 in effect. */ | |
| 1101 if (task -> tc_current_protect) | |
| 1102 { | |
| 1103 | |
| 1104 /* Yes, target task is in a protected mode. Release | |
| 1105 the protection on the scheduling list and transfer | |
| 1106 control briefly to the target task. */ | |
| 1107 TCT_Unprotect(); | |
| 1108 | |
| 1109 /* Switch to the protected task and wait until the | |
| 1110 task is not protected. */ | |
| 1111 TCT_Protect_Switch(task); | |
| 1112 | |
| 1113 /* Restore protection on the scheduling structures. */ | |
| 1114 TCT_Protect(&TCD_System_Protect); | |
| 1115 } | |
| 1116 } while (task -> tc_current_protect); | |
| 1117 | |
| 1118 /* Copy the current status and stack pointer to the signal save | |
| 1119 areas. */ | |
| 1120 task -> tc_saved_status = task -> tc_status; | |
| 1121 task -> tc_saved_stack_ptr = task -> tc_stack_pointer; | |
| 1122 | |
| 1123 /* Build a stack frame for the signal handling shell function. */ | |
| 1124 TCT_Build_Signal_Frame(task); | |
| 1125 | |
| 1126 /* Determine if the target task is currently suspended. If it is | |
| 1127 suspended for any other reason than a pure suspend, resume | |
| 1128 it. */ | |
| 1129 if ((task -> tc_status != NU_READY) && | |
| 1130 (task -> tc_status != NU_PURE_SUSPEND)) | |
| 1131 { | |
| 1132 | |
| 1133 /* Resume the target task and check for preemption. */ | |
| 1134 if (TCC_Resume_Task(task_ptr, task -> tc_status)) | |
| 1135 | |
| 1136 /* Preemption needs to take place. */ | |
| 1137 TCT_Control_To_System(); | |
| 1138 } | |
| 1139 } | |
| 1140 } | |
| 1141 | |
| 1142 /* Release protection, no signals are currently enabled. */ | |
| 1143 TCT_Unprotect(); | |
| 1144 | |
| 1145 /* Return to user mode */ | |
| 1146 NU_USER_MODE(); | |
| 1147 | |
| 1148 /* Return a successful status. */ | |
| 1149 return(NU_SUCCESS); | |
| 1150 } | |
| 1151 | |
| 1152 | |
| 1153 | |
| 1154 |
