comparison src/nucleus/smc.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 /* smc.c Nucleus PLUS 1.14 */
17 /* */
18 /* COMPONENT */
19 /* */
20 /* SM - Semaphore Management */
21 /* */
22 /* DESCRIPTION */
23 /* */
24 /* This file contains the core routines for the Semaphore Management*/
25 /* component. */
26 /* */
27 /* DATA STRUCTURES */
28 /* */
29 /* None */
30 /* */
31 /* FUNCTIONS */
32 /* */
33 /* SMC_Create_Semaphore Create a semaphore */
34 /* SMC_Delete_Semaphore Delete a semaphore */
35 /* SMC_Obtain_Semaphore Obtain instance of semaphore */
36 /* SMC_Release_Semaphore Release instance of semaphore*/
37 /* SMC_Cleanup Cleanup on timeout or a */
38 /* terminate condition */
39 /* */
40 /* DEPENDENCIES */
41 /* */
42 /* cs_extr.h Common Service functions */
43 /* tc_extr.h Thread Control functions */
44 /* sm_extr.h Semaphore functions */
45 /* hi_extr.h History functions */
46 /* */
47 /* HISTORY */
48 /* */
49 /* DATE REMARKS */
50 /* */
51 /* 03-01-1993 Created initial version 1.0 */
52 /* 04-19-1993 Verified version 1.0 */
53 /* 08-09-1993 Corrected pointer retrieval */
54 /* loop, resulting in version 1.0a */
55 /* 08-09-1993 Verified version 1.0a */
56 /* 03-01-1994 Moved non-core functions into */
57 /* supplemental files, changed */
58 /* function interfaces to match */
59 /* those in prototype, added */
60 /* register options, changed */
61 /* protection logic to reduce */
62 /* overhead, resulting in */
63 /* version 1.1 */
64 /* */
65 /* 03-18-1994 Verified version 1.1 */
66 /* 04-17-1996 updated to version 1.2 */
67 /* 03-24-1998 Released version 1.3 */
68 /* 03-26-1999 Released 1.11m (new release */
69 /* numbering scheme) */
70 /* 04-17-2002 Released version 1.13m */
71 /* 11-07-2002 Released version 1.14 */
72 /*************************************************************************/
73 #define NU_SOURCE_FILE
74
75
76 #include "cs_extr.h" /* Common service functions */
77 #include "tc_extr.h" /* Thread control functions */
78 #include "sm_extr.h" /* Semaphore functions */
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 *SMD_Created_Semaphores_List;
86 extern UNSIGNED SMD_Total_Semaphores;
87 extern TC_PROTECT SMD_List_Protect;
88
89
90 /* Define internal component function prototypes. */
91
92 VOID SMC_Cleanup(VOID *information);
93
94
95 /*************************************************************************/
96 /* */
97 /* FUNCTION */
98 /* */
99 /* SMC_Create_Semaphore */
100 /* */
101 /* DESCRIPTION */
102 /* */
103 /* This function creates a semaphore and then places it on the list */
104 /* of created semaphores. */
105 /* */
106 /* CALLED BY */
107 /* */
108 /* Application */
109 /* SMCE_Create_Semaphore Error checking shell */
110 /* */
111 /* CALLS */
112 /* */
113 /* CSC_Place_On_List Add node to linked-list */
114 /* [HIC_Make_History_Entry] Make entry in history log */
115 /* [TCT_Check_Stack] Stack checking function */
116 /* TCT_Protect Data structure protect */
117 /* TCT_Unprotect Un-protect data structure */
118 /* */
119 /* INPUTS */
120 /* */
121 /* semaphore_ptr Semaphore control block ptr */
122 /* name Semaphore name */
123 /* initial_count Initial semaphore instance */
124 /* count */
125 /* suspend_type Suspension type */
126 /* */
127 /* OUTPUTS */
128 /* */
129 /* NU_SUCCESS */
130 /* */
131 /* HISTORY */
132 /* */
133 /* DATE REMARKS */
134 /* */
135 /* 03-01-1993 Created initial version 1.0 */
136 /* 04-19-1993 Verified version 1.0 */
137 /* 03-01-1994 Changed function interfaces to */
138 /* match those in prototype, */
139 /* added register options, */
140 /* resulting in version 1.1 */
141 /* */
142 /* 03-18-1994 Verified version 1.1 */
143 /* */
144 /*************************************************************************/
145 STATUS SMC_Create_Semaphore(NU_SEMAPHORE *semaphore_ptr, CHAR *name,
146 UNSIGNED initial_count, OPTION suspend_type)
147 {
148
149 R1 SM_SCB *semaphore; /* Semaphore control blk ptr */
150 INT i; /* Working index variable */
151 NU_SUPERV_USER_VARIABLES
152
153 /* Switch to supervisor mode */
154 NU_SUPERVISOR_MODE();
155
156 /* Move input semaphore pointer into internal pointer. */
157 semaphore = (SM_SCB *) semaphore_ptr;
158
159
160 #ifdef NU_ENABLE_STACK_CHECK
161
162 /* Call stack checking function to check for an overflow condition. */
163 TCT_Check_Stack();
164
165 #endif
166
167 #ifdef NU_ENABLE_HISTORY
168
169 /* Make an entry that corresponds to this function in the system history
170 log. */
171 HIC_Make_History_Entry(NU_CREATE_SEMAPHORE_ID, (UNSIGNED) semaphore,
172 (UNSIGNED) name, (UNSIGNED) initial_count);
173
174 #endif
175
176 /* First, clear the semaphore ID just in case it is an old Semaphore
177 Control Block. */
178 semaphore -> sm_id = 0;
179
180 /* Fill in the semaphore name. */
181 for (i = 0; i < NU_MAX_NAME; i++)
182 semaphore -> sm_name[i] = name[i];
183
184 /* Setup the initial semaphore instance count. */
185 semaphore -> sm_semaphore_count = initial_count;
186
187 /* Setup the semaphore suspension type. */
188 if (suspend_type == NU_FIFO)
189
190 /* FIFO suspension is selected, setup the flag accordingly. */
191 semaphore -> sm_fifo_suspend = NU_TRUE;
192 else
193
194 /* Priority suspension is selected. */
195 semaphore -> sm_fifo_suspend = NU_FALSE;
196
197 /* Clear the suspension list pointer. */
198 semaphore -> sm_suspension_list = NU_NULL;
199
200 /* Clear the number of tasks waiting on the semaphore counter. */
201 semaphore -> sm_tasks_waiting = 0;
202
203 /* Initialize link pointers. */
204 semaphore -> sm_created.cs_previous = NU_NULL;
205 semaphore -> sm_created.cs_next = NU_NULL;
206
207 /* Protect against access to the list of created semaphores. */
208 TCT_Protect(&SMD_List_Protect);
209
210 /* At this point the semaphore is completely built. The ID can now be
211 set and it can be linked into the created semaphore list. */
212 semaphore -> sm_id = SM_SEMAPHORE_ID;
213
214 /* Link the semaphore into the list of created semaphores and increment the
215 total number of semaphores in the system. */
216 CSC_Place_On_List(&SMD_Created_Semaphores_List,&(semaphore -> sm_created));
217 SMD_Total_Semaphores++;
218
219 #ifdef INCLUDE_PROVIEW
220 _RTProf_DumpSema(RT_PROF_CREATE_SEMAPHORE,semaphore, RT_PROF_OK);
221 #endif
222
223 /* Release protection against access to the list of created semaphores. */
224 TCT_Unprotect();
225
226 /* Return to user mode */
227 NU_USER_MODE();
228
229 /* Return successful completion. */
230 return(NU_SUCCESS);
231 }
232
233
234 /*************************************************************************/
235 /* */
236 /* FUNCTION */
237 /* */
238 /* SMC_Delete_Semaphore */
239 /* */
240 /* DESCRIPTION */
241 /* */
242 /* This function deletes a semaphore and removes it from the list */
243 /* of created semaphores. All tasks suspended on the semaphore are */
244 /* resumed. Note that this function does not free the memory */
245 /* associated with the semaphore control block. */
246 /* */
247 /* CALLED BY */
248 /* */
249 /* Application */
250 /* SMCE_Delete_Semaphore Error checking shell */
251 /* */
252 /* CALLS */
253 /* */
254 /* CSC_Remove_From_List Remove node from list */
255 /* [HIC_Make_History_Entry] Make entry in history log */
256 /* TCC_Resume_Task Resume a suspended task */
257 /* [TCT_Check_Stack] Stack checking function */
258 /* TCT_Control_To_System Transfer control to system */
259 /* TCT_Protect Protect created list */
260 /* TCT_Set_Current_Protect Modify current protection */
261 /* TCT_System_Protect Setup system protection */
262 /* TCT_System_Unprotect Release system protection */
263 /* TCT_Unprotect Release protection */
264 /* */
265 /* INPUTS */
266 /* */
267 /* semaphore_ptr Semaphore control block ptr */
268 /* */
269 /* OUTPUTS */
270 /* */
271 /* NU_SUCCESS */
272 /* */
273 /* HISTORY */
274 /* */
275 /* DATE REMARKS */
276 /* */
277 /* 03-01-1993 Created initial version 1.0 */
278 /* 04-19-1993 Verified version 1.0 */
279 /* 03-01-1994 Changed function interfaces to */
280 /* match those in prototype, */
281 /* added register options, changed */
282 /* protection logic to reduce */
283 /* overhead, resulting in */
284 /* version 1.1 */
285 /* */
286 /* 03-18-1994 Verified version 1.1 */
287 /* */
288 /*************************************************************************/
289 STATUS SMC_Delete_Semaphore(NU_SEMAPHORE *semaphore_ptr)
290 {
291
292 R1 SM_SCB *semaphore; /* Semaphore control blk ptr */
293 SM_SUSPEND *suspend_ptr; /* Suspend block pointer */
294 SM_SUSPEND *next_ptr; /* Next suspend block */
295 STATUS preempt; /* Status for resume call */
296 NU_SUPERV_USER_VARIABLES
297
298 /* Switch to supervisor mode */
299 NU_SUPERVISOR_MODE();
300
301 /* Move input semaphore pointer into internal pointer. */
302 semaphore = (SM_SCB *) semaphore_ptr;
303
304
305 #ifdef NU_ENABLE_STACK_CHECK
306
307 /* Call stack checking function to check for an overflow condition. */
308 TCT_Check_Stack();
309
310 #endif
311
312 #ifdef NU_ENABLE_HISTORY
313
314 /* Make an entry that corresponds to this function in the system history
315 log. */
316 HIC_Make_History_Entry(NU_DELETE_SEMAPHORE_ID, (UNSIGNED) semaphore,
317 (UNSIGNED) 0, (UNSIGNED) 0);
318
319 #endif
320
321 /* Protect against access to the semaphore. */
322 TCT_System_Protect();
323
324 #ifdef INCLUDE_PROVIEW
325 _RTProf_DumpSema(RT_PROF_DELETE_SEMAPHORE,semaphore, RT_PROF_OK);
326 #endif
327
328 /* Clear the semaphore ID. */
329 semaphore -> sm_id = 0;
330
331 /* Release protection. */
332 TCT_Unprotect();
333
334 /* Protect against access to the list of created semaphores. */
335 TCT_Protect(&SMD_List_Protect);
336
337 /* Remove the semaphore from the list of created semaphores. */
338 CSC_Remove_From_List(&SMD_Created_Semaphores_List,
339 &(semaphore -> sm_created));
340
341 /* Decrement the total number of created semaphores. */
342 SMD_Total_Semaphores--;
343
344 /* Pickup the suspended task pointer list. */
345 suspend_ptr = semaphore -> sm_suspension_list;
346
347 /* Walk the chain task(s) currently suspended on the semaphore. */
348 preempt = 0;
349 while (suspend_ptr)
350 {
351
352 /* Protect against system access. */
353 TCT_System_Protect();
354
355 /* Resume the suspended task. Insure that the status returned is
356 NU_SEMAPHORE_DELETED. */
357 suspend_ptr -> sm_return_status = NU_SEMAPHORE_DELETED;
358
359 /* Point to the next suspend structure in the link. */
360 next_ptr = (SM_SUSPEND *) (suspend_ptr -> sm_suspend_link.cs_next);
361
362 /* Resume the specified task. */
363 preempt = preempt |
364 TCC_Resume_Task((NU_TASK *) suspend_ptr -> sm_suspended_task,
365 NU_SEMAPHORE_SUSPEND);
366
367 /* Determine if the next is the same as the current pointer. */
368 if (next_ptr == semaphore -> sm_suspension_list)
369
370 /* Clear the suspension pointer to signal the end of the list
371 traversal. */
372 suspend_ptr = NU_NULL;
373 else
374
375 /* Move the next pointer into the suspend block pointer. */
376 suspend_ptr = next_ptr;
377
378 /* Modify current protection. */
379 TCT_Set_Current_Protect(&SMD_List_Protect);
380
381 /* Clear the system protection. */
382 TCT_System_Unprotect();
383 }
384
385 /* Determine if preemption needs to occur. */
386 if (preempt)
387
388 /* Transfer control to system to facilitate preemption. */
389 TCT_Control_To_System();
390
391 /* Release protection against access to the list of created semaphores. */
392 TCT_Unprotect();
393
394 /* Return to user mode */
395 NU_USER_MODE();
396
397 /* Return a successful completion. */
398 return(NU_SUCCESS);
399 }
400
401
402 /*************************************************************************/
403 /* */
404 /* FUNCTION */
405 /* */
406 /* SMC_Obtain_Semaphore */
407 /* */
408 /* DESCRIPTION */
409 /* */
410 /* This function obtains an instance of the semaphore. An instance */
411 /* corresponds to decrementing the counter by 1. If the counter is */
412 /* greater than zero at the time of this call, this function can be */
413 /* completed immediately. Otherwise, suspension is possible. */
414 /* */
415 /* CALLED BY */
416 /* */
417 /* Application */
418 /* SMCE_Obtain_Semaphore Error checking shell */
419 /* */
420 /* CALLS */
421 /* */
422 /* CSC_Place_On_List Place on suspend list */
423 /* CSC_Priority_Place_On_List Place on priority list */
424 /* [HIC_Make_History_Entry] Make entry in history log */
425 /* TCC_Suspend_Task Suspend calling task */
426 /* TCC_Task_Priority Obtain task's priority */
427 /* [TCT_Check_Stack] Stack checking function */
428 /* TCT_Current_Thread Pickup current thread pointer*/
429 /* TCT_System_Protect Protect semaphore */
430 /* TCT_Unprotect Release protection */
431 /* */
432 /* INPUTS */
433 /* */
434 /* semaphore_ptr Semaphore control block ptr */
435 /* suspend Suspension option if full */
436 /* */
437 /* OUTPUTS */
438 /* */
439 /* NU_SUCCESS If service is successful */
440 /* NU_UNAVAILABLE If an instance of the */
441 /* semaphore is not available */
442 /* NU_TIMEOUT If timeout on service */
443 /* NU_SEMAPHORE_DELETED If semaphore deleted during */
444 /* suspension */
445 /* NU_SEMAPHORE_RESET If semaphore reset during */
446 /* suspension */
447 /* */
448 /* HISTORY */
449 /* */
450 /* DATE REMARKS */
451 /* */
452 /* 03-01-1993 Created initial version 1.0 */
453 /* 04-19-1993 Verified version 1.0 */
454 /* 03-01-1994 Changed function interfaces to */
455 /* match those in prototype, */
456 /* added register options, changed */
457 /* protection logic to reduce */
458 /* overhead, resulting in */
459 /* version 1.1 */
460 /* */
461 /* 03-18-1994 Verified version 1.1 */
462 /* */
463 /*************************************************************************/
464 STATUS SMC_Obtain_Semaphore(NU_SEMAPHORE *semaphore_ptr, UNSIGNED suspend)
465 {
466
467 R1 SM_SCB *semaphore; /* Semaphore control blk ptr */
468 R2 SM_SUSPEND *suspend_ptr; /* Suspend block pointer */
469 SM_SUSPEND suspend_block; /* Allocate suspension block */
470 TC_TCB *task; /* Task pointer */
471 STATUS status; /* Completion status */
472 NU_SUPERV_USER_VARIABLES
473
474 /* Switch to supervisor mode */
475 NU_SUPERVISOR_MODE();
476
477 /* Move input semaphore pointer into internal pointer. */
478 semaphore = (SM_SCB *) semaphore_ptr;
479
480
481 #ifdef NU_ENABLE_STACK_CHECK
482
483 /* Call stack checking function to check for an overflow condition. */
484 TCT_Check_Stack();
485
486 #endif
487
488 #ifdef NU_ENABLE_HISTORY
489
490 /* Make an entry that corresponds to this function in the system history
491 log. */
492 HIC_Make_History_Entry(NU_OBTAIN_SEMAPHORE_ID, (UNSIGNED) semaphore,
493 (UNSIGNED) suspend, (UNSIGNED) 0);
494
495 #endif
496
497 /* Initialize the status as successful. */
498 status = NU_SUCCESS;
499
500 /* Protect against simultaneous access to the semaphore. */
501 TCT_System_Protect();
502
503 /* Determine if the semaphore has an instance (can be decremented). */
504 if (semaphore -> sm_semaphore_count)
505 {
506
507 /* Semaphore available. Decrement and return to the caller. */
508 semaphore -> sm_semaphore_count--;
509 #ifdef INCLUDE_PROVIEW
510 _RTProf_DumpSema(RT_PROF_OBTAIN_SEMAPHORE,semaphore, RT_PROF_OK);
511 #endif
512
513 }
514 else
515 {
516
517 /* Semaphore is not available. Determine if suspension is required. */
518 if (suspend)
519 {
520
521 /* Suspension is selected. */
522
523 /* Increment the number of tasks waiting. */
524 semaphore -> sm_tasks_waiting++;
525
526 #ifdef INCLUDE_PROVIEW
527 _RTProf_DumpSema(RT_PROF_OBTAIN_SEMAPHORE,semaphore , RT_PROF_WAIT);
528 #endif
529
530 /* Setup the suspend block and suspend the calling task. */
531 suspend_ptr = &suspend_block;
532 suspend_ptr -> sm_semaphore = semaphore;
533 suspend_ptr -> sm_suspend_link.cs_next = NU_NULL;
534 suspend_ptr -> sm_suspend_link.cs_previous = NU_NULL;
535 task = (TC_TCB *) TCT_Current_Thread();
536 suspend_ptr -> sm_suspended_task = task;
537
538 /* Determine if priority or FIFO suspension is associated with the
539 semaphore. */
540 if (semaphore -> sm_fifo_suspend)
541 {
542
543 /* FIFO suspension is required. Link the suspend block into
544 the list of suspended tasks on this semaphore. */
545 CSC_Place_On_List((CS_NODE **)
546 &(semaphore -> sm_suspension_list),
547 &(suspend_ptr -> sm_suspend_link));
548 }
549 else
550 {
551
552 /* Get the priority of the current thread so the suspend block
553 can be placed in the appropriate place. */
554 suspend_ptr -> sm_suspend_link.cs_priority =
555 TCC_Task_Priority(task);
556
557 CSC_Priority_Place_On_List((CS_NODE **)
558 &(semaphore -> sm_suspension_list),
559 &(suspend_ptr -> sm_suspend_link));
560 }
561
562 /* Finally, suspend the calling task. Note that the suspension call
563 automatically clears the protection on the semaphore. */
564 TCC_Suspend_Task((NU_TASK *) task, NU_SEMAPHORE_SUSPEND,
565 SMC_Cleanup, suspend_ptr, suspend);
566
567 /* Pickup the return status. */
568 status = suspend_ptr -> sm_return_status;
569 }
570 else
571 {
572 /* No suspension requested. Simply return an error status. */
573 status = NU_UNAVAILABLE;
574
575 #ifdef INCLUDE_PROVIEW
576 _RTProf_DumpSema(RT_PROF_OBTAIN_SEMAPHORE, semaphore,RT_PROF_FAIL);
577 #endif
578 }
579 }
580
581 /* Release protection against access to the semaphore. */
582 TCT_Unprotect();
583
584 /* Return to user mode */
585 NU_USER_MODE();
586
587 /* Return the completion status. */
588 return(status);
589 }
590
591
592 /*************************************************************************/
593 /* */
594 /* FUNCTION */
595 /* */
596 /* SMC_Release_Semaphore */
597 /* */
598 /* DESCRIPTION */
599 /* */
600 /* This function releases a previously obtained semaphore. If one */
601 /* or more tasks are waiting, the first task is given the released */
602 /* instance of the semaphore. Otherwise, the semaphore instance */
603 /* counter is simply incremented. */
604 /* */
605 /* CALLED BY */
606 /* */
607 /* Application */
608 /* SMCE_Release_Semaphore Error checking shell */
609 /* */
610 /* CALLS */
611 /* */
612 /* CSC_Remove_From_List Remove from suspend list */
613 /* [HIC_Make_History_Entry] Make entry in history log */
614 /* TCC_Resume_Task Resume a suspended task */
615 /* [TCT_Check_Stack] Stack checking function */
616 /* TCT_Control_To_System Transfer control to system */
617 /* TCT_System_Protect Protect semaphore */
618 /* TCT_Unprotect Release protection */
619 /* */
620 /* INPUTS */
621 /* */
622 /* semaphore_ptr Semaphore control block ptr */
623 /* */
624 /* OUTPUTS */
625 /* */
626 /* NU_SUCCESS */
627 /* */
628 /* HISTORY */
629 /* */
630 /* DATE REMARKS */
631 /* */
632 /* 03-01-1993 Created initial version 1.0 */
633 /* 04-19-1993 Verified version 1.0 */
634 /* 03-01-1994 Changed function interfaces to */
635 /* match those in prototype, */
636 /* added register options, changed */
637 /* protection logic to reduce */
638 /* overhead, resulting in */
639 /* version 1.1 */
640 /* */
641 /* 03-18-1994 Verified version 1.1 */
642 /* */
643 /*************************************************************************/
644 STATUS SMC_Release_Semaphore(NU_SEMAPHORE *semaphore_ptr)
645 {
646
647 R1 SM_SCB *semaphore; /* Semaphore control blk ptr */
648 R2 SM_SUSPEND *suspend_ptr; /* Pointer to suspend block */
649 STATUS preempt; /* Preemption flag */
650 STATUS status; /* Completion status */
651 NU_SUPERV_USER_VARIABLES
652
653 /* Switch to supervisor mode */
654 NU_SUPERVISOR_MODE();
655
656 /* Move input semaphore pointer into internal pointer. */
657 semaphore = (SM_SCB *) semaphore_ptr;
658
659
660 #ifdef NU_ENABLE_STACK_CHECK
661
662 /* Call stack checking function to check for an overflow condition. */
663 TCT_Check_Stack();
664
665 #endif
666
667 #ifdef NU_ENABLE_HISTORY
668
669 /* Make an entry that corresponds to this function in the system history
670 log. */
671 HIC_Make_History_Entry(NU_RELEASE_SEMAPHORE_ID, (UNSIGNED) semaphore,
672 (UNSIGNED) 0, (UNSIGNED) 0);
673
674 #endif
675
676 /* Initialize the status as successful. */
677 status = NU_SUCCESS;
678
679 /* Protect against simultaneous access to the semaphore. */
680 TCT_System_Protect();
681
682 /* Determine if another task is waiting on the semaphore. */
683 if (semaphore -> sm_tasks_waiting)
684 {
685
686 /* Yes, another task is waiting for an instance of the semaphore. */
687
688 /* Decrement the number of tasks waiting counter. */
689 semaphore -> sm_tasks_waiting--;
690
691 #ifdef INCLUDE_PROVIEW
692 _RTProf_DumpSema(RT_PROF_RELEASE_SEMAPHORE, semaphore,RT_PROF_OK);
693 #endif
694
695 /* Remove the first suspended block from the list. */
696 suspend_ptr = semaphore -> sm_suspension_list;
697 CSC_Remove_From_List((CS_NODE **) &(semaphore -> sm_suspension_list),
698 &(suspend_ptr -> sm_suspend_link));
699
700 /* Setup the appropriate return value. */
701 suspend_ptr -> sm_return_status = NU_SUCCESS;
702
703 /* Resume the suspended task. */
704 preempt =
705 TCC_Resume_Task((NU_TASK *) suspend_ptr -> sm_suspended_task,
706 NU_SEMAPHORE_SUSPEND);
707
708 /* Determine if a preempt condition is present. */
709 if (preempt)
710
711 /* Transfer control to the system if the resumed task function
712 detects a preemption condition. */
713 TCT_Control_To_System();
714 }
715 else
716 {
717
718 /* Increment the semaphore instance counter. */
719 semaphore -> sm_semaphore_count++;
720
721 #ifdef INCLUDE_PROVIEW
722 _RTProf_DumpSema(RT_PROF_RELEASE_SEMAPHORE, semaphore,RT_PROF_OK);
723 #endif
724 }
725
726 /* Release protection against access to the semaphore. */
727 TCT_Unprotect();
728
729 /* Return to user mode */
730 NU_USER_MODE();
731
732 /* Return the completion status. */
733 return(status);
734 }
735
736
737 /*************************************************************************/
738 /* */
739 /* FUNCTION */
740 /* */
741 /* SMC_Cleanup */
742 /* */
743 /* DESCRIPTION */
744 /* */
745 /* This function is responsible for removing a suspension block */
746 /* from a semaphore. It is not called unless a timeout or a task */
747 /* terminate is in progress. Note that protection is already in */
748 /* effect - the same protection at suspension time. This routine */
749 /* must be called from Supervisor mode in Supervisor/User mode */
750 /* switching kernels. */
751 /* */
752 /* CALLED BY */
753 /* */
754 /* TCC_Timeout Task timeout */
755 /* TCC_Terminate Task terminate */
756 /* */
757 /* CALLS */
758 /* */
759 /* CSC_Remove_From_List Remove suspend block from */
760 /* the suspension list */
761 /* */
762 /* INPUTS */
763 /* */
764 /* information Pointer to suspend block */
765 /* */
766 /* OUTPUTS */
767 /* */
768 /* None */
769 /* */
770 /* HISTORY */
771 /* */
772 /* DATE REMARKS */
773 /* */
774 /* 03-01-1993 Created initial version 1.0 */
775 /* 04-19-1993 Verified version 1.0 */
776 /* */
777 /*************************************************************************/
778 VOID SMC_Cleanup(VOID *information)
779 {
780
781 SM_SUSPEND *suspend_ptr; /* Suspension block pointer */
782 NU_SUPERV_USER_VARIABLES
783
784 /* Switch to supervisor mode */
785 NU_SUPERVISOR_MODE();
786
787 /* Use the information pointer as a suspend pointer. */
788 suspend_ptr = (SM_SUSPEND *) information;
789
790 /* By default, indicate that the service timed-out. It really does not
791 matter if this function is called from a terminate request since
792 the task does not resume. */
793 suspend_ptr -> sm_return_status = NU_TIMEOUT;
794
795 /* Decrement the number of tasks waiting counter. */
796 (suspend_ptr -> sm_semaphore) -> sm_tasks_waiting--;
797
798 /* Unlink the suspend block from the suspension list. */
799 CSC_Remove_From_List((CS_NODE **)
800 &((suspend_ptr -> sm_semaphore) -> sm_suspension_list),
801 &(suspend_ptr -> sm_suspend_link));
802
803 /* Return to user mode */
804 NU_USER_MODE();
805 }
806
807
808
809
810
811