Table of Contents

include/AK/SoundEngine/Common/AkMemoryMgr.h

Go to the documentation of this file.
00001 /*******************************************************************************
00002 The content of this file includes portions of the AUDIOKINETIC Wwise Technology
00003 released in source code form as part of the SDK installer package.
00004 
00005 Commercial License Usage
00006 
00007 Licensees holding valid commercial licenses to the AUDIOKINETIC Wwise Technology
00008 may use this file in accordance with the end user license agreement provided 
00009 with the software or, alternatively, in accordance with the terms contained in a
00010 written agreement between you and Audiokinetic Inc.
00011 
00012 Apache License Usage
00013 
00014 Alternatively, this file may be used under the Apache License, Version 2.0 (the 
00015 "Apache License"); you may not use this file except in compliance with the 
00016 Apache License. You may obtain a copy of the Apache License at 
00017 http://www.apache.org/licenses/LICENSE-2.0.
00018 
00019 Unless required by applicable law or agreed to in writing, software distributed
00020 under the Apache License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
00021 OR CONDITIONS OF ANY KIND, either express or implied. See the Apache License for
00022 the specific language governing permissions and limitations under the License.
00023 
00024   Version: <VERSION>  Build: <BUILDNUMBER>
00025   Copyright (c) <COPYRIGHTYEAR> Audiokinetic Inc.
00026 *******************************************************************************/
00027 
00028 /// \file 
00029 /// Memory Manager namespace.
00030 
00031 #ifndef _AKMEMORYMGR_H_
00032 #define _AKMEMORYMGR_H_
00033 
00034 #include <AK/SoundEngine/Common/AkTypes.h>
00035 #include <AK/SoundEngine/Common/AkSoundEngineExport.h>
00036 
00037 #ifndef AK_OPTIMIZED
00038 
00039 #define AK_MAX_MEM_POOL_NAME_SIZE 64
00040 
00041 /// Set the debug name for a pool. This is the name shown in the Memory tab of the Advanced Profiler.
00042 #define AK_SETPOOLNAME( _poolid, _name )                \
00043     if( AK_INVALID_POOL_ID != _poolid )                 \
00044     {                                                   \
00045         AK::MemoryMgr::SetPoolName( _poolid, _name );   \
00046     }
00047 
00048 // #define AK_MEMDEBUG
00049 
00050 #ifdef MSTC_SYSTEMATIC_MEMORY_STRESS
00051 #define AK_MEMDEBUG
00052 #endif
00053 
00054 #else
00055 #define AK_SETPOOLNAME(_poolid,_name)
00056 #endif
00057 
00058 
00059 namespace AK
00060 {   
00061     /// Memory Manager namespace.
00062     /// \remarks The functions in this namespace are thread-safe, unless stated otherwise.
00063     /// \sa
00064     /// - \ref memorymanager
00065     namespace MemoryMgr
00066     {
00067         /// Memory pool statistics. 
00068         /// \remarks These statistics are not collected in the Release configuration of 
00069         /// the default memory manager implementation.
00070         /// \sa 
00071         /// - AK::MemoryMgr::GetPoolStats()
00072         /// - \ref memorymanager
00073         struct PoolStats
00074         {
00075             // Current state
00076             AkUInt32 uReserved;     ///< Reserved memory (in bytes)
00077             AkUInt32 uUsed;         ///< Used memory (in bytes)
00078             AkUInt32 uMaxFreeBlock; ///< Size of biggest free block (in bytes)
00079 
00080             // Statistics
00081             AkUInt32 uAllocs;       ///< Number of Alloc calls since initialization
00082             AkUInt32 uFrees;        ///< Number of Free calls since initialization
00083             AkUInt32 uPeakUsed;     ///< Peak used memory (in bytes)
00084         };
00085 
00086         /// Memory pool current state. 
00087         /// \sa 
00088         /// - AK::MemoryMgr::GetPoolMemoryUsed()
00089         /// - \ref memorymanager
00090         struct PoolMemInfo
00091         {
00092             // Current state
00093             AkUInt32 uReserved;     ///< Reserved memory (in bytes)
00094             AkUInt32 uUsed;         ///< Used memory (in bytes)
00095         };
00096 
00097 
00098         /// Memory management debug tools.  When specified in Init, each memory allocation will have a extra tag that can be verified periodically.
00099         /// Enabling this will use a lot of CPU and additional memory.  This should not be enabled unless required by Audiokinetic's support.  These are enabled in Debug configuration only.
00100         enum DebugFlags
00101         {
00102             CheckOverwriteAtFree = 1,   ///< Performs a for buffer overflow when an allocation is freed.
00103             CheckOverwritePerFrame = 2, ///< Performs a check for buffer overflow once per audio frame
00104             CheckOverwritePerVoice = 4, ///< Performs a check for buffer overflow once per audio voice          
00105         };
00106 
00107         /// Query whether the Memory Manager has been sucessfully initialized.
00108         /// \warning This function is not thread-safe. It should not be called at the same time as MemoryMgr::Init or MemoryMgr::Term.
00109         /// \return True if the Memory Manager is initialized, False otherwise
00110         /// \sa 
00111         /// - AK::MemoryMgr::Init()
00112         /// - \ref memorymanager
00113         AK_EXTERNAPIFUNC( bool, IsInitialized )();
00114 
00115         /// Terminate the Memory Manager.
00116         /// \warning This function is not thread-safe. 
00117         /// \sa
00118         /// - \ref memorymanager
00119         AK_EXTERNAPIFUNC( void, Term )();
00120 
00121         ////////////////////////////////////////////////////////////////////////
00122         /// @name Memory Pools
00123         //@{
00124 
00125         /// Create a new memory pool.
00126         /// \return The ID of the created memory pool, or AK_INVALID_POOL_ID if creation failed
00127         /// \aktip
00128         /// Refer to \ref memorymanager_pools for information about pool resource overhead.
00129         /// \endaktip
00130         /// \sa
00131         /// - \ref memorymanager
00132         AK_EXTERNAPIFUNC( AkMemPoolId, CreatePool )(
00133             void *          in_pMemAddress,     ///< Memory address of the pool, or NULL if it should be allocated
00134             AkUInt32        in_uMemSize,        ///< Size of the pool (in bytes)
00135             AkUInt32        in_uBlockSize,      ///< Size of a block (in bytes)
00136             AkUInt32        in_eAttributes,     ///< Memory pool attributes: use values of \ref AkMemPoolAttributes
00137             AkUInt32        in_uBlockAlign = 0  ///< Alignment of memory blocks. 
00138                                                 ///< Some plug-ins and specific processors may require specific data alignment.
00139                                                 ///< When allocating space for sound bank data, we recommend using AK_BANK_PLATFORM_DATA_ALIGNMENT.
00140             );
00141 
00142 #ifdef AK_SUPPORT_WCHAR
00143         /// Set the name of a memory pool.
00144         /// \return AK_Success if successful
00145         /// \sa
00146         /// - \ref memorymanager
00147         AK_EXTERNAPIFUNC( AKRESULT, SetPoolName )( 
00148             AkMemPoolId     in_poolId,          ///< ID of memory pool
00149             const wchar_t*  in_pszPoolName      ///< Pointer to unicode name string
00150             );
00151 #endif //AK_SUPPORT_WCHAR
00152 
00153         /// Set the name of a memory pool.
00154         /// \return AK_Success if successful
00155         /// \sa
00156         /// - \ref memorymanager
00157         AK_EXTERNAPIFUNC( AKRESULT, SetPoolName )( 
00158             AkMemPoolId     in_poolId,          ///< ID of memory pool
00159             const char*     in_pszPoolName      ///< Pointer to name string
00160             );
00161 
00162         /// Get the name of a memory pool.
00163         /// \return A pointer to the name of the memory pool (NULL if the operation failed)
00164         /// \sa
00165         /// - \ref memorymanager
00166         AK_EXTERNAPIFUNC( AkOSChar*, GetPoolName )( 
00167             AkMemPoolId     in_poolId           ///< ID of memory pool
00168             );
00169         
00170         /// Enables or disables error notifications posted by a memory pool.
00171         /// The notifications are enabled by default when creating a pool.
00172         /// They are always disabled in the Release build.
00173         /// \return AK_Success if the pool exists
00174         /// \sa
00175         /// - \ref memorymanager
00176         AK_EXTERNAPIFUNC( AKRESULT, SetMonitoring )(
00177             AkMemPoolId     in_poolId,          ///< ID of memory pool
00178             bool            in_bDoMonitor       ///< Enables error monitoring (has no effect in Release build)
00179             );
00180 
00181         /// Destroy a memory pool.
00182         /// \return AK_Success if successful
00183         /// \sa
00184         /// - \ref memorymanager
00185         AK_EXTERNAPIFUNC( AKRESULT, DestroyPool )(
00186             AkMemPoolId     in_poolId           ///< ID of memory pool
00187             );
00188 
00189         /// Get a memory pool's statistics.
00190         /// \sa
00191         /// - AK::MemoryMgr::PoolStats
00192         /// - \ref memorymanager
00193         AK_EXTERNAPIFUNC( AKRESULT, GetPoolStats )(
00194             AkMemPoolId     in_poolId,          ///< ID of memory pool
00195             PoolStats&      out_stats           ///< Returned statistics structure
00196             );
00197 
00198         /// Get a memory pool current used size.
00199         /// Mostly used by the memory threshold features.
00200         /// If this function cannot be implemented if your memory manager, at least set the member uUsed to 0, that
00201         /// will disable the memory threshold feature.
00202         /// \sa
00203         /// - AK::MemoryMgr::PoolMemInfo
00204         /// - \ref memorymanager
00205         AK_EXTERNAPIFUNC( void, GetPoolMemoryUsed )(
00206             AkMemPoolId     in_poolId,          ///< ID of memory pool
00207             PoolMemInfo&    out_memInfo         ///< Returned statistics structure
00208             );
00209 
00210         /// Get the current number of memory pools.
00211         /// \return The current number of memory pools
00212         /// \sa
00213         /// - \ref memorymanager
00214         AK_EXTERNAPIFUNC( AkInt32, GetNumPools )();
00215 
00216         /// Get the maximum number of memory pools.
00217         /// \return The maximum number of memory pools
00218         /// \sa
00219         /// - \ref memorymanager
00220         AK_EXTERNAPIFUNC( AkInt32, GetMaxPools )();
00221 
00222         /// Test the validity of a pool ID.
00223         /// This is used to verify the validity of a memory pool ID.
00224         /// \return AK_Success if the pool exists, AK_InvalidID otherwise
00225         /// \sa
00226         /// - \ref memorymanager
00227         AK_EXTERNAPIFUNC( AKRESULT, CheckPoolId )(
00228             AkMemPoolId     in_poolId           ///< ID of memory pool to test
00229             );
00230 
00231         /// Get pool attributes.
00232         /// \return The memory pool's attributes.
00233         /// \sa
00234         /// - \ref memorymanager
00235         AK_EXTERNAPIFUNC( AkMemPoolAttributes, GetPoolAttributes )(
00236             AkMemPoolId     in_poolId           ///< ID of memory pool
00237             );
00238 
00239         //@}
00240 
00241         ////////////////////////////////////////////////////////////////////////
00242         /// @name Memory Allocation
00243         //@{
00244 
00245 #if defined (AK_MEMDEBUG)
00246         /// Allocate memory from a pool: debug version.
00247         /// \return A pointer to the start of the allocated memory (NULL if the system is out of memory)
00248         /// \sa
00249         /// - \ref memorymanager
00250         AK_EXTERNAPIFUNC( void *, dMalloc )(
00251             AkMemPoolId in_poolId,              ///< ID of the memory pool
00252             size_t      in_uSize,               ///< Number of bytes to allocate
00253             const char *in_pszFile,             ///< Debug file name
00254             AkUInt32    in_uLine                ///< Debug line number
00255             );      
00256 #endif
00257         /// Allocate memory from a pool.
00258         /// \return A pointer to the start of the allocated memory (NULL if the system is out of memory)
00259         /// \sa
00260         /// - \ref memorymanager
00261         AK_EXTERNAPIFUNC( void *, Malloc )(
00262             AkMemPoolId in_poolId,              ///< ID of the memory pool
00263             size_t      in_uSize                ///< Number of bytes to allocate
00264             );
00265 
00266         /// Reallocate memory from a pool.
00267         /// \return A pointer to the start of the allocated memory (NULL if the system is out of memory)
00268         /// \sa
00269         /// - \ref memorymanager
00270         AK_EXTERNAPIFUNC(void *, Realloc)(
00271             AkMemPoolId in_poolId,              ///< ID of the memory pool
00272             void *in_pAlloc,                    ///< Pointer to the start of the allocated memory
00273             size_t      in_uSize                ///< Number of bytes to allocate
00274             );
00275 
00276         /// Free memory from a pool.
00277         /// \return AK_Success if successful
00278         /// \sa
00279         /// - \ref memorymanager
00280         AK_EXTERNAPIFUNC( AKRESULT, Free )(
00281             AkMemPoolId in_poolId,              ///< ID of the memory pool
00282             void *      in_pMemAddress          ///< Pointer to the start of memory allocated with Malloc
00283             );
00284 
00285 #if defined (AK_MEMDEBUG)
00286         /// Allocate memory from a pool, overriding the pool's default memory alignment. Needs to be used
00287         /// in conjunction with AK::MemoryMgr::Falign. debug version.
00288         /// \return A pointer to the start of the allocated memory (NULL if the system is out of memory)
00289         /// \sa
00290         /// - \ref memorymanager
00291         AK_EXTERNAPIFUNC( void *, dMalign )(
00292             AkMemPoolId in_poolId,              ///< ID of the memory pool
00293             size_t      in_uSize,               ///< Number of bytes to allocate
00294             AkUInt32    in_uAlignment,          ///< Alignment (in bytes)
00295             const char*  in_pszFile,            ///< Debug file name
00296             AkUInt32    in_uLine                ///< Debug line number
00297             );
00298 #endif
00299 
00300         /// Allocate memory from a pool, overriding the pool's default memory alignment. Needs to be used
00301         /// in conjunction with AK::MemoryMgr::Falign.
00302         /// \return A pointer to the start of the allocated memory (NULL if the system is out of memory)
00303         /// \sa
00304         /// - \ref memorymanager
00305         AK_EXTERNAPIFUNC( void *, Malign )(
00306             AkMemPoolId in_poolId,              ///< ID of the memory pool
00307             size_t      in_uSize,               ///< Number of bytes to allocate
00308             AkUInt32    in_uAlignment           ///< Alignment (in bytes)
00309             );
00310 
00311         /// Free memory from a pool, overriding the pool's default memory alignment. Needs to be used in
00312         /// conjunction with AK::MemoryMgr::Malign.
00313         /// 
00314         /// \return AK_Success if successful
00315         /// \sa
00316         /// - \ref memorymanager
00317         AK_EXTERNAPIFUNC( AKRESULT, Falign )(
00318             AkMemPoolId in_poolId,              ///< ID of the memory pool
00319             void *      in_pMemAddress          ///< Pointer to the start of memory allocated with Malign
00320             );
00321 
00322         //@}
00323 
00324         ////////////////////////////////////////////////////////////////////////
00325         /// @name Fixed-Size Blocks Memory Allocation Mode
00326         //@{
00327 
00328         /// Get a block from a Fixed-Size Block type pool. To be used with pools created with AkFixedSizeBlocksMode
00329         /// block management type, along with any of the block allocation types.
00330         /// \return A pointer to the start of the allocated memory (NULL if the system is out of memory)
00331         ///         The size of the memory block is always in_uBlockSize, specified in AK::MemoryMgr::CreatePool.
00332         /// \warning This method is not thread-safe. Fixed-Size Block pool access must be protected.
00333         /// \sa 
00334         /// - AK::MemoryMgr::CreatePool
00335         /// - AkMemPoolAttributes
00336         /// - \ref memorymanager
00337         AK_EXTERNAPIFUNC( void *, GetBlock )(
00338             AkMemPoolId in_poolId               ///< ID of the memory pool
00339             );
00340 
00341         /// Free memory from a Fixed-Size Block type pool.
00342         /// \return AK_Success if successful
00343         /// \warning This method is not thread-safe. Fixed-Size Block pool access must be protected.
00344         /// \sa
00345         /// - \ref memorymanager
00346         AK_EXTERNAPIFUNC( AKRESULT, ReleaseBlock )(
00347             AkMemPoolId in_poolId,              ///< ID of the memory pool
00348             void *      in_pMemAddress          ///< Pointer to the start of memory allocated with Malloc
00349             );
00350 
00351         /// Get block size of blocks obtained with GetBlock() for a given memory pool.
00352         /// The block size is fixed and set when creating a pool with AkFixedSizeBlocksMode.
00353         /// \return Block size
00354         /// \sa
00355         /// - AK::MemoryMgr::CreatePool
00356         /// - AK::MemoryMgr::GetBlock
00357         /// - \ref memorymanager
00358         AK_EXTERNAPIFUNC( AkUInt32, GetBlockSize )(
00359             AkMemPoolId in_poolId               ///< ID of the memory pool
00360             );
00361 
00362         /// Called to start profiling memory usage for one thread (the calling thread).
00363         /// \note Not implementing this will result in the Soundbank tab of the Wwise Profiler to show 0 bytes for memory usage.
00364         AK_EXTERNAPIFUNC( void, StartProfileThreadUsage) (
00365             AkMemPoolId in_PoolId   ///< Pool to profile
00366             );
00367 
00368         /// Called to stop profiling memory usage for the current thread.
00369         /// \return The amount of memory allocated by this thread since \ref StartProfileThreadUsage was called.
00370         /// \note Not implementing this will result in the Soundbank tab of the Wwise Profiler to show 0 bytes for memory usage.
00371         AK_EXTERNAPIFUNC( AkUInt32, StopProfileThreadUsage ) (
00372             AkMemPoolId in_PoolId   ///< Pool to profile
00373             );
00374 
00375 
00376         /// Debugging method that verifies if buffer overflow occurred in a specific pool.
00377         /// Called at various moments depending on the DebugFlags set in AkMemSettings.
00378         /// In the default implementation it is not called in Release otherwise will assert if overrun found.
00379         /// Implementation is not mendatory if the MemoryMgr is overriden.
00380         AK_EXTERNAPIFUNC(void, CheckForOverwrite) (
00381             AkUInt32 in_uPoolID
00382             );      
00383 
00384 #if defined (AK_MEMDEBUG)
00385         /// Debugging method that dumps a snapshot list of actual memory allocations to a file.
00386         /// The list contains the size allocated and the source file and line number where the memory allocation was done.
00387         AK_EXTERNAPIFUNC(void, DumpToFile) (const char* strFileName = "AkMemDump.txt");
00388 #endif
00389         //@}
00390     }
00391 }
00392 
00393 #endif // _AKMEMORYMGR_H_