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 |
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 }
int memcounter = 0 |
Referenced by FLA_Finalize_memcounter(), FLA_free(), FLA_Init_memcounter(), and FLA_malloc().