FLA_Memory.c File Reference

(r)


Functions

void * FLA_malloc (size_t size)
void * FLA_realloc (void *old_ptr, size_t size)
void FLA_free (void *ptr)

Variables

int memcounter = 0
FLA_Lock memcounter_lock

Function Documentation

void FLA_free ( void *  ptr  ) 

References FLA_Lock_acquire(), FLA_Lock_release(), and memcounter.

Referenced by FLA_Apply_househ2_UT_opt_dcomplex(), FLA_Apply_househ2_UT_opt_double(), FLA_Apply_househ2_UT_opt_float(), FLA_Apply_househ2_UT_opt_scomplex(), FLA_Blocksize_free(), FLA_Cntl_obj_free(), FLA_Obj_free(), FLA_Obj_free_without_buffer(), FLA_realloc(), FLASH_Obj_create_conf_to(), FLASH_Obj_create_helper(), FLASH_Obj_exec_parallel(), FLASH_Obj_free(), FLASH_Queue_push(), FLASH_Task_free(), and FLASH_Task_free_parallel().

00186 {
00187   if ( ptr != NULL )
00188   {
00189     // Free the memory addressed by ptr. Make sure it is not NULL just in case.
00190     free( ptr );
00191 
00192 #ifdef FLA_ENABLE_MEM_COUNTER
00193     // We don't want to decrement the counter if the buffer is NULL.
00194     // This is because it's likely that the buffer was never allocated
00195     // a valid pointer to begin with, which means FLA_malloc() was never
00196     // called and thus the counter was never incremented.
00197   #ifdef FLA_ENABLE_MULTITHREADING
00198     FLA_Lock_acquire( &memcounter_lock );
00199     memcounter -= 1;
00200     FLA_Lock_release( &memcounter_lock );
00201   #else
00202     memcounter -= 1;
00203   #endif
00204 #endif
00205   }
00206 }

void* FLA_malloc ( size_t  size  ) 

References FLA_Check_error_level(), FLA_Check_malloc_pointer(), FLA_Check_posix_memalign_failure(), FLA_Lock_acquire(), FLA_Lock_release(), and memcounter.

Referenced by FLA_Apply_househ2_UT_opt_dcomplex(), FLA_Apply_househ2_UT_opt_double(), FLA_Apply_househ2_UT_opt_float(), FLA_Apply_househ2_UT_opt_scomplex(), FLA_Blocksize_create(), FLA_Blocksize_create_copy(), FLA_Cntl_apqut_obj_create(), FLA_Cntl_apqutinc_obj_create(), FLA_Cntl_apqutud_obj_create(), FLA_Cntl_axpy_obj_create(), FLA_Cntl_chol_obj_create(), FLA_Cntl_copy_obj_create(), FLA_Cntl_gemm_obj_create(), FLA_Cntl_gemv_obj_create(), FLA_Cntl_hemm_obj_create(), FLA_Cntl_her2k_obj_create(), FLA_Cntl_herk_obj_create(), FLA_Cntl_hess_obj_create(), FLA_Cntl_lqut_obj_create(), FLA_Cntl_lu_obj_create(), FLA_Cntl_qrut_obj_create(), FLA_Cntl_qrutinc_obj_create(), FLA_Cntl_qrutud_obj_create(), FLA_Cntl_spdinv_obj_create(), FLA_Cntl_swap_obj_create(), FLA_Cntl_sylv_obj_create(), FLA_Cntl_symm_obj_create(), FLA_Cntl_syr2k_obj_create(), FLA_Cntl_syrk_obj_create(), FLA_Cntl_tpose_obj_create(), FLA_Cntl_trinv_obj_create(), FLA_Cntl_trmm_obj_create(), FLA_Cntl_trsm_obj_create(), FLA_Cntl_trsv_obj_create(), FLA_Cntl_ttmm_obj_create(), FLA_Obj_create_conf_to(), FLA_Obj_create_ext(), FLA_Obj_create_without_buffer(), FLA_realloc(), FLASH_Obj_create_conf_to(), FLASH_Obj_create_helper(), FLASH_Obj_push(), FLASH_Queue_push(), and FLASH_Task_alloc().

00051 {
00052   void*     ptr = NULL;
00053   FLA_Error e_val;
00054 #ifdef FLA_ENABLE_MEMORY_ALIGNMENT
00055   int       r_val;
00056 #endif
00057 
00058   // In practice, the size argument should very rarely be zero. However, if the
00059   // calling code does request a memory region of zero length, we short-circut
00060   // the actual allocation request and just return NULL. Hopefully, the calling
00061   // code is written such that the pointer is never dereferenced. At free()-time
00062   // everything will be fine, as calling free() with a NULl pointer is safe.
00063   // Also note that we do NOT increment the memory counter before returning.
00064   // Likewise, we will not decrement the counter when a NULL pointer is freed.
00065   if ( size == 0 ) return NULL;
00066 
00067 #ifdef FLA_ENABLE_MEMORY_ALIGNMENT
00068 
00069   // Allocate size bytes of memory. Here, we call posix_memalign() if
00070   // memory alignment was requested at configure-time, providing the
00071   // alignment boundary value given by the user. posix_memalign() also
00072   // returns an error code, which is how it signals that something
00073   // went wrong. Compare to malloc(), which does this by simply returning
00074   // a NULL pointer.
00075   r_val = posix_memalign( &ptr, ( size_t ) FLA_MEMORY_ALIGNMENT_BOUNDARY, size );
00076 
00077   // Check the return value of posix_memalign() for evidence that the
00078   // request failed.
00079   if ( FLA_Check_error_level() >= FLA_MIN_ERROR_CHECKING )
00080   {
00081     e_val = FLA_Check_posix_memalign_failure( r_val );
00082     FLA_Check_error_code( e_val );
00083   }
00084 
00085 #else
00086 
00087   // Allocate size bytes of memory. Note that malloc() only guarantees 8-byte
00088   // alignment.
00089   ptr = malloc( size );
00090 
00091   // It may not seem useful to have a check for a null pointer here, given
00092   // that such an occurance would cause the file and line of the error to
00093   // be reported as the below line of the current file instead of the file
00094   // and line number of the calling code. However, consider that in the
00095   // unlikely event that malloc() does return a null pointer, the user will
00096   // have much bigger problems on his hands (e.g. an exhausted memory heap)
00097   // than needing to know exactly what line in the library triggered error.
00098   // Note that such a line in the application code is likely not the root
00099   // source of the problem anyway (ie: not the reason why the heap is full).
00100   if ( FLA_Check_error_level() >= FLA_MIN_ERROR_CHECKING )
00101   {
00102     e_val = FLA_Check_malloc_pointer( ptr );
00103     FLA_Check_error_code( e_val );
00104   }
00105 
00106 #endif
00107 
00108   // Update the memory counter if it is enabled, and do so thread-safely if
00109   // multithreading is enabled.
00110 #ifdef FLA_ENABLE_MEM_COUNTER
00111   #ifdef FLA_ENABLE_MULTITHREADING
00112   FLA_Lock_acquire( &memcounter_lock );
00113   memcounter += 1;
00114   FLA_Lock_release( &memcounter_lock );
00115   #else
00116   memcounter += 1;
00117   #endif
00118 #endif
00119   
00120   // Return the pointer to the new memory region returned by malloc().
00121   return ptr;
00122 }

void* FLA_realloc ( void *  old_ptr,
size_t  size 
)

References FLA_Check_error_level(), FLA_Check_malloc_pointer(), FLA_free(), and FLA_malloc().

00131 {
00132   FLA_Error e_val;
00133   void*     new_ptr;
00134 
00135   // We can't do much if size is zero. To emulate realloc(), we must
00136   // return a NULL pointer, regardless of the value of old_ptr.
00137   if ( size == 0 )
00138   {
00139     // If the pointer is valid, free() it.
00140     if ( old_ptr != NULL )
00141       FLA_free( old_ptr );
00142 
00143     // If size is zero, we should return a NULL pointer.
00144     new_ptr = NULL;
00145   }
00146   else
00147   {
00148     // If old_ptr is NULL, allocate size bytes as if it were a first-time
00149     // FLA_malloc() request. Otherwise, proceed to realloc() the memory.
00150     if ( old_ptr == NULL )
00151     {
00152       new_ptr = FLA_malloc( size );
00153     }
00154     else
00155     {
00156       // At this point, we know that size is non-zero and old_ptr is valid.
00157 
00158       // Since we may need aligned addresses, we don't really want to call
00159       // realloc(), since it does not guarantee arbitrary aligned pointers.
00160       // But we can't implement it ourselves either, because we don't know
00161       // how large the original buffer is, therefor we don't know how much
00162       // to copy over after the new buffer is allocated. So we're stuck with
00163       // the system implementation.
00164       new_ptr = realloc( old_ptr, size );
00165 
00166       if ( FLA_Check_error_level() >= FLA_MIN_ERROR_CHECKING )
00167       {
00168         e_val = FLA_Check_malloc_pointer( new_ptr );
00169         FLA_Check_error_code( e_val );
00170       }
00171     }
00172   }
00173 
00174   // Return the pointer (either NULL, or the return value from FLA_malloc()
00175   // or realloc()).
00176   return new_ptr;
00177 }


Variable Documentation

int memcounter = 0


Generated on Mon Jul 6 05:45:52 2009 for libflame by  doxygen 1.5.9