comparison src/nucleus/pmc.c @ 0:4e78acac3d88

src/{condat,cs,gpf,nucleus}: import from Selenite
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 16 Oct 2020 06:23:26 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:4e78acac3d88
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 /* pmc.c Nucleus PLUS 1.14 */
17 /* */
18 /* COMPONENT */
19 /* */
20 /* PM - Partition Memory Management */
21 /* */
22 /* DESCRIPTION */
23 /* */
24 /* This file contains the core routines for the Partition Memory */
25 /* Management component. */
26 /* */
27 /* DATA STRUCTURES */
28 /* */
29 /* None */
30 /* */
31 /* FUNCTIONS */
32 /* */
33 /* PMC_Create_Partition_Pool Create a Partition Pool */
34 /* PMC_Delete_Partition_Pool Delete a Partition Pool */
35 /* PMC_Allocate_Partition Allocate a partition from a */
36 /* pool */
37 /* PMC_Deallocate_Partition Deallocate a partition from */
38 /* a pool */
39 /* PMC_Cleanup Cleanup on timeout or a */
40 /* terminate condition */
41 /* */
42 /* DEPENDENCIES */
43 /* */
44 /* cs_extr.h Common Service functions */
45 /* tc_extr.h Thread Control functions */
46 /* pm_extr.h Partition functions */
47 /* hi_extr.h History functions */
48 /* */
49 /* HISTORY */
50 /* */
51 /* DATE REMARKS */
52 /* */
53 /* 03-01-1993 Created initial version 1.0 */
54 /* 04-19-1993 Verified version 1.0 */
55 /* 08-09-1993 Corrected pointer retrieval */
56 /* loop, resulting in version 1.0a */
57 /* 08-09-1993 Verified version 1.0a */
58 /* 03-01-1994 Moved non-core functions into */
59 /* supplemental files, changed */
60 /* function interfaces to match */
61 /* those in prototype, added */
62 /* register options, changed */
63 /* protection logic to reduce */
64 /* overhead, resulting in */
65 /* version 1.1 */
66 /* */
67 /* 03-18-1994 Verified version 1.1 */
68 /* 04-17-1996 updated to version 1.2 */
69 /* 03-24-1998 Released version 1.3 */
70 /* 03-26-1999 Released 1.11m (new release */
71 /* numbering scheme) */
72 /* 04-17-2002 Released version 1.13m */
73 /* 11-07-2002 Released version 1.14 */
74 /*************************************************************************/
75 #define NU_SOURCE_FILE
76
77
78 #include "cs_extr.h" /* Common service functions */
79 #include "tc_extr.h" /* Thread control functions */
80 #include "pm_extr.h" /* Partition functions */
81 #include "hi_extr.h" /* History functions */
82 #include "profiler.h" /* ProView interface */
83
84
85 /* Define external inner-component global data references. */
86
87 extern CS_NODE *PMD_Created_Pools_List;
88 extern UNSIGNED PMD_Total_Pools;
89 extern TC_PROTECT PMD_List_Protect;
90
91
92 /* Define internal component function prototypes. */
93
94 VOID PMC_Cleanup(VOID *information);
95
96
97 /*************************************************************************/
98 /* */
99 /* FUNCTION */
100 /* */
101 /* PMC_Create_Partition_Pool */
102 /* */
103 /* DESCRIPTION */
104 /* */
105 /* This function creates a memory partition pool and then places it */
106 /* on the list of created partition pools. */
107 /* */
108 /* CALLED BY */
109 /* */
110 /* Application */
111 /* PMCE_Create_Partition_Pool Error checking shell */
112 /* */
113 /* CALLS */
114 /* */
115 /* CSC_Place_On_List Add node to linked-list */
116 /* [HIC_Make_History_Entry] Make entry in history log */
117 /* [TCT_Check_Stack] Stack checking function */
118 /* TCT_Protect Data structure protect */
119 /* TCT_Unprotect Un-protect data structure */
120 /* */
121 /* INPUTS */
122 /* */
123 /* pool_ptr Partition pool control block */
124 /* pointer */
125 /* name Partition pool name */
126 /* start_address Starting address of the pool */
127 /* pool_size Number of bytes in the pool */
128 /* partition_size Number of bytes in each */
129 /* partition of the pool */
130 /* suspend_type Suspension type */
131 /* */
132 /* OUTPUTS */
133 /* */
134 /* NU_SUCCESS */
135 /* */
136 /* HISTORY */
137 /* */
138 /* DATE REMARKS */
139 /* */
140 /* 03-01-1993 Created initial version 1.0 */
141 /* 04-19-1993 Verified version 1.0 */
142 /* 03-01-1994 Changed function interfaces to */
143 /* match those in prototype, */
144 /* added register options, */
145 /* resulting in version 1.1 */
146 /* */
147 /* 03-18-1994 Verified version 1.1 */
148 /* */
149 /*************************************************************************/
150 STATUS PMC_Create_Partition_Pool(NU_PARTITION_POOL *pool_ptr, CHAR *name,
151 VOID *start_address, UNSIGNED pool_size,
152 UNSIGNED partition_size, OPTION suspend_type)
153 {
154
155 R1 PM_PCB *pool; /* Pool control block ptr */
156 INT i; /* Working index variable */
157 BYTE_PTR pointer; /* Working byte pointer */
158 PM_HEADER *header_ptr; /* Partition block header ptr*/
159 NU_SUPERV_USER_VARIABLES
160
161 /* Switch to supervisor mode */
162 NU_SUPERVISOR_MODE();
163
164 /* Move input pool pointer into internal pointer. */
165 pool = (PM_PCB *) pool_ptr;
166
167
168 #ifdef NU_ENABLE_STACK_CHECK
169
170 /* Call stack checking function to check for an overflow condition. */
171 TCT_Check_Stack();
172
173 #endif
174
175 #ifdef NU_ENABLE_HISTORY
176
177 /* Make an entry that corresponds to this function in the system history
178 log. */
179 HIC_Make_History_Entry(NU_CREATE_PARTITION_POOL_ID, (UNSIGNED) pool,
180 (UNSIGNED) name, (UNSIGNED) start_address);
181
182 #endif
183
184 /* First, clear the partition pool ID just in case it is an old
185 pool control block. */
186 pool -> pm_id = 0;
187
188 /* Fill in the partition pool name. */
189 for (i = 0; i < NU_MAX_NAME; i++)
190 pool -> pm_name[i] = name[i];
191
192 /* Save the starting address and size parameters in the partition control
193 block. */
194 pool -> pm_start_address = start_address;
195 pool -> pm_pool_size = pool_size;
196 pool -> pm_partition_size = partition_size;
197
198 /* Setup the partition pool suspension type. */
199 if (suspend_type == NU_FIFO)
200
201 /* FIFO suspension is selected, setup the flag accordingly. */
202 pool -> pm_fifo_suspend = NU_TRUE;
203 else
204
205 /* Priority suspension is selected. */
206 pool -> pm_fifo_suspend = NU_FALSE;
207
208 /* Clear the suspension list pointer. */
209 pool -> pm_suspension_list = NU_NULL;
210
211 /* Clear the number of tasks waiting on the partition pool. */
212 pool -> pm_tasks_waiting = 0;
213
214 /* Initialize link pointers. */
215 pool -> pm_created.cs_previous = NU_NULL;
216 pool -> pm_created.cs_next = NU_NULL;
217
218 /* Initialize the partition parameters. */
219 pool -> pm_available = 0;
220 pool -> pm_allocated = 0;
221 pool -> pm_available_list = NU_NULL;
222
223 /* Convert the supplied partition size into something that is evenly
224 divisible by the sizeof an UNSIGNED data element. This insures
225 UNSIGNED alignment. */
226 partition_size =
227 ((partition_size + sizeof(UNSIGNED) - 1)/sizeof(UNSIGNED)) *
228 sizeof(UNSIGNED);
229
230 /* Loop to build and link as many partitions as possible from within the
231 specified memory area. */
232 pointer = (BYTE_PTR) start_address;
233 while (pool_size >= (PM_OVERHEAD + partition_size))
234 {
235
236 /* There is room for another partition. */
237
238 /* Cast the current pointer variable to a header pointer. */
239 header_ptr = (PM_HEADER *) pointer;
240
241 /* Now, build a header and link it into the partition pool
242 available list- at the front. */
243 header_ptr -> pm_partition_pool = pool;
244 header_ptr -> pm_next_available = pool -> pm_available_list;
245 pool -> pm_available_list = header_ptr;
246
247 /* Increment the number of partitions available in the pool. */
248 pool -> pm_available++;
249
250 /* Decrement the number of bytes remaining in the pool. */
251 pool_size = pool_size - (PM_OVERHEAD + partition_size);
252
253 /* Increment the working pointer to the next partition position. */
254 pointer = pointer + (PM_OVERHEAD + partition_size);
255 }
256
257 /* Protect against access to the list of created partition pools. */
258 TCT_Protect(&PMD_List_Protect);
259
260 /* At this point the partition pool is completely built. The ID can
261 now be set and it can be linked into the created partition pool list. */
262 pool -> pm_id = PM_PARTITION_ID;
263
264 /* Link the partition pool into the list of created partition pools and
265 increment the total number of pools in the system. */
266 CSC_Place_On_List(&PMD_Created_Pools_List, &(pool -> pm_created));
267 PMD_Total_Pools++;
268
269 #ifdef INCLUDE_PROVIEW
270 _RTProf_DumpPartitionPool(RT_PROF_CREATE_PARTITION_POOL,pool,RT_PROF_OK);
271 #endif /* INCLUDE_PROVIEW */
272 /* Release protection against access to the list of created partition
273 pools. */
274 TCT_Unprotect();
275
276 /* Return to user mode */
277 NU_USER_MODE();
278
279 /* Return successful completion. */
280 return(NU_SUCCESS);
281 }
282
283
284 /*************************************************************************/
285 /* */
286 /* FUNCTION */
287 /* */
288 /* PMC_Delete_Partition_Pool */
289 /* */
290 /* DESCRIPTION */
291 /* */
292 /* This function deletes a memory partition pool and removes it from*/
293 /* the list of created partition pools. All tasks suspended on the */
294 /* partition pool are resumed with the appropriate error status. */
295 /* Note that this function does not free any memory associated with */
296 /* either the pool area or the pool control block. */
297 /* */
298 /* CALLED BY */
299 /* */
300 /* Application */
301 /* PMCE_Delete_Partition_Pool Error checking shell */
302 /* */
303 /* CALLS */
304 /* */
305 /* CSC_Remove_From_List Remove node from list */
306 /* [HIC_Make_History_Entry] Make entry in history log */
307 /* TCC_Resume_Task Resume a suspended task */
308 /* [TCT_Check_Stack] Stack checking function */
309 /* TCT_Control_To_System Transfer control to system */
310 /* TCT_Protect Protect created list */
311 /* TCT_Set_Current_Protect Modify current protection */
312 /* TCT_System_Protect Setup system protection */
313 /* TCT_System_Unprotect Release system protection */
314 /* TCT_Unprotect Release protection */
315 /* */
316 /* INPUTS */
317 /* */
318 /* pool_ptr Partition pool control block */
319 /* pointer */
320 /* */
321 /* OUTPUTS */
322 /* */
323 /* NU_SUCCESS */
324 /* */
325 /* HISTORY */
326 /* */
327 /* DATE REMARKS */
328 /* */
329 /* 03-01-1993 Created initial version 1.0 */
330 /* 04-19-1993 Verified version 1.0 */
331 /* 03-01-1994 Changed function interfaces to */
332 /* match those in prototype, */
333 /* added register options, changed */
334 /* protection logic to reduce */
335 /* overhead, resulting in */
336 /* version 1.1 */
337 /* */
338 /* 03-18-1994 Verified version 1.1 */
339 /* */
340 /*************************************************************************/
341 STATUS PMC_Delete_Partition_Pool(NU_PARTITION_POOL *pool_ptr)
342 {
343
344 R1 PM_PCB *pool; /* Pool control block ptr */
345 PM_SUSPEND *suspend_ptr; /* Suspend block pointer */
346 PM_SUSPEND *next_ptr; /* Next suspend block */
347 STATUS preempt; /* Status for resume call */
348 NU_SUPERV_USER_VARIABLES
349
350 /* Switch to supervisor mode */
351 NU_SUPERVISOR_MODE();
352
353 /* Move input pool pointer into internal pointer. */
354 pool = (PM_PCB *) pool_ptr;
355
356
357 #ifdef NU_ENABLE_STACK_CHECK
358
359 /* Call stack checking function to check for an overflow condition. */
360 TCT_Check_Stack();
361
362 #endif
363
364 #ifdef NU_ENABLE_HISTORY
365
366 /* Make an entry that corresponds to this function in the system history
367 log. */
368 HIC_Make_History_Entry(NU_DELETE_PARTITION_POOL_ID, (UNSIGNED) pool,
369 (UNSIGNED) 0, (UNSIGNED) 0);
370
371 #endif
372
373 /* Protect against simultaneous access to the partition pool. */
374 TCT_System_Protect();
375
376 #ifdef INCLUDE_PROVIEW
377 _RTProf_DumpPartitionPool(RT_PROF_DELETE_PARTITION_POOL,pool,RT_PROF_OK);
378 #endif /* INCLUDE_PROVIEW */
379
380 /* Clear the partition pool ID. */
381 pool -> pm_id = 0;
382
383 /* Release protection. */
384 TCT_Unprotect();
385
386 /* Protect against access to the list of created partition pools. */
387 TCT_Protect(&PMD_List_Protect);
388
389 /* Remove the partition pool from the list of created partition pools. */
390 CSC_Remove_From_List(&PMD_Created_Pools_List, &(pool -> pm_created));
391
392 /* Decrement the total number of created partition pools. */
393 PMD_Total_Pools--;
394
395 /* Pickup the suspended task pointer list. */
396 suspend_ptr = pool -> pm_suspension_list;
397
398 /* Walk the chain task(s) currently suspended on the partition pool. */
399 preempt = 0;
400 while (suspend_ptr)
401 {
402
403 /* Protect against system access. */
404 TCT_System_Protect();
405
406 /* Resume the suspended task. Insure that the status returned is
407 NU_POOL_DELETED. */
408 suspend_ptr -> pm_return_pointer = NU_NULL;
409 suspend_ptr -> pm_return_status = NU_POOL_DELETED;
410
411 /* Point to the next suspend structure in the link. */
412 next_ptr = (PM_SUSPEND *) (suspend_ptr -> pm_suspend_link.cs_next);
413
414 /* Resume the specified task. */
415 preempt = preempt |
416 TCC_Resume_Task((NU_TASK *) suspend_ptr -> pm_suspended_task,
417 NU_PARTITION_SUSPEND);
418
419 /* Determine if the next is the same as the current pointer. */
420 if (next_ptr == pool -> pm_suspension_list)
421
422 /* Clear the suspension pointer to signal the end of the list
423 traversal. */
424 suspend_ptr = NU_NULL;
425 else
426
427 /* Move the next pointer into the suspend block pointer. */
428 suspend_ptr = next_ptr;
429
430 /* Modify current protection. */
431 TCT_Set_Current_Protect(&PMD_List_Protect);
432
433 /* Clear the system protection. */
434 TCT_System_Unprotect();
435 }
436
437 /* Determine if preemption needs to occur. */
438 if (preempt)
439
440 /* Transfer control to system to facilitate preemption. */
441 TCT_Control_To_System();
442
443 /* Release protection against access to the list of created partition
444 pools. */
445 TCT_Unprotect();
446
447 /* Return to user mode */
448 NU_USER_MODE();
449
450 /* Return a successful completion. */
451 return(NU_SUCCESS);
452 }
453
454
455 /*************************************************************************/
456 /* */
457 /* FUNCTION */
458 /* */
459 /* PMC_Allocate_Partition */
460 /* */
461 /* DESCRIPTION */
462 /* */
463 /* This function allocates a memory partition from the specified */
464 /* memory partition pool. If a memory partition is currently */
465 /* available, this function is completed immediately. Otherwise, */
466 /* if there are no partitions currently available, suspension is */
467 /* possible. */
468 /* */
469 /* CALLED BY */
470 /* */
471 /* Application */
472 /* PMCE_Allocate_Partition Error checking shell */
473 /* */
474 /* CALLS */
475 /* */
476 /* CSC_Place_On_List Place on suspend list */
477 /* CSC_Priority_Place_On_List Place on priority list */
478 /* [HIC_Make_History_Entry] Make entry in history log */
479 /* TCC_Suspend_Task Suspend calling task */
480 /* TCC_Task_Priority Pickup task's priority */
481 /* [TCT_Check_Stack] Stack checking function */
482 /* TCT_Current_Thread Pickup current thread pointer*/
483 /* TCT_System_Protect Protect partition pool */
484 /* TCT_Unprotect Release protection */
485 /* */
486 /* INPUTS */
487 /* */
488 /* pool_ptr Memory partition pool pointer*/
489 /* return_pointer Pointer to the destination */
490 /* memory pointer */
491 /* suspend Suspension option if full */
492 /* */
493 /* OUTPUTS */
494 /* */
495 /* NU_SUCCESS If service is successful */
496 /* NU_NO_PARTITION No partitions are available */
497 /* NU_TIMEOUT If timeout on service */
498 /* NU_POOL_DELETED If partition pool deleted */
499 /* during suspension */
500 /* */
501 /* HISTORY */
502 /* */
503 /* DATE REMARKS */
504 /* */
505 /* 03-01-1993 Created initial version 1.0 */
506 /* 04-19-1993 Verified version 1.0 */
507 /* 03-01-1994 Changed function interfaces to */
508 /* match those in prototype, */
509 /* added register options, changed */
510 /* protection logic to reduce */
511 /* overhead, resulting in */
512 /* version 1.1 */
513 /* */
514 /* 03-18-1994 Verified version 1.1 */
515 /* */
516 /*************************************************************************/
517 STATUS PMC_Allocate_Partition(NU_PARTITION_POOL *pool_ptr,
518 VOID **return_pointer, UNSIGNED suspend)
519 {
520
521 R1 PM_PCB *pool; /* Pool control block ptr */
522 R2 PM_SUSPEND *suspend_ptr; /* Suspend block pointer */
523 PM_SUSPEND suspend_block; /* Allocate suspension block */
524 R3 PM_HEADER *partition_ptr; /* Pointer to partition */
525 TC_TCB *task; /* Task pointer */
526 STATUS status; /* Completion status */
527 NU_SUPERV_USER_VARIABLES
528
529 /* Switch to supervisor mode */
530 NU_SUPERVISOR_MODE();
531
532 /* Move input pool pointer into internal pointer. */
533 pool = (PM_PCB *) pool_ptr;
534
535
536 #ifdef NU_ENABLE_STACK_CHECK
537
538 /* Call stack checking function to check for an overflow condition. */
539 TCT_Check_Stack();
540
541 #endif
542
543 #ifdef NU_ENABLE_HISTORY
544
545 /* Make an entry that corresponds to this function in the system history
546 log. */
547 HIC_Make_History_Entry(NU_ALLOCATE_PARTITION_ID, (UNSIGNED) pool,
548 (UNSIGNED) return_pointer, (UNSIGNED) suspend);
549
550 #endif
551
552 /* Initialize the status as successful. */
553 status = NU_SUCCESS;
554
555 /* Protect against simultaneous access to the partition pool. */
556 TCT_System_Protect();
557
558 /* Determine if there is an available memory partition. */
559 if (pool -> pm_available)
560 {
561
562 /* Partition available. */
563
564 /* Decrement the available count. */
565 pool -> pm_available--;
566
567 /* Increment the allocated count. */
568 pool -> pm_allocated++;
569
570 /* Unlink the first memory partition and return the pointer to the
571 caller. */
572 partition_ptr = pool -> pm_available_list;
573 pool -> pm_available_list = partition_ptr -> pm_next_available;
574 partition_ptr -> pm_next_available = NU_NULL;
575
576 /* Return a memory address to the caller. */
577 *return_pointer = (VOID *) (((BYTE_PTR) partition_ptr) + PM_OVERHEAD);
578
579 #ifdef INCLUDE_PROVIEW
580 _RTProf_DumpPartitionPool(RT_PROF_ALLOCATE_PARTITION,pool,RT_PROF_OK);
581 #endif /* INCLUDE_PROVIEW */
582
583 }
584 else
585 {
586
587 /* A partition is not available. Determine if suspension is
588 required. */
589 if (suspend)
590 {
591
592 /* Suspension is selected. */
593
594 /* Increment the number of tasks waiting. */
595 pool -> pm_tasks_waiting++;
596
597 #ifdef INCLUDE_PROVIEW
598 _RTProf_DumpPartitionPool(RT_PROF_ALLOCATE_PARTITION,pool,RT_PROF_WAIT);
599 #endif /* INCLUDE_PROVIEW */
600 /* Setup the suspend block and suspend the calling task. */
601 suspend_ptr = &suspend_block;
602 suspend_ptr -> pm_partition_pool = pool;
603 suspend_ptr -> pm_suspend_link.cs_next = NU_NULL;
604 suspend_ptr -> pm_suspend_link.cs_previous = NU_NULL;
605 task = (TC_TCB *) TCT_Current_Thread();
606 suspend_ptr -> pm_suspended_task = task;
607
608 /* Determine if priority or FIFO suspension is associated with the
609 partition pool. */
610 if (pool -> pm_fifo_suspend)
611 {
612
613 /* FIFO suspension is required. Link the suspend block into
614 the list of suspended tasks on this partition pool. */
615 CSC_Place_On_List((CS_NODE **)
616 &(pool -> pm_suspension_list),
617 &(suspend_ptr -> pm_suspend_link));
618 }
619 else
620 {
621
622 /* Get the priority of the current thread so the suspend block
623 can be placed in the appropriate place. */
624 suspend_ptr -> pm_suspend_link.cs_priority =
625 TCC_Task_Priority(task);
626
627 CSC_Priority_Place_On_List((CS_NODE **)
628 &(pool -> pm_suspension_list),
629 &(suspend_ptr -> pm_suspend_link));
630 }
631
632 /* Finally, suspend the calling task. Note that the suspension call
633 automatically clears the protection on the partition pool. */
634 TCC_Suspend_Task((NU_TASK *) task, NU_PARTITION_SUSPEND,
635 PMC_Cleanup, suspend_ptr, suspend);
636
637 /* Pickup the return status. */
638 status = suspend_ptr -> pm_return_status;
639 *return_pointer = suspend_ptr -> pm_return_pointer;
640 }
641 else
642 {
643 /* No suspension requested. Simply return an error status. */
644 status = NU_NO_PARTITION;
645
646 #ifdef INCLUDE_PROVIEW
647 _RTProf_DumpPartitionPool(RT_PROF_ALLOCATE_PARTITION,pool,RT_PROF_FAIL);
648 #endif /* INCLUDE_PROVIEW */
649 }
650 }
651
652 /* Release protection of the partition pool. */
653 TCT_Unprotect();
654
655 /* Return to user mode */
656 NU_USER_MODE();
657
658 /* Return the completion status. */
659 return(status);
660 }
661
662
663 /*************************************************************************/
664 /* */
665 /* FUNCTION */
666 /* */
667 /* PMC_Deallocate_Partition */
668 /* */
669 /* DESCRIPTION */
670 /* */
671 /* This function deallocates a previously allocated partition. If */
672 /* there is a task waiting for a partition, the partition is simply */
673 /* given to the waiting task and the waiting task is resumed. */
674 /* Otherwise, the partition is returned to the partition pool. */
675 /* */
676 /* CALLED BY */
677 /* */
678 /* Application */
679 /* PMCE_Deallocate_Partition Error checking shell */
680 /* */
681 /* CALLS */
682 /* */
683 /* CSC_Remove_From_List Remove from suspend list */
684 /* [HIC_Make_History_Entry] Make entry in history log */
685 /* TCC_Resume_Task Resume a suspended task */
686 /* [TCT_Check_Stack] Stack checking function */
687 /* TCT_Control_To_System Transfer control to system */
688 /* TCT_System_Protect Protect partition pool */
689 /* TCT_Unprotect Release protection */
690 /* */
691 /* INPUTS */
692 /* */
693 /* partition Pointer to partition memory */
694 /* */
695 /* OUTPUTS */
696 /* */
697 /* NU_SUCCESS */
698 /* */
699 /* HISTORY */
700 /* */
701 /* DATE REMARKS */
702 /* */
703 /* 03-01-1993 Created initial version 1.0 */
704 /* 04-19-1993 Verified version 1.0 */
705 /* 03-01-1994 Added register options, changed */
706 /* protection logic to reduce */
707 /* overhead, resulting in */
708 /* version 1.1 */
709 /* */
710 /* 03-18-1994 Verified version 1.1 */
711 /* */
712 /*************************************************************************/
713 STATUS PMC_Deallocate_Partition(VOID *partition)
714 {
715
716 R1 PM_PCB *pool; /* Pool pointer */
717 R3 PM_SUSPEND *suspend_ptr; /* Pointer to suspend block */
718 R2 PM_HEADER *header_ptr; /* Pointer to partition hdr */
719 STATUS preempt; /* Preemption flag */
720 STATUS status; /* Completion status */
721 NU_SUPERV_USER_VARIABLES
722
723 /* Switch to supervisor mode */
724 NU_SUPERVISOR_MODE();
725
726 #ifdef NU_ENABLE_STACK_CHECK
727
728 /* Call stack checking function to check for an overflow condition. */
729 TCT_Check_Stack();
730
731 #endif
732
733 #ifdef NU_ENABLE_HISTORY
734
735 /* Make an entry that corresponds to this function in the system history
736 log. */
737 HIC_Make_History_Entry(NU_DEALLOCATE_PARTITION_ID, (UNSIGNED) partition,
738 (UNSIGNED) 0, (UNSIGNED) 0);
739
740 #endif
741
742 /* Initialize the status as successful. */
743 status = NU_SUCCESS;
744
745 /* Pickup the associated pool's pointer. It is inside the header of
746 each partition. */
747 header_ptr = (PM_HEADER *) (((BYTE_PTR) partition) - PM_OVERHEAD);
748 pool = header_ptr -> pm_partition_pool;
749
750 /* Protect against simultaneous access to the partition pool. */
751 TCT_System_Protect();
752
753 /* Determine if another task is waiting for a partition from the pool. */
754 if (pool -> pm_tasks_waiting)
755 {
756
757 /* Yes, another task is waiting for a partition from the pool. */
758
759 /* Decrement the number of tasks waiting counter. */
760 pool -> pm_tasks_waiting--;
761
762 #ifdef INCLUDE_PROVIEW
763 _RTProf_DumpPartitionPool(RT_PROF_DEALLOCATE_PARTITION,pool,RT_PROF_OK);
764 #endif /* INCLUDE_PROVIEW */
765
766 /* Remove the first suspended block from the list. */
767 suspend_ptr = pool -> pm_suspension_list;
768 CSC_Remove_From_List((CS_NODE **) &(pool -> pm_suspension_list),
769 &(suspend_ptr -> pm_suspend_link));
770
771 /* Setup the appropriate return value. */
772 suspend_ptr -> pm_return_status = NU_SUCCESS;
773 suspend_ptr -> pm_return_pointer = partition;
774
775 /* Resume the suspended task. */
776 preempt =
777 TCC_Resume_Task((NU_TASK *) suspend_ptr -> pm_suspended_task,
778 NU_PARTITION_SUSPEND);
779
780 /* Determine if a preempt condition is present. */
781 if (preempt)
782
783 /* Transfer control to the system if the resumed task function
784 detects a preemption condition. */
785 TCT_Control_To_System();
786 }
787 else
788 {
789
790 /* Increment the available partitions counter. */
791 pool -> pm_available++;
792
793 /* Decrement the allocated partitions counter. */
794 pool -> pm_allocated--;
795
796 /* Place the partition back on the available list. */
797 header_ptr -> pm_next_available = pool -> pm_available_list;
798 pool -> pm_available_list = header_ptr;
799
800 #ifdef INCLUDE_PROVIEW
801 _RTProf_DumpPartitionPool(RT_PROF_DEALLOCATE_PARTITION,pool,RT_PROF_OK);
802 #endif /* INCLUDE_PROVIEW */
803
804 }
805
806 /* Release protection of the partition pool. */
807 TCT_Unprotect();
808
809 /* Return to user mode */
810 NU_USER_MODE();
811
812 /* Return the completion status. */
813 return(status);
814 }
815
816
817 /*************************************************************************/
818 /* */
819 /* FUNCTION */
820 /* */
821 /* PMC_Cleanup */
822 /* */
823 /* DESCRIPTION */
824 /* */
825 /* This function is responsible for removing a suspension block */
826 /* from a partition pool. It is not called unless a timeout or */
827 /* a task terminate is in progress. Note that protection is */
828 /* already in effect - the same protection at suspension time. */
829 /* */
830 /* CALLED BY */
831 /* */
832 /* TCC_Timeout Task timeout */
833 /* TCC_Terminate Task terminate */
834 /* */
835 /* CALLS */
836 /* */
837 /* CSC_Remove_From_List Remove suspend block from */
838 /* the suspension list */
839 /* */
840 /* INPUTS */
841 /* */
842 /* information Pointer to suspend block */
843 /* */
844 /* OUTPUTS */
845 /* */
846 /* None */
847 /* */
848 /* HISTORY */
849 /* */
850 /* DATE REMARKS */
851 /* */
852 /* 03-01-1993 Created initial version 1.0 */
853 /* 04-19-1993 Verified version 1.0 */
854 /* */
855 /*************************************************************************/
856 VOID PMC_Cleanup(VOID *information)
857 {
858
859 PM_SUSPEND *suspend_ptr; /* Suspension block pointer */
860 NU_SUPERV_USER_VARIABLES
861
862 /* Switch to supervisor mode */
863 NU_SUPERVISOR_MODE();
864
865 /* Use the information pointer as a suspend pointer. */
866 suspend_ptr = (PM_SUSPEND *) information;
867
868 /* By default, indicate that the service timed-out. It really does not
869 matter if this function is called from a terminate request since
870 the task does not resume. */
871 suspend_ptr -> pm_return_status = NU_TIMEOUT;
872 suspend_ptr -> pm_return_pointer = NU_NULL;
873
874 /* Decrement the number of tasks waiting counter. */
875 (suspend_ptr -> pm_partition_pool) -> pm_tasks_waiting--;
876
877 /* Unlink the suspend block from the suspension list. */
878 CSC_Remove_From_List((CS_NODE **)
879 &((suspend_ptr -> pm_partition_pool) -> pm_suspension_list),
880 &(suspend_ptr -> pm_suspend_link));
881
882 /* Return to user mode */
883 NU_USER_MODE();
884 }
885
886
887
888
889