Logo Search packages:      
Sourcecode: adun.app version File versions  Download package

AdunMemoryManager.m

/*
   Project: Adun

   Copyright (C) 2005 Michael Johnston & Jordi Villa-Freixa

   Author: Michael Johnston

   This application 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 application 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
   Library General Public License for more details.

   You should have received a copy of the GNU General Public
   License along with this library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#include "AdunKernel/AdunMemoryManager.h"

static id memoryManager;

#define MEM_CON 1048576

00028 @implementation AdMemoryManager

00030 + (id) appMemoryManager
{
      if(memoryManager == nil)
            memoryManager = [[AdMemoryManager alloc] init];

      return memoryManager;
}

00038 - (id) initWithEnvironment: (id) object observe: (BOOL) value
{
      if(self = [super initWithEnvironment: object observe: value])
      {
            MEMORY_STATS=[[NSUserDefaults standardUserDefaults] boolForKey: @"OutputMemoryStatistics"];
            memoryManager = self;
      }           

      return self;
}

00049 - (id) initWithEnvironment: (id) object
{
      return [self initWithEnvironment: object observe: YES];
}

- (id) init
{
      return [self initWithEnvironment: nil];

}

- (void) dealloc
{

}

00065 - (void*) allocateArrayOfSize: (int) size
{
      void* array;
      NSError* error;
      NSMutableDictionary* errorDict;

      if(MEMORY_STATS==YES)
      {
            mem_struct = mallinfo();
            GSPrintf(stderr, @"Before Array Alloc - Arena : %lf MB. Hblks : %lf MB. Uordblocks %lf MB. Fordblocks %d\n", 
                  (float)mem_struct.arena/(float)MEM_CON,
                  (float)mem_struct.hblkhd/(float)MEM_CON, 
                  (float)mem_struct.uordblks/(float)MEM_CON, 
                  mem_struct.fordblks); 
      }

      //The return value of malloc(0) is implementation dependant
      //It can return NULL in which case it is indistinguisable from
      //the results of mallocing an array that will exhaust virtual memory.
      //We want to avoid this since we dont want malloc(0) to trigger the
      //array == NULL error below. 
      //malloc(0) can also return a special pointer. This is problematic
      //since we dont know what this special pointer is and attempting
      //to free it later could cause a segmentation fault. Hence if
      //malloc(0) is attempted with immediatly return NULL. In this
      //way when freeing an array or matrix that was created using 0 
      //we can recognise and handle it. 

      //Unfortunatly something is trying to use the NULL pointer
      //returned here and causing the program to crash. Until this
      //is corrected we cant use this method.

      /*if(size == 0)
      {
            NSLog(@"Attempting to allocate a zero size array");
            return NULL;
      }
      else*/
            array = malloc(size);
      
      if(array == NULL)
      {
            NSWarnLog(@"Attempt to allocate array of size %d will exhaust virtual memory!\n", size);
            
            errorDict = [NSMutableDictionary new];
            [errorDict setObject: [NSString stringWithFormat: 
                  @"Simulator attempted to allocate an array that would have exhausted virtual memory (size %d bytes).\n"
                        , size]
                  forKey: NSLocalizedDescriptionKey];
            [errorDict setObject: @"This is probably a symptom of the simulation exploding due to excessive forces.\n"
                  forKey: @"AdDetailedDescriptionKey"];
            [errorDict setObject: @"You may need to relax the system before performing a full simulation.\nSee the User Guide for\
 details on how to do this (diana.imim.es/Adun).\n"
                  forKey: @"NSRecoverySuggestionKey"];
            [errorDict setObject: NSInternalInconsistencyException
                  forKey: NSUnderlyingErrorKey];

            error = [NSError errorWithDomain: @"AdKernelErrorDomain"
                        code: 2
                        userInfo: errorDict];

            [[NSException exceptionWithName: NSInternalInconsistencyException
                  reason: [NSString stringWithFormat:
                  @"Attempted to allocate an array that would have exhausted virtual memory (size %d bytes).", size]
                  userInfo: [NSDictionary dictionaryWithObject: error
                              forKey: @"AdKnownExceptionError"]] 
                  raise];
      }
      
      memset(array, 0, size);
      
      if(MEMORY_STATS==YES)
      {
            mem_struct = mallinfo();
            GSPrintf(stderr, @"After Array Alloc (%d) - Arena : %lf MB. Hblks : %lf MB. Uordblocks %lf MB. Fordblocks %d\n\n", size, 
                  (float)mem_struct.arena/(float)MEM_CON, 
                  (float)mem_struct.hblkhd/(float)MEM_CON, 
                  (float)mem_struct.uordblks/(float)MEM_CON, 
                  mem_struct.fordblks); 
            fflush(stderr);
      }


      return array;
}

00151 - (AdMatrix*) allocateMatrixWithRows: (int) no_rows withColumns: (int) no_columns
{
      int i, j;
      double *array;
      AdMatrix *matrix;

      if(MEMORY_STATS==YES)
      {
            mem_struct = mallinfo();
            GSPrintf(stderr, @"Before Matrix Alloc - Arena : %lf MB. Hblks : %lf MB. Uordblocks %lf MB. Fordblocks %d\n", 
                  (float)mem_struct.arena/(float)MEM_CON, 
                  (float)mem_struct.hblkhd/(float)MEM_CON, 
                  (float)mem_struct.uordblks/(float)MEM_CON, 
                  mem_struct.fordblks); 
      }

      matrix = (AdMatrix*)malloc(sizeof(AdMatrix));
      matrix->no_rows = no_rows;
      matrix->no_columns = no_columns;
      array = (double*)[self allocateArrayOfSize: no_rows*no_columns*sizeof(double)];
      matrix->matrix = (double**)[self allocateArrayOfSize: no_rows*sizeof(double*)];
      for(i=0, j=0; i < no_rows; i++, j = j + no_columns)
                  matrix->matrix[i] = array + j;

      if(MEMORY_STATS==YES)
      {
            mem_struct = mallinfo();
            GSPrintf(stderr, @"After Matrix Alloc - Arena : %lf MB. Hblks : %lf MB. Uordblocks %lf MB. Fordblocks %d\n", 
                  (float)mem_struct.arena/(float)MEM_CON, 
                  (float)mem_struct.hblkhd/(float)MEM_CON, 
                  (float)mem_struct.uordblks/(float)MEM_CON,
                  mem_struct.fordblks); 
      }

      return matrix;
}

00188 - (IntMatrix*) allocateIntMatrixWithRows: (int) no_rows withColumns: (int) no_columns
{
      int i, j;
      int *array;
      IntMatrix *matrix;

      if(MEMORY_STATS==YES)
      {
            mem_struct = mallinfo();
            GSPrintf(stderr, @"Before Matrix Alloc - Arena : %lf MB. Hblks : %lf MB. Uordblocks %lf MB. Fordblocks %d\n", 
                  (float)mem_struct.arena/(float)MEM_CON, 
                  (float)mem_struct.hblkhd/(float)MEM_CON, 
                  (float)mem_struct.uordblks/(float)MEM_CON, 
                  mem_struct.fordblks); 
      }

      matrix = (IntMatrix*)malloc(sizeof(IntMatrix));
      matrix->no_rows = no_rows;
      matrix->no_columns = no_columns;
      array = (int*)[self allocateArrayOfSize: no_rows*no_columns*sizeof(int)];
      matrix->matrix = (int**)[self allocateArrayOfSize: no_rows*sizeof(int*)];
      for(i=0, j=0; i < no_rows; i++, j = j + no_columns)
                  matrix->matrix[i] = array + j;

      if(MEMORY_STATS==YES)
      {
            mem_struct = mallinfo();
            GSPrintf(stderr, @"After Matrix Alloc - Arena : %lf MB. Hblks : %lf MB. Uordblocks %lf MB. Fordblocks %d\n", 
                  (float)mem_struct.arena/(float)MEM_CON, 
                  (float)mem_struct.hblkhd/(float)MEM_CON, 
                  (float)mem_struct.uordblks/(float)MEM_CON, 
                  mem_struct.fordblks); 
      }

      return matrix;
}

00225 - (InterTable*) allocateInterTableWithRows: (int) no_rows withColumns: (int) no_columns
{
      int i, j;
      double *array;
      InterTable *table;
      
      if(MEMORY_STATS==YES)
      {
            mem_struct = mallinfo();
            GSPrintf(stderr, @"Before Table Alloc - Arena : %lf MB. Hblks : %lf MB. Uordblocks %lf MB. Fordblocks %d\n", 
                  (float)mem_struct.arena/(float)MEM_CON, 
                  (float)mem_struct.hblkhd/(float)MEM_CON, 
                  (float)mem_struct.uordblks/(float)MEM_CON,
                   mem_struct.fordblks); 
      }

      table = (InterTable*)malloc(sizeof(InterTable));
      table->no_interactions = no_rows;
      table->no_columns = no_columns;

      array = (double*)[self allocateArrayOfSize: no_rows*no_columns*sizeof(double)];
      table->table = (double**)[self allocateArrayOfSize: no_rows*sizeof(double*)];

      for(i=0, j=0; i < no_rows; i++, j = j + no_columns)
                  table->table[i] = array + j;
      
      if(MEMORY_STATS==YES)
      {
            mem_struct = mallinfo();
            GSPrintf(stderr, @"After Table Alloc Arena : %lf MB. Hblks : %lf MB. Uordblocks %lf MB. Fordblocks %d\n", 
                  (float)mem_struct.arena/(float)MEM_CON, 
                  (float)mem_struct.hblkhd/(float)MEM_CON, 
                  (float)mem_struct.uordblks/(float)MEM_CON, 
                  mem_struct.fordblks); 
      }

      return table;
}

00264 - (void) freeArray: (void*)array
{     
      if(MEMORY_STATS==YES)
      {
            mem_struct = mallinfo();
            GSPrintf(stderr, @"Before Array Free - Arena : %lf MB. Hblks : %lf MB. Uordblocks %lf MB. Fordblocks %d\n", 
                  (float)mem_struct.arena/(float)MEM_CON, 
                  (float)mem_struct.hblkhd/(float)MEM_CON, 
                  (float)mem_struct.uordblks/(float)MEM_CON, 
                  mem_struct.fordblks); 
      }

      free(array);

      if(MEMORY_STATS==YES)
      {
            mem_struct = mallinfo();
            GSPrintf(stderr, @"After Array Free  - Arena : %lf MB. Hblks : %lf MB. Uordblocks %lf MB. Fordblocks %d\n\n",  
                  (float)mem_struct.arena/(float)MEM_CON, 
                  (float)mem_struct.hblkhd/(float)MEM_CON, 
                  (float)mem_struct.uordblks/(float)MEM_CON, 
                  mem_struct.fordblks); 
      }
}

/** Do not use this method to free matrices not allocated by one of the
above methods **/

00292 - (void) freeDoubleMatrix: (double**) matrix withRows: (int) no_rows 
{
      //matrices are allocated as arrays
      //with another array of indexes
      
      free(matrix[0]);  //frees the number array      
      free(matrix);           //frees the index array 

      if(MEMORY_STATS==YES)
      {
            mem_struct = mallinfo();
            GSPrintf(stderr, @"Arena : %lf MB. Hblks : %lf MB. Uordblocks %lf MB. Fordblocks %d\n", 
                  (float)mem_struct.arena/(float)MEM_CON, 
                  (float)mem_struct.hblkhd/(float)MEM_CON, 
                  (float)mem_struct.uordblks/(float)MEM_CON, 
                  mem_struct.fordblks); 
      }

}

00312 - (void) freeMatrix: (AdMatrix*) matrix 
{
      //matrices are allocated as arrays
      //with another array of indexes
      if(MEMORY_STATS==YES)
      {
            mem_struct = mallinfo();
            GSPrintf(stderr, @"Before Matrix free - Arena : %lf MB. Hblks : %lf MB. Uordblocks %lf MB. Fordblocks %d\n", 
                  (float)mem_struct.arena/(float)MEM_CON, 
                  (float)mem_struct.hblkhd/(float)MEM_CON, 
                  (float)mem_struct.uordblks/(float)MEM_CON, 
                  mem_struct.fordblks); 
      }

      if(matrix->no_rows != 0)
      {
            free(matrix->matrix[0]); //frees the number array     
            free(matrix->matrix);          //frees the index array
      }
      free(matrix);
      
      if(MEMORY_STATS==YES)
      {
            mem_struct = mallinfo();
            GSPrintf(stderr, @"After Matrix free - Arena : %lf MB. Hblks : %lf MB. Uordblocks %lf MB. Fordblocks %d\n", 
                  (float)mem_struct.arena/(float)MEM_CON, 
                  (float)mem_struct.hblkhd/(float)MEM_CON, 
                  (float)mem_struct.uordblks/(float)MEM_CON, 
                  mem_struct.fordblks); 
      }
}

00344 - (void) freeIntMatrix: (IntMatrix*) matrix 
{
      if(MEMORY_STATS==YES)
      {
            mem_struct = mallinfo();
            GSPrintf(stderr, @"Before Matrix free - Arena : %lf MB. Hblks : %lf MB. Uordblocks %lf MB. Fordblocks %d\n", 
                  (float)mem_struct.arena/(float)MEM_CON, 
                  (float)mem_struct.hblkhd/(float)MEM_CON, 
                  (float)mem_struct.uordblks/(float)MEM_CON, 
                  mem_struct.fordblks); 
      }

      if(matrix->no_rows != 0)
      {
            free(matrix->matrix[0]); 
            free(matrix->matrix);   
      }
      free(matrix);
      
      if(MEMORY_STATS==YES)
      {
            mem_struct = mallinfo();
            GSPrintf(stderr, @"After Matrix free - Arena : %lf MB. Hblks : %lf MB. Uordblocks %lf MB. Fordblocks %d\n", 
                  (float)mem_struct.arena/(float)MEM_CON, 
                  (float)mem_struct.hblkhd/(float)MEM_CON, 
                  (float)mem_struct.uordblks/(float)MEM_CON, 
                  mem_struct.fordblks); 
      }
}

00374 - (void) freeInterTable: (InterTable*) matrix  
{
      //matrices are allocated as arrays
      //with another array of indexes
      
      if(MEMORY_STATS==YES)
      {
            mem_struct = mallinfo();
            GSPrintf(stderr, @"Before InterTable free - Arena : %lf MB. Hblks : %lf MB. Uordblocks %lf MB. Fordblocks %d\n", 
                  (float)mem_struct.arena/(float)MEM_CON, 
                  (float)mem_struct.hblkhd/(float)MEM_CON, 
                  (float)mem_struct.uordblks/(float)MEM_CON, 
                  mem_struct.fordblks); 
      }

      if(matrix->no_interactions != 0)
      {
            free(matrix->table[0]);
            free(matrix->table);    //frees the number array      
      }

      free(matrix);
      
      if(MEMORY_STATS==YES)
      {
            mem_struct = mallinfo();
            GSPrintf(stderr, @"After Intertable free - Arena : %lf MB. Hblks : %lf MB. Uordblocks %lf MB. Fordblocks %d\n", 
                  (float)mem_struct.arena/(float)MEM_CON, 
                  (float)mem_struct.hblkhd/(float)MEM_CON, 
                  (float)mem_struct.uordblks/(float)MEM_CON, 
                  mem_struct.fordblks); 
      }
}

@end



Generated by  Doxygen 1.6.0   Back to index