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 |
