FreeCalypso > hg > ffs-editor
comparison src/nucleus/pmc.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 /* 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 |