diff options
Diffstat (limited to 'Build/source/libs/libttf/ttmemory.c')
-rw-r--r-- | Build/source/libs/libttf/ttmemory.c | 397 |
1 files changed, 397 insertions, 0 deletions
diff --git a/Build/source/libs/libttf/ttmemory.c b/Build/source/libs/libttf/ttmemory.c new file mode 100644 index 00000000000..280c05f22d6 --- /dev/null +++ b/Build/source/libs/libttf/ttmemory.c @@ -0,0 +1,397 @@ +/******************************************************************* + * + * ttmemory.c 1.2 + * + * Memory management component (body). + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * + * Changes between 1.1 and 1.2: + * + * - the font pool is gone. + * + * - introduced the FREE macro and the Free function for + * future use in destructors. + * + * - Init_FontPool() is now a macro to allow the compilation of + * 'legacy' applications (all four test programs have been updated). + * + ******************************************************************/ + +#include "ttdebug.h" +#include "ttmemory.h" +#include "ttengine.h" + +/* required by the tracing mode */ +#undef TT_COMPONENT +#define TT_COMPONENT trace_memory + + +#ifdef DEBUG_MEMORY + +#include <stdio.h> + +#define MAX_TRACKED_BLOCKS 1024 + + struct TMemRec_ + { + void* base; + Long size; + }; + + typedef struct TMemRec_ TMemRec; + + static TMemRec pointers[MAX_TRACKED_BLOCKS + 1]; + + static Int num_alloc; + static Int num_free; + static Int num_realloc; /* counts only `real' reallocations + (i.e., an existing buffer will be resized + to a value larger than zero */ + + static Int fail_alloc; + static Int fail_realloc; + static Int fail_free; + +#endif /* DEBUG_MEMORY */ + + +#ifndef TT_CONFIG_OPTION_THREAD_SAFE + Long TTMemory_Allocated; + Long TTMemory_MaxAllocated; +#endif + + +/******************************************************************* + * + * Function : TT_Alloc + * + * Description : Allocates memory from the heap buffer. + * + * Input : Size size of the memory to be allocated + * P pointer to a buffer pointer + * + * Output : Error code. + * + * NOTE : The newly allocated block should _always_ be zeroed + * on return. Many parts of the engine rely on this to + * work properly. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Alloc( ULong Size, void** P ) + { +#ifdef DEBUG_MEMORY + Int i; +#endif + + + if ( !P ) + return TT_Err_Invalid_Argument; + + if ( Size > (size_t)-1 ) + return TT_Err_Out_Of_Memory; + if ( Size > 0 ) + { + *P = (void*)malloc( Size ); + if ( !*P ) + return TT_Err_Out_Of_Memory; + +#ifndef TT_CONFIG_OPTION_THREAD_SAFE + TTMemory_Allocated += Size; + TTMemory_MaxAllocated += Size; +#endif + +#ifdef DEBUG_MEMORY + + num_alloc++; + + i = 0; + while ( i < MAX_TRACKED_BLOCKS && pointers[i].base != NULL ) + i++; + + if ( i >= MAX_TRACKED_BLOCKS ) + fail_alloc++; + else + { + pointers[i].base = *P; + pointers[i].size = Size; + } + +#endif /* DEBUG_MEMORY */ + + MEM_Set( *P, 0, Size ); + } + else + *P = NULL; + + return TT_Err_Ok; + } + + +#ifdef TT_CONFIG_OPTION_EXTEND_ENGINE + + +/******************************************************************* + * + * Function : TT_Realloc + * + * Description : Reallocates memory from the heap buffer. + * + * Input : Size new size of the memory to be allocated; + * if zero, TT_Free() will be called + * P pointer to a buffer pointer; if *P == NULL, + * TT_Alloc() will be called + * + * Output : Error code. + * + * NOTES : It's not necessary to zero the memory in case the + * reallocated buffer is larger than before -- the + * application has to take care of this. + * + * If the memory request fails, TT_Free() will be + * called on *P, and TT_Err_Out_Of_Memory returned. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Realloc( ULong Size, void** P ) + { + void* Q; + +#ifdef DEBUG_MEMORY + Int i; +#endif + + + if ( !P ) + return TT_Err_Invalid_Argument; + + if ( !*P ) + return TT_Alloc( Size, P ); + + if ( Size == 0 ) + return TT_Free( P ); + + if ( Size > (size_t)-1 ) + { + TT_Free( *P ); + return TT_Err_Out_Of_Memory; + } + + Q = (void*)realloc( *P, Size ); + if ( !Q ) + { + TT_Free( *P ); + return TT_Err_Out_Of_Memory; + } + +#ifdef DEBUG_MEMORY + + num_realloc++; + + i = 0; + while ( i < MAX_TRACKED_BLOCKS && pointers[i].base != *P ) + i++; + + if ( i >= MAX_TRACKED_BLOCKS ) + fail_realloc++; + else + { +#ifndef TT_CONFIG_OPTION_THREAD_SAFE + TTMemory_Allocated += Size - pointers[i].size; + if ( Size > pointers[i].size ) + TTMemory_MaxAllocated += Size - pointers[i].size; +#endif + + pointers[i].base = Q; + pointers[i].size = size; + } +#endif /* DEBUG_MEMORY */ + + *P = Q; + + return TT_Err_Ok; + } + + +#endif /* TT_CONFIG_OPTION_EXTEND_ENGINE */ + + +/******************************************************************* + * + * Function : TT_Free + * + * Description : Releases a previously allocated block of memory. + * + * Input : P pointer to memory block + * + * Output : Always SUCCESS. + * + * Note : The pointer must _always_ be set to NULL by this function. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Free( void** P ) + { +#ifdef DEBUG_MEMORY + Int i; +#endif /* DEBUG_MEMORY */ + + + if ( !P || !*P ) + return TT_Err_Ok; + +#ifdef DEBUG_MEMORY + + num_free++; + + i = 0; + while ( i < MAX_TRACKED_BLOCKS && pointers[i].base != *P ) + i++; + + if ( i >= MAX_TRACKED_BLOCKS ) + fail_free++; + else + { +#ifndef TT_CONFIG_OPTION_THREAD_SAFE + TTMemory_Allocated -= pointers[i].size; +#endif + + pointers[i].base = NULL; + pointers[i].size = 0; + } +#endif /* DEBUG_MEMORY */ + + free( *P ); + + *P = NULL; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TTMemory_Init + * + * Description : Initializes the memory. + * + * Output : Always SUCCESS. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error TTMemory_Init( void ) + { +#ifdef DEBUG_MEMORY + Int i; + + + for ( i = 0; i < MAX_TRACKED_BLOCKS; i++ ) + { + pointers[i].base = NULL; + pointers[i].size = 0; + } + + num_alloc = 0; + num_realloc = 0; + num_free = 0; + + fail_alloc = 0; + fail_realloc = 0; + fail_free = 0; +#endif + + +#ifndef TT_CONFIG_OPTION_THREAD_SAFE + TTMemory_Allocated = 0; + TTMemory_MaxAllocated = 0; +#endif + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TTMemory_Done + * + * Description : Finalizes memory usage. + * + * Output : Always SUCCESS. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error TTMemory_Done( void ) + { +#ifdef DEBUG_MEMORY + Int i, num_leaked, tot_leaked; + + + num_leaked = 0; + tot_leaked = 0; + + for ( i = 0; i < MAX_TRACKED_BLOCKS; i++ ) + { + if ( pointers[i].base ) + { + num_leaked ++; + tot_leaked += pointers[i].size; + } + } + + fprintf( stderr, + "%d memory allocations, of which %d failed\n", + num_alloc, + fail_alloc ); + + fprintf( stderr, + "%d memory reallocations, of which %d failed\n", + num_realloc, + fail_realloc ); + + fprintf( stderr, + "%d memory frees, of which %d failed\n", + num_free, + fail_free ); + + if ( num_leaked > 0 ) + { + fprintf( stderr, + "There are %d leaked memory blocks, totalizing %d bytes\n", + num_leaked, tot_leaked ); + + for ( i = 0; i < MAX_TRACKED_BLOCKS; i++ ) + { + if ( pointers[i].base ) + { + fprintf( stderr, + "index: %4d (base: $%08lx, size: %08ld)\n", + i, + (long)pointers[i].base, + pointers[i].size ); + } + } + } + else + fprintf( stderr, "No memory leaks !\n" ); + +#endif /* DEBUG_MEMORY */ + + return TT_Err_Ok; + } + + +/* END */ |