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  *          &nbsp;&nbsp;	// 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