diff options
Diffstat (limited to 'intern/dualcon/intern/MemoryAllocator.h')
-rw-r--r-- | intern/dualcon/intern/MemoryAllocator.h | 219 |
1 files changed, 219 insertions, 0 deletions
diff --git a/intern/dualcon/intern/MemoryAllocator.h b/intern/dualcon/intern/MemoryAllocator.h new file mode 100644 index 00000000000..de9dca175a4 --- /dev/null +++ b/intern/dualcon/intern/MemoryAllocator.h @@ -0,0 +1,219 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Tao Ju + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef MEMORYALLOCATOR_H +#define MEMORYALLOCATOR_H + +#include <stdio.h> +#include <stdlib.h> + +#define HEAP_BASE 16 +#define UCHAR unsigned char + +/** + * Customized memory allocators that allocates/deallocates memory in chunks + * + * @author Tao Ju + */ + + + +/** + * Base class of memory allocators + */ +class VirtualMemoryAllocator +{ +public: + virtual UCHAR * allocate( ) = 0 ; + virtual void deallocate( UCHAR * obj ) = 0 ; + virtual void destroy( ) = 0 ; + virtual void printInfo( ) = 0 ; + + virtual int getAllocated( ) = 0 ; + virtual int getAll( ) = 0 ; + virtual int getBytes( ) = 0 ; +}; + +/** + * Dynamic memory allocator - allows allocation/deallocation + * + * Note: there are 4 bytes overhead for each allocated yet unused object. + */ +template < int N > +class MemoryAllocator : public VirtualMemoryAllocator +{ +private: + + /// Constants + int HEAP_UNIT, HEAP_MASK ; + + /// Data array + UCHAR ** data ; + + /// Allocation stack + UCHAR *** stack ; + + /// Number of data blocks + int datablocknum ; + + /// Number of stack blocks + int stackblocknum ; + + /// Size of stack + int stacksize ; + + /// Number of available objects on stack + int available ; + + /** + * Allocate a memory block + */ + void allocateDataBlock ( ) + { + // Allocate a data block + datablocknum += 1 ; + data = ( UCHAR ** )realloc( data, sizeof ( UCHAR * ) * datablocknum ) ; + data[ datablocknum - 1 ] = ( UCHAR * )malloc( HEAP_UNIT * N ) ; + + // Update allocation stack + for ( int i = 0 ; i < HEAP_UNIT ; i ++ ) + { + stack[ 0 ][ i ] = ( data[ datablocknum - 1 ] + i * N ) ; + } + available = HEAP_UNIT ; + } + + /** + * Allocate a stack block, to store more deallocated objects + */ + void allocateStackBlock( ) + { + // Allocate a stack block + stackblocknum += 1 ; + stacksize += HEAP_UNIT ; + stack = ( UCHAR *** )realloc( stack, sizeof ( UCHAR ** ) * stackblocknum ) ; + stack[ stackblocknum - 1 ] = ( UCHAR ** )malloc( HEAP_UNIT * sizeof ( UCHAR * ) ) ; + } + + +public: + /** + * Constructor + */ + MemoryAllocator( ) + { + HEAP_UNIT = 1 << HEAP_BASE ; + HEAP_MASK = ( 1 << HEAP_BASE ) - 1 ; + + data = ( UCHAR ** )malloc( sizeof( UCHAR * ) ) ; + data[ 0 ] = ( UCHAR * )malloc( HEAP_UNIT * N ) ; + datablocknum = 1 ; + + stack = ( UCHAR *** )malloc( sizeof ( UCHAR ** ) ) ; + stack[ 0 ] = ( UCHAR ** )malloc( HEAP_UNIT * sizeof ( UCHAR * ) ) ; + stackblocknum = 1 ; + stacksize = HEAP_UNIT ; + available = HEAP_UNIT ; + + for ( int i = 0 ; i < HEAP_UNIT ; i ++ ) + { + stack[ 0 ][ i ] = ( data[ 0 ] + i * N ) ; + } + } + + /** + * Destructor + */ + void destroy( ) + { + int i ; + for ( i = 0 ; i < datablocknum ; i ++ ) + { + free( data[ i ] ) ; + } + for ( i = 0 ; i < stackblocknum ; i ++ ) + { + free( stack[ i ] ) ; + } + free( data ) ; + free( stack ) ; + } + + /** + * Allocation method + */ + UCHAR * allocate ( ) + { + if ( available == 0 ) + { + allocateDataBlock ( ) ; + } + + // printf("Allocating %d\n", header[ allocated ]) ; + available -- ; + return stack[ available >> HEAP_BASE ][ available & HEAP_MASK ] ; + } + + /** + * De-allocation method + */ + void deallocate ( UCHAR * obj ) + { + if ( available == stacksize ) + { + allocateStackBlock ( ) ; + } + + // printf("De-allocating %d\n", ( obj - data ) / N ) ; + stack[ available >> HEAP_BASE ][ available & HEAP_MASK ] = obj ; + available ++ ; + // printf("%d %d\n", allocated, header[ allocated ]) ; + } + + /** + * Print information + */ + void printInfo ( ) + { + printf("Bytes: %d Used: %d Allocated: %d Maxfree: %d\n", getBytes(), getAllocated(), getAll(), stacksize ) ; + } + + /** + * Query methods + */ + int getAllocated( ) + { + return HEAP_UNIT * datablocknum - available ; + }; + + int getAll( ) + { + return HEAP_UNIT * datablocknum ; + }; + + int getBytes( ) + { + return N ; + }; +}; + +#endif |