1 /*! @header QuesaMemory.h 2 Declares the Quesa memory manager. 3 */ 4 /* NAME: 5 QuesaMemory.h 6 7 DESCRIPTION: 8 Quesa public header. 9 10 COPYRIGHT: 11 Copyright (c) 1999-2004, Quesa Developers. All rights reserved. 12 13 For the current release of Quesa, please see: 14 15 <http://www.quesa.org/> 16 17 Redistribution and use in source and binary forms, with or without 18 modification, are permitted provided that the following conditions 19 are met: 20 21 o Redistributions of source code must retain the above copyright 22 notice, this list of conditions and the following disclaimer. 23 24 o Redistributions in binary form must reproduce the above 25 copyright notice, this list of conditions and the following 26 disclaimer in the documentation and/or other materials provided 27 with the distribution. 28 29 o Neither the name of Quesa nor the names of its contributors 30 may be used to endorse or promote products derived from this 31 software without specific prior written permission. 32 33 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 34 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 35 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 36 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 37 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 38 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 39 TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 40 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 41 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 42 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 43 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 44 ___________________________________________________________________________ 45 */ 46 #ifndef QUESA_MEMORY_HDR 47 #define QUESA_MEMORY_HDR 48 //============================================================================= 49 // Include files 50 //----------------------------------------------------------------------------- 51 #include "Quesa.h" 52 53 54 55 56 57 //============================================================================= 58 // C++ preamble 59 //----------------------------------------------------------------------------- 60 #ifdef __cplusplus 61 extern "C" { 62 #endif 63 64 65 66 67 68 //============================================================================= 69 // Constants 70 //----------------------------------------------------------------------------- 71 /*! 72 @constant kQ3MemoryStatisticsStructureVersion 73 @abstract Current version of TQ3MemoryStatistics structure. 74 */ 75 #define kQ3MemoryStatisticsStructureVersion 1 76 77 78 79 80 81 //============================================================================= 82 // Types 83 //----------------------------------------------------------------------------- 84 /*! 85 @struct TQ3MemoryStatistics 86 @abstract Parameter structure for Q3Memory_GetStatistics. 87 @field structureVersion Version of this structure. 88 Initialize to kQ3MemoryStatisticsStructureVersion. 89 @field currentAllocations Current number of memory blocks allocated by Quesa. 90 @field maxAllocations Maximum number of memory blocks allocated by Quesa. 91 @field currentBytes Current number of memory bytes allocated by Quesa. 92 @field maxBytes Maximum number of memory bytes allocated by Quesa 93 ("high-water mark"). 94 */ 95 typedef struct TQ3MemoryStatistics 96 { 97 TQ3Uns32 structureVersion; 98 TQ3Uns32 currentAllocations; 99 TQ3Uns32 maxAllocations; 100 TQ3Int64 currentBytes; 101 TQ3Int64 maxBytes; 102 } TQ3MemoryStatistics; 103 104 105 106 107 108 //============================================================================= 109 // Function prototypes 110 //----------------------------------------------------------------------------- 111 /*! 112 * @function 113 * Q3Memory_Allocate 114 * @discussion 115 * Allocates a block of memory of the specified size. 116 * 117 * The pointer returned must be disposed of with Q3Memory_Free. 118 * The initial contents of the block are undefined. 119 * 120 * <em>This function is not available in QD3D.</em> 121 * 122 * @param theSize The size in bytes of the block to allocate. 123 * @result A pointer to the block. 124 */ 125 #if QUESA_ALLOW_QD3D_EXTENSIONS 126 127 Q3_EXTERN_API_C ( void * ) 128 Q3Memory_Allocate ( 129 TQ3Uns32 theSize 130 ); 131 132 #endif // QUESA_ALLOW_QD3D_EXTENSIONS 133 134 135 136 /*! 137 * @function 138 * Q3Memory_AllocateClear 139 * @discussion 140 * Allocates a zero-filled block of memory of the specified size. 141 * 142 * The pointer returned must be disposed of with Q3Memory_Free. 143 * 144 * <em>This function is not available in QD3D.</em> 145 * 146 * @param theSize The size in bytes of the block to allocate. 147 * @result A pointer to the block. 148 */ 149 #if QUESA_ALLOW_QD3D_EXTENSIONS 150 151 Q3_EXTERN_API_C ( void * ) 152 Q3Memory_AllocateClear ( 153 TQ3Uns32 theSize 154 ); 155 156 #endif // QUESA_ALLOW_QD3D_EXTENSIONS 157 158 159 160 /*! 161 * @function 162 * Q3Memory_Free 163 * @discussion 164 * Frees a previously allocated block of memory. 165 * 166 * Takes a pointer to a pointer, which points to a block of previously 167 * allocated memory. 168 * 169 * After freeing the memory, the supplied pointer will be reset to NULL 170 * to prevent future dereferences. 171 * 172 * Note that you <em>must</em> pass a pointer to a pointer, and not 173 * simply the pointer to the allocated memory. The double-indirection 174 * is deliberate, to ensure that the pointer can be fully invalidated 175 * after disposal. 176 * 177 * <em>This function is not available in QD3D.</em> 178 * 179 * @param thePtr A pointer to the pointer to free. 180 */ 181 #if QUESA_ALLOW_QD3D_EXTENSIONS 182 183 #undef Q3Memory_Free 184 #define Q3Memory_Free Q3Memory_Free_ 185 186 Q3_EXTERN_API_C ( void ) 187 Q3Memory_Free ( 188 void **thePtr 189 ); 190 191 #undef Q3Memory_Free 192 #define Q3Memory_Free(_x) Q3Memory_Free_((void **) (_x)) 193 194 #endif // QUESA_ALLOW_QD3D_EXTENSIONS 195 196 197 198 /*! 199 * @function 200 * Q3Memory_Reallocate 201 * @discussion 202 * Attempts to reallocate a previously allocated block of memory. 203 * 204 * Implements the same behaviour as realloc, allowing memory to 205 * be allocated, freed, or resized with a single call. See the 206 * documentation for realloc for the exact specification. 207 * Unlike some implementations of realloc, passing a size of zero 208 * frees the memory and returns NULL. 209 * 210 * Note that like Q3Memory_Free, a pointer to the pointer is 211 * passed to allow it to be set to NULL after disposal, and to 212 * allow it to be changed when resized. 213 * 214 * <em>This function is not available in QD3D.</em> 215 * 216 * @param thePtr A pointer to the pointer to reallocate. 217 * @param newSize The size in bytes to reallocate the block to. 218 * @result Success or failure of the operation. 219 */ 220 #if QUESA_ALLOW_QD3D_EXTENSIONS 221 222 #undef Q3Memory_Reallocate 223 #define Q3Memory_Reallocate Q3Memory_Reallocate_ 224 225 Q3_EXTERN_API_C ( TQ3Status ) 226 Q3Memory_Reallocate ( 227 void **thePtr, 228 TQ3Uns32 newSize 229 ); 230 231 #undef Q3Memory_Reallocate 232 #define Q3Memory_Reallocate(_x, _y) Q3Memory_Reallocate_((void **) (_x), (_y)) 233 234 #endif // QUESA_ALLOW_QD3D_EXTENSIONS 235 236 237 238 /*! 239 * @function 240 * Q3Memory_Initialize 241 * @discussion 242 * Initialises a block of memory. 243 * 244 * Sets theSize bytes from thePtr to theValue. 245 * 246 * <em>This function is not available in QD3D.</em> 247 * 248 * @param thePtr A pointer to the memory to set. 249 * @param theSize The number of bytes to set. 250 * @param theValue The value to set at each byte. 251 */ 252 #if QUESA_ALLOW_QD3D_EXTENSIONS 253 254 Q3_EXTERN_API_C ( void ) 255 Q3Memory_Initialize ( 256 void *thePtr, 257 TQ3Uns32 theSize, 258 TQ3Uns8 theValue 259 ); 260 261 #endif // QUESA_ALLOW_QD3D_EXTENSIONS 262 263 264 265 /*! 266 * @function 267 * Q3Memory_Clear 268 * @discussion 269 * Clears a block of memory. 270 * 271 * Sets theSize bytes from thePtr to 0. 272 * 273 * <em>This function is not available in QD3D.</em> 274 * 275 * @param thePtr A pointer to the memory to set. 276 * @param theSize The number of bytes to set. 277 */ 278 #if QUESA_ALLOW_QD3D_EXTENSIONS 279 280 Q3_EXTERN_API_C ( void ) 281 Q3Memory_Clear ( 282 void *thePtr, 283 TQ3Uns32 theSize 284 ); 285 286 #endif // QUESA_ALLOW_QD3D_EXTENSIONS 287 288 289 290 /*! 291 * @function 292 * Q3Memory_Copy 293 * @discussion 294 * Copies a block of memory. 295 * 296 * Copies theSize bytes from srcPtr to dstPtr. The memory pointed to by 297 * srcPtr and dstPtr is allowed to overlap, although this may reduce 298 * performance. 299 * 300 * <em>This function is not available in QD3D.</em> 301 * 302 * @param srcPtr A pointer to the block to copy. 303 * @param dstPtr A pointer to the memory to copy to. 304 * @param theSize The number of bytes to copy. 305 */ 306 #if QUESA_ALLOW_QD3D_EXTENSIONS 307 308 Q3_EXTERN_API_C ( void ) 309 Q3Memory_Copy ( 310 const void *srcPtr, 311 void *dstPtr, 312 TQ3Uns32 theSize 313 ); 314 315 #endif // QUESA_ALLOW_QD3D_EXTENSIONS 316 317 318 319 /*! 320 * @function 321 * Q3Memory_StartRecording 322 * @discussion 323 * Begin recording allocations of Quesa objects. 324 * 325 * In non-debug builds, this function does nothing. 326 * 327 * <em>This function is not available in QD3D.</em> 328 * 329 * @result Success or failure of the operation. 330 */ 331 #if QUESA_ALLOW_QD3D_EXTENSIONS 332 333 Q3_EXTERN_API_C ( TQ3Status ) 334 Q3Memory_StartRecording( 335 void 336 ); 337 338 #endif // QUESA_ALLOW_QD3D_EXTENSIONS 339 340 341 342 /*! 343 * @function 344 * Q3Memory_StopRecording 345 * @discussion 346 * Stop recording allocations of Quesa objects. 347 * 348 * In non-debug builds, this function does nothing. 349 * 350 * <em>This function is not available in QD3D.</em> 351 * 352 * @result Success or failure of the operation. 353 */ 354 #if QUESA_ALLOW_QD3D_EXTENSIONS 355 356 Q3_EXTERN_API_C ( TQ3Status ) 357 Q3Memory_StopRecording( 358 void 359 ); 360 361 #endif // QUESA_ALLOW_QD3D_EXTENSIONS 362 363 364 365 /*! 366 * @function 367 * Q3Memory_IsRecording 368 * @discussion 369 * Determine whether object allocations are being recorded. 370 * 371 * <em>This function is not available in QD3D.</em> 372 * 373 * @result kQ3True if allocation recording is on. 374 */ 375 #if QUESA_ALLOW_QD3D_EXTENSIONS 376 377 Q3_EXTERN_API_C ( TQ3Boolean ) 378 Q3Memory_IsRecording( 379 void 380 ); 381 382 #endif // QUESA_ALLOW_QD3D_EXTENSIONS 383 384 385 386 /*! 387 * @function 388 * Q3Memory_ForgetRecording 389 * @discussion 390 * Forget any previously recorded allocations of Quesa objects. 391 * 392 * In non-debug builds, this function does nothing. 393 * 394 * <em>This function is not available in QD3D.</em> 395 * 396 * @result Success or failure of the operation. 397 */ 398 #if QUESA_ALLOW_QD3D_EXTENSIONS 399 400 Q3_EXTERN_API_C ( TQ3Status ) 401 Q3Memory_ForgetRecording( 402 void 403 ); 404 405 #endif // QUESA_ALLOW_QD3D_EXTENSIONS 406 407 408 409 /*! 410 * @function 411 * Q3Memory_CountRecords 412 * @discussion 413 * Return the number of recorded allocations of Quesa objects. 414 * 415 * In non-debug builds, this function returns 0. 416 * 417 * <em>This function is not available in QD3D.</em> 418 * 419 * @result Success or failure of the operation. 420 */ 421 #if QUESA_ALLOW_QD3D_EXTENSIONS 422 423 Q3_EXTERN_API_C ( TQ3Uns32 ) 424 Q3Memory_CountRecords( 425 void 426 ); 427 428 #endif // QUESA_ALLOW_QD3D_EXTENSIONS 429 430 431 432 /*! 433 * @function 434 * Q3Memory_NextRecordedObject 435 * @discussion 436 * This function can be used to iterate through the list 437 * of Quesa objects that were created while recording was 438 * turned on. Pass NULL to get the first object in the list. 439 * When it returns NULL, you have reached the end. 440 * 441 * Example: 442 * 443 * <blockquote><pre><code> 444 * TQ3Object leaked = NULL; 445 * while (NULL != (leaked = Q3Memory_NextRecordedObject( leaked ))) 446 * { 447 * // do something nondestructive to the object 448 * } 449 * </code></pre></blockquote> 450 * 451 * In non-debug builds, this function always returns NULL. 452 * 453 * <em>This function is not available in QD3D.</em> 454 * 455 * @param inObject NULL or a recorded object. 456 * @result Next recorded object, or NULL. 457 */ 458 #if QUESA_ALLOW_QD3D_EXTENSIONS 459 460 Q3_EXTERN_API_C ( TQ3Object ) 461 Q3Memory_NextRecordedObject( 462 TQ3Object inObject 463 ); 464 465 #endif // QUESA_ALLOW_QD3D_EXTENSIONS 466 467 468 469 /*! 470 * @function 471 * Q3Memory_DumpRecording 472 * @discussion 473 * Write a text file listing Quesa objects that were created when 474 * recording was turned on and still exist. If there is already a 475 * file in the default directory with the specified name, new text 476 * is appended to it. 477 * 478 * In non-debug builds, this function does nothing. 479 * 480 * If recording is on when Q3Exit shuts down Quesa, this function 481 * will be called for you. 482 * 483 * <em>This function is not available in QD3D.</em> 484 * 485 * @param fileName Name of memory dump file. 486 * @param memo Text written at start of dump for identification. May be NULL. 487 * @result Success or failure of the operation. 488 */ 489 #if QUESA_ALLOW_QD3D_EXTENSIONS 490 491 Q3_EXTERN_API_C ( TQ3Status ) 492 Q3Memory_DumpRecording( 493 const char *fileName, 494 const char *memo 495 ); 496 497 #endif // QUESA_ALLOW_QD3D_EXTENSIONS 498 499 500 501 /*! 502 * @function 503 * Q3Memory_GetStatistics 504 * @abstract 505 * Get information about Quesa memory usage. 506 * 507 * @discussion 508 * Retrieve debugging statistics about memory allocations by Quesa. 509 * 510 * In non-debug builds (compiled with Q3_DEBUG or Q3_MEMORY_DEBUG set to 0) 511 * this function returns kQ3Failure. 512 * 513 * <em>This function is not available in QD3D.</em> 514 * 515 * @param info Structure to receive memory statistics. You must initialize 516 * the structureVersion field to kQ3MemoryStatisticsStructureVersion. 517 * @result Success or failure of the operation. 518 */ 519 #if QUESA_ALLOW_QD3D_EXTENSIONS 520 521 Q3_EXTERN_API_C ( TQ3Status ) 522 Q3Memory_GetStatistics( 523 TQ3MemoryStatistics* info 524 ); 525 526 #endif // QUESA_ALLOW_QD3D_EXTENSIONS 527 528 529 530 /*! 531 * @function 532 * Q3SlabMemory_New 533 * @discussion 534 * Create a new memory slab object. 535 * 536 * A slab may be created with an initial number of allocated items, which can 537 * be optionally initialised with supplied data. 538 * 539 * Either numItems or itemData may be 0 (or NULL, respectively), however if 540 * itemData is non-NULL then numItems should be non-zero. 541 * 542 * The itemSize parameter must be non-zero. 543 * 544 * <em>This function is not available in QD3D.</em> 545 * 546 * @param itemSize The size of each item within the slab. 547 * @param numitems The initial number of items in the slab. 548 * @param itemData The data to initialise the new items, or NULL. 549 * @result The new slab object. 550 */ 551 #if QUESA_ALLOW_QD3D_EXTENSIONS 552 553 Q3_EXTERN_API_C ( TQ3SlabObject ) 554 Q3SlabMemory_New( 555 TQ3Uns32 itemSize, 556 TQ3Uns32 numItems, 557 const void *itemData 558 ); 559 560 #endif // QUESA_ALLOW_QD3D_EXTENSIONS 561 562 563 564 /*! 565 * @function 566 * Q3SlabMemory_GetData 567 * @discussion 568 * Get a pointer to the data for an item within a slab. 569 * 570 * Items are stored contiguously within a slab, and are indexed from 0. 571 * 572 * The item index must be between 0 and the number of items in the slab, 573 * which can be obtained with Q3SlabMemory_GetCount. 574 * 575 * <em>This function is not available in QD3D.</em> 576 * 577 * @param theSlab The slab to query. 578 * @param itemIndex The index of the item within the slab. 579 * @result A pointer to the specified item within the slab. 580 */ 581 #if QUESA_ALLOW_QD3D_EXTENSIONS 582 583 Q3_EXTERN_API_C ( void * ) 584 Q3SlabMemory_GetData( 585 TQ3SlabObject theSlab, 586 TQ3Uns32 itemIndex 587 ); 588 589 #endif // QUESA_ALLOW_QD3D_EXTENSIONS 590 591 592 /*! 593 * @function 594 * Q3SlabMemory_AppendData 595 * @discussion 596 * Append items to the end of a slab. 597 * 598 * The slab will be grown as required, and the specified number of items 599 * will be appended to the end of the slab. A pointer to the newly-added 600 * items within the slab will be returned, or NULL on failure. 601 * 602 * The slab may move in memory when it is grown, and any existing pointers 603 * into the slab should be invalidated. 604 * 605 * 606 * If itemData is non-NULL, it is assumed to point to a contiguous block 607 * of item data. This data is copied into the slab to initialise the new 608 * items. 609 * 610 * If no initialisation data is supplied, the contents of the items will 611 * be left uninitialised. 612 * 613 * 614 * <em>This function is not available in QD3D.</em> 615 * 616 * @param theSlab The slab to update. 617 * @param numItems The number of items to append. 618 * @param itemData The data to initialise the new items, or NULL. 619 * @result A pointer to the first newly-added item within the slab. 620 */ 621 #if QUESA_ALLOW_QD3D_EXTENSIONS 622 623 Q3_EXTERN_API_C ( void * ) 624 Q3SlabMemory_AppendData( 625 TQ3SlabObject theSlab, 626 TQ3Uns32 numItems, 627 const void *itemData 628 ); 629 630 #endif // QUESA_ALLOW_QD3D_EXTENSIONS 631 632 633 /*! 634 * @function 635 * Q3SlabMemory_GetCount 636 * @discussion 637 * Get the number of items within a slab. 638 * 639 * <em>This function is not available in QD3D.</em> 640 * 641 * @param theSlab The slab to query. 642 * @result The number of items within the slab. 643 */ 644 #if QUESA_ALLOW_QD3D_EXTENSIONS 645 646 Q3_EXTERN_API_C ( TQ3Uns32 ) 647 Q3SlabMemory_GetCount( 648 TQ3SlabObject theSlab 649 ); 650 651 #endif // QUESA_ALLOW_QD3D_EXTENSIONS 652 653 654 655 /*! 656 * @function 657 * Q3SlabMemory_SetCount 658 * @discussion 659 * Set the number of items within a slab. 660 * 661 * Existing items within the slab will be preserved when the slab is 662 * grown, and lost when the slab is shrunk. 663 * 664 * The slab may move in memory on any resize operation, and pointers 665 * into the slab should be invalidated. 666 * 667 * <em>This function is not available in QD3D.</em> 668 * 669 * @param theSlab The slab to update. 670 * @param numItems The number of items required in the slab. 671 * @result Success or failure of the operation. 672 */ 673 #if QUESA_ALLOW_QD3D_EXTENSIONS 674 675 Q3_EXTERN_API_C ( TQ3Status ) 676 Q3SlabMemory_SetCount( 677 TQ3SlabObject theSlab, 678 TQ3Uns32 numItems 679 ); 680 681 #endif // QUESA_ALLOW_QD3D_EXTENSIONS 682 683 684 685 686 687 //============================================================================= 688 // C++ postamble 689 //----------------------------------------------------------------------------- 690 #ifdef __cplusplus 691 } 692 #endif 693 694 #endif 695 696 697