libflame  12600
Functions
FLA_Memory.c File Reference

(r12600)

Functions

void FLA_Memory_leak_counter_init (void)
void FLA_Memory_leak_counter_finalize (void)
FLA_Bool FLA_Memory_leak_counter_status (void)
FLA_Bool FLA_Memory_leak_counter_set (FLA_Bool new_status)
void * FLA_malloc (size_t size)
void * FLA_realloc (void *old_ptr, size_t size)
void FLA_free (void *ptr)

Function Documentation

void FLA_free ( void *  ptr)

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

Referenced by FLA_Apply_H2_UT_l_opc_var1(), FLA_Apply_H2_UT_l_opd_var1(), FLA_Apply_H2_UT_l_ops_var1(), FLA_Apply_H2_UT_l_opz_var1(), FLA_Apply_H2_UT_r_opc_var1(), FLA_Apply_H2_UT_r_opd_var1(), FLA_Apply_H2_UT_r_ops_var1(), FLA_Apply_H2_UT_r_opz_var1(), FLA_Bidiag_UT_u_step_ofc_var2(), FLA_Bidiag_UT_u_step_ofc_var3(), FLA_Bidiag_UT_u_step_ofc_var4(), FLA_Bidiag_UT_u_step_ofd_var2(), FLA_Bidiag_UT_u_step_ofd_var3(), FLA_Bidiag_UT_u_step_ofd_var4(), FLA_Bidiag_UT_u_step_ofs_var2(), FLA_Bidiag_UT_u_step_ofs_var3(), FLA_Bidiag_UT_u_step_ofs_var4(), FLA_Bidiag_UT_u_step_ofz_var2(), FLA_Bidiag_UT_u_step_ofz_var3(), FLA_Bidiag_UT_u_step_ofz_var4(), FLA_Bidiag_UT_u_step_opc_var1(), FLA_Bidiag_UT_u_step_opc_var2(), FLA_Bidiag_UT_u_step_opc_var3(), FLA_Bidiag_UT_u_step_opc_var4(), FLA_Bidiag_UT_u_step_opc_var5(), FLA_Bidiag_UT_u_step_opd_var1(), FLA_Bidiag_UT_u_step_opd_var2(), FLA_Bidiag_UT_u_step_opd_var3(), FLA_Bidiag_UT_u_step_opd_var4(), FLA_Bidiag_UT_u_step_opd_var5(), FLA_Bidiag_UT_u_step_ops_var1(), FLA_Bidiag_UT_u_step_ops_var2(), FLA_Bidiag_UT_u_step_ops_var3(), FLA_Bidiag_UT_u_step_ops_var4(), FLA_Bidiag_UT_u_step_ops_var5(), FLA_Bidiag_UT_u_step_opz_var1(), FLA_Bidiag_UT_u_step_opz_var2(), FLA_Bidiag_UT_u_step_opz_var3(), FLA_Bidiag_UT_u_step_opz_var4(), FLA_Bidiag_UT_u_step_opz_var5(), FLA_Blocksize_free(), FLA_Cntl_obj_free(), FLA_Hess_UT_step_ofc_var2(), FLA_Hess_UT_step_ofc_var3(), FLA_Hess_UT_step_ofc_var4(), FLA_Hess_UT_step_ofd_var2(), FLA_Hess_UT_step_ofd_var3(), FLA_Hess_UT_step_ofd_var4(), FLA_Hess_UT_step_ofs_var2(), FLA_Hess_UT_step_ofs_var3(), FLA_Hess_UT_step_ofs_var4(), FLA_Hess_UT_step_ofz_var2(), FLA_Hess_UT_step_ofz_var3(), FLA_Hess_UT_step_ofz_var4(), FLA_Hess_UT_step_opc_var2(), FLA_Hess_UT_step_opc_var3(), FLA_Hess_UT_step_opc_var4(), FLA_Hess_UT_step_opc_var5(), FLA_Hess_UT_step_opd_var2(), FLA_Hess_UT_step_opd_var3(), FLA_Hess_UT_step_opd_var4(), FLA_Hess_UT_step_opd_var5(), FLA_Hess_UT_step_ops_var2(), FLA_Hess_UT_step_ops_var3(), FLA_Hess_UT_step_ops_var4(), FLA_Hess_UT_step_ops_var5(), FLA_Hess_UT_step_opz_var2(), FLA_Hess_UT_step_opz_var3(), FLA_Hess_UT_step_opz_var4(), FLA_Hess_UT_step_opz_var5(), FLA_Obj_free(), FLA_Obj_free_buffer(), FLA_Obj_free_without_buffer(), FLA_realloc(), FLA_Tridiag_UT_l_step_ofc_var2(), FLA_Tridiag_UT_l_step_ofd_var2(), FLA_Tridiag_UT_l_step_ofs_var2(), FLA_Tridiag_UT_l_step_ofz_var2(), FLA_Tridiag_UT_l_step_opc_var1(), FLA_Tridiag_UT_l_step_opc_var2(), FLA_Tridiag_UT_l_step_opc_var3(), FLA_Tridiag_UT_l_step_opd_var1(), FLA_Tridiag_UT_l_step_opd_var2(), FLA_Tridiag_UT_l_step_opd_var3(), FLA_Tridiag_UT_l_step_ops_var1(), FLA_Tridiag_UT_l_step_ops_var2(), FLA_Tridiag_UT_l_step_ops_var3(), FLA_Tridiag_UT_l_step_opz_var1(), FLA_Tridiag_UT_l_step_opz_var2(), FLA_Tridiag_UT_l_step_opz_var3(), FLASH_Obj_create_conf_to(), FLASH_Obj_create_helper(), FLASH_Obj_free(), FLASH_Part_create_1x2(), FLASH_Part_create_2x1(), FLASH_Part_create_2x2(), FLASH_Queue_exec(), FLASH_Queue_exec_gpu(), FLASH_Queue_exec_parallel(), FLASH_Queue_exec_simulation(), FLASH_Queue_push_output(), FLASH_Task_free(), and FLASH_Task_free_parallel().

{
  // We don't want to decrement the counter if the buffer is NULL.
  // This is because it's likely that the buffer was never allocated
  // a valid pointer to begin with, which means FLA_malloc() was never
  // called and thus the counter was never incremented. Or, it means
  // memory was allocated but the address has since been lost, which
  // means that we can't free it anyway.
  if ( ptr != NULL )
  {
    // Free the memory addressed by ptr.
    free( ptr );

    if ( FLA_Memory_leak_counter_status() == TRUE )
    {
#ifdef FLA_ENABLE_MULTITHREADING
      FLA_Lock_acquire( &fla_mem_leak_counter_lock );
      fla_mem_leak_counter -= 1;
      FLA_Lock_release( &fla_mem_leak_counter_lock );
#else
      fla_mem_leak_counter -= 1;
#endif
    }
  }
}
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 FLA_Memory_leak_counter_status().

Referenced by FLA_Apply_H2_UT_l_opc_var1(), FLA_Apply_H2_UT_l_opd_var1(), FLA_Apply_H2_UT_l_ops_var1(), FLA_Apply_H2_UT_l_opz_var1(), FLA_Apply_H2_UT_r_opc_var1(), FLA_Apply_H2_UT_r_opd_var1(), FLA_Apply_H2_UT_r_ops_var1(), FLA_Apply_H2_UT_r_opz_var1(), FLA_Bidiag_UT_u_step_ofc_var2(), FLA_Bidiag_UT_u_step_ofc_var3(), FLA_Bidiag_UT_u_step_ofc_var4(), FLA_Bidiag_UT_u_step_ofd_var2(), FLA_Bidiag_UT_u_step_ofd_var3(), FLA_Bidiag_UT_u_step_ofd_var4(), FLA_Bidiag_UT_u_step_ofs_var2(), FLA_Bidiag_UT_u_step_ofs_var3(), FLA_Bidiag_UT_u_step_ofs_var4(), FLA_Bidiag_UT_u_step_ofz_var2(), FLA_Bidiag_UT_u_step_ofz_var3(), FLA_Bidiag_UT_u_step_ofz_var4(), FLA_Bidiag_UT_u_step_opc_var1(), FLA_Bidiag_UT_u_step_opc_var2(), FLA_Bidiag_UT_u_step_opc_var3(), FLA_Bidiag_UT_u_step_opc_var4(), FLA_Bidiag_UT_u_step_opc_var5(), FLA_Bidiag_UT_u_step_opd_var1(), FLA_Bidiag_UT_u_step_opd_var2(), FLA_Bidiag_UT_u_step_opd_var3(), FLA_Bidiag_UT_u_step_opd_var4(), FLA_Bidiag_UT_u_step_opd_var5(), FLA_Bidiag_UT_u_step_ops_var1(), FLA_Bidiag_UT_u_step_ops_var2(), FLA_Bidiag_UT_u_step_ops_var3(), FLA_Bidiag_UT_u_step_ops_var4(), FLA_Bidiag_UT_u_step_ops_var5(), FLA_Bidiag_UT_u_step_opz_var1(), FLA_Bidiag_UT_u_step_opz_var2(), FLA_Bidiag_UT_u_step_opz_var3(), FLA_Bidiag_UT_u_step_opz_var4(), FLA_Bidiag_UT_u_step_opz_var5(), FLA_Blocksize_create(), FLA_Blocksize_create_copy(), FLA_Cntl_apcaq2ut_obj_create(), FLA_Cntl_apcaqutinc_obj_create(), FLA_Cntl_appiv_obj_create(), FLA_Cntl_apq2ut_obj_create(), FLA_Cntl_apqudut_obj_create(), FLA_Cntl_apqudutinc_obj_create(), FLA_Cntl_apqut_obj_create(), FLA_Cntl_apqutinc_obj_create(), FLA_Cntl_axpy_obj_create(), FLA_Cntl_axpyt_obj_create(), FLA_Cntl_bidiagut_obj_create(), FLA_Cntl_caqr2ut_obj_create(), FLA_Cntl_caqrutinc_obj_create(), FLA_Cntl_chol_obj_create(), FLA_Cntl_copy_obj_create(), FLA_Cntl_copyr_obj_create(), FLA_Cntl_copyt_obj_create(), FLA_Cntl_eig_gest_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_hessut_obj_create(), FLA_Cntl_lqut_obj_create(), FLA_Cntl_lu_obj_create(), FLA_Cntl_lyap_obj_create(), FLA_Cntl_qr2ut_obj_create(), FLA_Cntl_qrut_obj_create(), FLA_Cntl_qrutinc_obj_create(), FLA_Cntl_scal_obj_create(), FLA_Cntl_scalr_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_tridiagut_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_Cntl_uddateut_obj_create(), FLA_Cntl_uddateutinc_obj_create(), FLA_Hess_UT_step_ofc_var2(), FLA_Hess_UT_step_ofc_var3(), FLA_Hess_UT_step_ofc_var4(), FLA_Hess_UT_step_ofd_var2(), FLA_Hess_UT_step_ofd_var3(), FLA_Hess_UT_step_ofd_var4(), FLA_Hess_UT_step_ofs_var2(), FLA_Hess_UT_step_ofs_var3(), FLA_Hess_UT_step_ofs_var4(), FLA_Hess_UT_step_ofz_var2(), FLA_Hess_UT_step_ofz_var3(), FLA_Hess_UT_step_ofz_var4(), FLA_Hess_UT_step_opc_var2(), FLA_Hess_UT_step_opc_var3(), FLA_Hess_UT_step_opc_var4(), FLA_Hess_UT_step_opc_var5(), FLA_Hess_UT_step_opd_var2(), FLA_Hess_UT_step_opd_var3(), FLA_Hess_UT_step_opd_var4(), FLA_Hess_UT_step_opd_var5(), FLA_Hess_UT_step_ops_var2(), FLA_Hess_UT_step_ops_var3(), FLA_Hess_UT_step_ops_var4(), FLA_Hess_UT_step_ops_var5(), FLA_Hess_UT_step_opz_var2(), FLA_Hess_UT_step_opz_var3(), FLA_Hess_UT_step_opz_var4(), FLA_Hess_UT_step_opz_var5(), FLA_Obj_create_buffer(), FLA_Obj_create_ext(), FLA_Obj_create_without_buffer(), FLA_realloc(), FLA_Tridiag_UT_l_step_ofc_var2(), FLA_Tridiag_UT_l_step_ofd_var2(), FLA_Tridiag_UT_l_step_ofs_var2(), FLA_Tridiag_UT_l_step_ofz_var2(), FLA_Tridiag_UT_l_step_opc_var1(), FLA_Tridiag_UT_l_step_opc_var2(), FLA_Tridiag_UT_l_step_opc_var3(), FLA_Tridiag_UT_l_step_opd_var1(), FLA_Tridiag_UT_l_step_opd_var2(), FLA_Tridiag_UT_l_step_opd_var3(), FLA_Tridiag_UT_l_step_ops_var1(), FLA_Tridiag_UT_l_step_ops_var2(), FLA_Tridiag_UT_l_step_ops_var3(), FLA_Tridiag_UT_l_step_opz_var1(), FLA_Tridiag_UT_l_step_opz_var2(), FLA_Tridiag_UT_l_step_opz_var3(), FLASH_Obj_create_conf_to(), FLASH_Obj_create_helper(), FLASH_Part_create_1x2(), FLASH_Part_create_2x1(), FLASH_Part_create_2x2(), FLASH_Queue_exec(), FLASH_Queue_exec_gpu(), FLASH_Queue_exec_parallel(), FLASH_Queue_exec_simulation(), FLASH_Queue_push_input(), FLASH_Queue_push_output(), and FLASH_Task_alloc().

{
  void*     ptr = NULL;
  FLA_Error e_val;
#ifdef FLA_ENABLE_MEMORY_ALIGNMENT
  int       r_val;
#endif

  // In practice, the size argument should very rarely be zero. However, if the
  // calling code does request a memory region of zero length, we short-circut
  // the actual allocation request and just return NULL. Hopefully, the calling
  // code is written such that the pointer is never dereferenced. At free()-time
  // everything will be fine, as calling free() with a NULL pointer is safe.
  // Also note that we do NOT increment the memory leak counter before returning.
  // (Likewise, we will not decrement the counter when a NULL pointer is freed.)
  if ( size == 0 ) return NULL;

#ifdef FLA_ENABLE_MEMORY_ALIGNMENT

  // Allocate size bytes of memory. Here, we call posix_memalign() if
  // memory alignment was requested at configure-time, providing the
  // alignment boundary value given by the user. posix_memalign() also
  // returns an error code, which is how it signals that something
  // went wrong. Compare to malloc(), which does this by simply returning
  // a NULL pointer.
  r_val = posix_memalign( &ptr, ( size_t ) FLA_MEMORY_ALIGNMENT_BOUNDARY, size );

  // Check the return value of posix_memalign() for evidence that the
  // request failed.
  if ( FLA_Check_error_level() >= FLA_MIN_ERROR_CHECKING )
  {
    e_val = FLA_Check_posix_memalign_failure( r_val );
    FLA_Check_error_code( e_val );
  }

#else

  // Allocate size bytes of memory. Note that malloc() only guarantees 8-byte
  // alignment.
  ptr = malloc( size );

  // It may not seem useful to have a check for a null pointer here, given
  // that such an occurance would cause the file and line of the error to
  // be reported as the below line of the current file instead of the file
  // and line number of the calling code. However, consider that in the
  // unlikely event that malloc() does return a null pointer, the user will
  // have much bigger problems on his hands (e.g. an exhausted memory heap)
  // than needing to know exactly what line in the library triggered error.
  // Note that such a line in the application code is likely not the root
  // source of the problem anyway (ie: not the reason why the heap is full).
  if ( FLA_Check_error_level() >= FLA_MIN_ERROR_CHECKING )
  {
    e_val = FLA_Check_malloc_pointer( ptr );
    FLA_Check_error_code( e_val );
  }

#endif

  // Update the memory leak counter if it is enabled, and do so thread-safely
  // if multithreading is enabled.
  if ( FLA_Memory_leak_counter_status() == TRUE )
  {
#ifdef FLA_ENABLE_MULTITHREADING
    FLA_Lock_acquire( &fla_mem_leak_counter_lock );
    fla_mem_leak_counter += 1;
    FLA_Lock_release( &fla_mem_leak_counter_lock );
#else
    fla_mem_leak_counter += 1;
#endif
  }
  
  // Return the pointer to the new memory region returned by malloc().
  return ptr;
}

References FLA_Lock_destroy(), and FLA_Memory_leak_counter_status().

Referenced by FLA_Finalize().

{
  // Output the memory leak counter, but only if it's currently enabled.
  if ( FLA_Memory_leak_counter_status() == TRUE )
  {
    fprintf( stderr, "libflame: memory leak counter: %d\n", fla_mem_leak_counter );
    fflush( stderr );
  }

  // Destroy the memory leak counter lock, but only if we have locks in
  // the first place (ie: only if multithreading is enabled).
#ifdef FLA_ENABLE_MULTITHREADING
  FLA_Lock_destroy( &fla_mem_leak_counter_lock );
#endif

  // We leave the fla_mem_leak_counter_status variable alone.

  // Reset the counter, just for good measure.
  fla_mem_leak_counter = 0;
}

References FLA_Lock_init().

Referenced by FLA_Init().

{
  // Initialize the memory leak counter to zero.
  fla_mem_leak_counter = 0;

  // Initialize the memory leak counter status to whatever was requested at
  // configure-time.
#ifdef FLA_ENABLE_MEMORY_LEAK_COUNTER
  fla_mem_leak_counter_status = TRUE;
#else
  fla_mem_leak_counter_status = FALSE;
#endif

  // Initialize the memory leak counter lock, but only if we have locks in
  // the first place (ie: only if multithreading is enabled).
#ifdef FLA_ENABLE_MULTITHREADING
  FLA_Lock_init( &fla_mem_leak_counter_lock );
#endif
}
{
  FLA_Bool old_status;

  // Grab the current status.
  old_status = fla_mem_leak_counter_status;

  // Only make the change if the status is boolean. If the user provides us
  // with garbage, we do nothing.
  if ( new_status == TRUE || new_status == FALSE )
    fla_mem_leak_counter_status = new_status;

  return old_status;
}

Referenced by FLA_free(), FLA_malloc(), and FLA_Memory_leak_counter_finalize().

{
  return fla_mem_leak_counter_status;
}
void* FLA_realloc ( void *  old_ptr,
size_t  size 
)

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

{
  FLA_Error e_val;
  void*     new_ptr;

  // We can't do much if size is zero. To emulate realloc(), we must
  // return a NULL pointer, regardless of the value of old_ptr.
  if ( size == 0 )
  {
    // If the pointer is valid, free() it.
    if ( old_ptr != NULL )
      FLA_free( old_ptr );

    // If size is zero, we should return a NULL pointer.
    new_ptr = NULL;
  }
  else
  {
    // If old_ptr is NULL, allocate size bytes as if it were a first-time
    // FLA_malloc() request. Otherwise, proceed to realloc() the memory.
    if ( old_ptr == NULL )
    {
      new_ptr = FLA_malloc( size );
    }
    else
    {
      // At this point, we know that size is non-zero and old_ptr is valid.

      // Since we may need aligned addresses, we don't really want to call
      // realloc(), since it does not guarantee arbitrary aligned pointers.
      // But we can't implement it ourselves either, because we don't know
      // how large the original buffer is, therefor we don't know how much
      // to copy over after the new buffer is allocated. So we're stuck with
      // the system implementation.
      new_ptr = realloc( old_ptr, size );

      if ( FLA_Check_error_level() >= FLA_MIN_ERROR_CHECKING )
      {
        e_val = FLA_Check_malloc_pointer( new_ptr );
        FLA_Check_error_code( e_val );
      }
    }
  }

  // Return the pointer (either NULL, or the return value from FLA_malloc()
  // or realloc()).
  return new_ptr;
}