Blender V2.61 - r43446

MemoryAllocator.h

Go to the documentation of this file.
00001 /*
00002  * ***** BEGIN GPL LICENSE BLOCK *****
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software Foundation,
00016  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  *
00018  * Contributor(s): Tao Ju
00019  *
00020  * ***** END GPL LICENSE BLOCK *****
00021  */
00022 
00023 #ifndef MEMORYALLOCATOR_H
00024 #define MEMORYALLOCATOR_H
00025 
00026 #include <stdio.h>
00027 #include <stdlib.h>
00028 
00029 #define HEAP_BASE 16
00030 #define UCHAR unsigned char
00031 
00043 class VirtualMemoryAllocator
00044 {
00045 public:
00046     virtual UCHAR * allocate( ) = 0 ;
00047     virtual void deallocate( UCHAR * obj ) = 0 ;
00048     virtual void destroy( ) = 0 ;
00049     virtual void printInfo( ) = 0 ;
00050 
00051     virtual int getAllocated( ) = 0 ;
00052     virtual int getAll( ) = 0 ;
00053     virtual int getBytes( ) = 0 ;
00054 };
00055 
00061 template < int N >
00062 class MemoryAllocator : public VirtualMemoryAllocator
00063 {
00064 private:
00065 
00067     int HEAP_UNIT, HEAP_MASK ;
00068 
00070     UCHAR ** data ;
00071 
00073     UCHAR *** stack ;
00074 
00076     int datablocknum ;
00077 
00079     int stackblocknum ;
00080 
00082     int stacksize ;
00083 
00085     int available ;
00086 
00090     void allocateDataBlock ( )
00091     {
00092         // Allocate a data block
00093         datablocknum += 1 ;
00094         data = ( UCHAR ** )realloc( data, sizeof ( UCHAR * ) * datablocknum ) ;
00095         data[ datablocknum - 1 ] = ( UCHAR * )malloc( HEAP_UNIT * N ) ;
00096 
00097         // Update allocation stack
00098         for ( int i = 0 ; i < HEAP_UNIT ; i ++ )
00099         {
00100             stack[ 0 ][ i ] = ( data[ datablocknum - 1 ] + i * N ) ;
00101         }
00102         available = HEAP_UNIT ;
00103     }
00104 
00108     void allocateStackBlock( )
00109     {
00110         // Allocate a stack block
00111         stackblocknum += 1 ;
00112         stacksize += HEAP_UNIT ;
00113         stack = ( UCHAR *** )realloc( stack, sizeof ( UCHAR ** ) * stackblocknum ) ;
00114         stack[ stackblocknum - 1 ] = ( UCHAR ** )malloc( HEAP_UNIT * sizeof ( UCHAR * ) ) ;
00115     }
00116 
00117 
00118 public:
00122     MemoryAllocator( )
00123     {
00124         HEAP_UNIT = 1 << HEAP_BASE ;
00125         HEAP_MASK = ( 1 << HEAP_BASE ) - 1 ;
00126 
00127         data = ( UCHAR ** )malloc( sizeof( UCHAR * ) ) ;
00128         data[ 0 ] = ( UCHAR * )malloc( HEAP_UNIT * N ) ;
00129         datablocknum = 1 ;
00130 
00131         stack = ( UCHAR *** )malloc( sizeof ( UCHAR ** ) ) ;
00132         stack[ 0 ] = ( UCHAR ** )malloc( HEAP_UNIT * sizeof ( UCHAR * ) ) ;
00133         stackblocknum = 1 ;
00134         stacksize = HEAP_UNIT ;
00135         available = HEAP_UNIT ;
00136 
00137         for ( int i = 0 ; i < HEAP_UNIT ; i ++ )
00138         {
00139             stack[ 0 ][ i ] = ( data[ 0 ] + i * N ) ;
00140         }
00141     }
00142 
00146     void destroy( )
00147     {
00148         int i ;
00149         for ( i = 0 ; i < datablocknum ; i ++ )
00150         {
00151             free( data[ i ] ) ;
00152         }
00153         for ( i = 0 ; i < stackblocknum ; i ++ )
00154         {
00155             free( stack[ i ] ) ;
00156         }
00157         free( data ) ;
00158         free( stack ) ;
00159     }
00160 
00164     UCHAR * allocate ( )
00165     {
00166         if ( available == 0 )
00167         {
00168             allocateDataBlock ( ) ;
00169         }
00170 
00171         // printf("Allocating %d\n", header[ allocated ]) ;
00172         available -- ;
00173         return stack[ available >> HEAP_BASE ][ available & HEAP_MASK ] ;
00174     }
00175 
00179     void deallocate ( UCHAR * obj )
00180     {
00181         if ( available == stacksize )
00182         {
00183             allocateStackBlock ( ) ;
00184         }
00185 
00186         // printf("De-allocating %d\n", ( obj - data ) / N ) ;
00187         stack[ available >> HEAP_BASE ][ available & HEAP_MASK ] = obj ;
00188         available ++ ;
00189         // printf("%d %d\n", allocated, header[ allocated ]) ;
00190     }
00191 
00195     void printInfo ( )
00196     {
00197         printf("Bytes: %d Used: %d Allocated: %d Maxfree: %d\n", getBytes(), getAllocated(), getAll(), stacksize ) ;
00198     }
00199 
00203     int getAllocated( )
00204     {
00205         return HEAP_UNIT * datablocknum - available ;   
00206     };
00207 
00208     int getAll( )
00209     {
00210         return HEAP_UNIT * datablocknum ;
00211     };
00212 
00213     int getBytes( )
00214     {
00215         return N ;  
00216     };
00217 };
00218 
00219 #endif