libflame  revision_anchor
Functions
FLA_Memory.c File Reference

(r)

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

◆ FLA_free()

void FLA_free ( void *  ptr)
248 {
249  // We don't want to decrement the counter if the buffer is NULL.
250  // This is because it's likely that the buffer was never allocated
251  // a valid pointer to begin with, which means FLA_malloc() was never
252  // called and thus the counter was never incremented. Or, it means
253  // memory was allocated but the address has since been lost, which
254  // means that we can't free it anyway.
255  if ( ptr != NULL )
256  {
257  // Free the memory addressed by ptr.
258  free( ptr );
259 
260  if ( FLA_Memory_leak_counter_status() == TRUE )
261  {
262 #ifdef FLA_ENABLE_MULTITHREADING
263  FLA_Lock_acquire( &fla_mem_leak_counter_lock );
264  fla_mem_leak_counter -= 1;
265  FLA_Lock_release( &fla_mem_leak_counter_lock );
266 #else
267  fla_mem_leak_counter -= 1;
268 #endif
269  }
270  }
271 }
FLA_Bool FLA_Memory_leak_counter_status(void)
Definition: FLA_Memory.c:79
void FLA_Lock_release(FLA_Lock *fla_lock_ptr)
Definition: FLA_Lock.c:58
void FLA_Lock_acquire(FLA_Lock *fla_lock_ptr)
Definition: FLA_Lock.c:43

References FLA_Lock_acquire(), 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_Task_free(), and FLASH_Task_free_parallel().

◆ FLA_malloc()

void* FLA_malloc ( size_t  size)
112 {
113  void* ptr = NULL;
114  FLA_Error e_val;
115 #ifdef FLA_ENABLE_MEMORY_ALIGNMENT
116  int r_val;
117 #endif
118 
119  // In practice, the size argument should very rarely be zero. However, if the
120  // calling code does request a memory region of zero length, we short-circut
121  // the actual allocation request and just return NULL. Hopefully, the calling
122  // code is written such that the pointer is never dereferenced. At free()-time
123  // everything will be fine, as calling free() with a NULL pointer is safe.
124  // Also note that we do NOT increment the memory leak counter before returning.
125  // (Likewise, we will not decrement the counter when a NULL pointer is freed.)
126  if ( size == 0 ) return NULL;
127 
128 #ifdef FLA_ENABLE_MEMORY_ALIGNMENT
129 
130  // Allocate size bytes of memory. Here, we call posix_memalign() if
131  // memory alignment was requested at configure-time, providing the
132  // alignment boundary value given by the user. posix_memalign() also
133  // returns an error code, which is how it signals that something
134  // went wrong. Compare to malloc(), which does this by simply returning
135  // a NULL pointer.
136  r_val = posix_memalign( &ptr, ( size_t ) FLA_MEMORY_ALIGNMENT_BOUNDARY, size );
137 
138  // Check the return value of posix_memalign() for evidence that the
139  // request failed.
140  if ( FLA_Check_error_level() >= FLA_MIN_ERROR_CHECKING )
141  {
142  e_val = FLA_Check_posix_memalign_failure( r_val );
143  FLA_Check_error_code( e_val );
144  }
145 
146 #else
147 
148  // Allocate size bytes of memory. Note that malloc() only guarantees 8-byte
149  // alignment.
150  ptr = malloc( size );
151 
152  // It may not seem useful to have a check for a null pointer here, given
153  // that such an occurance would cause the file and line of the error to
154  // be reported as the below line of the current file instead of the file
155  // and line number of the calling code. However, consider that in the
156  // unlikely event that malloc() does return a null pointer, the user will
157  // have much bigger problems on his hands (e.g. an exhausted memory heap)
158  // than needing to know exactly what line in the library triggered error.
159  // Note that such a line in the application code is likely not the root
160  // source of the problem anyway (ie: not the reason why the heap is full).
161  if ( FLA_Check_error_level() >= FLA_MIN_ERROR_CHECKING )
162  {
163  e_val = FLA_Check_malloc_pointer( ptr );
164  FLA_Check_error_code( e_val );
165  }
166 
167 #endif
168 
169  // Update the memory leak counter if it is enabled, and do so thread-safely
170  // if multithreading is enabled.
171  if ( FLA_Memory_leak_counter_status() == TRUE )
172  {
173 #ifdef FLA_ENABLE_MULTITHREADING
174  FLA_Lock_acquire( &fla_mem_leak_counter_lock );
175  fla_mem_leak_counter += 1;
176  FLA_Lock_release( &fla_mem_leak_counter_lock );
177 #else
178  fla_mem_leak_counter += 1;
179 #endif
180  }
181 
182  // Return the pointer to the new memory region returned by malloc().
183  return ptr;
184 }
FLA_Error FLA_Check_malloc_pointer(void *ptr)
Definition: FLA_Check.c:562
unsigned int FLA_Check_error_level(void)
Definition: FLA_Check.c:18
FLA_Error FLA_Check_posix_memalign_failure(int r_val)
Definition: FLA_Check.c:824
int FLA_Error
Definition: FLA_type_defs.h:47

References FLA_Check_error_level(), FLA_Check_malloc_pointer(), FLA_Check_posix_memalign_failure(), FLA_Lock_acquire(), 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(), and FLASH_Task_alloc().

◆ FLA_Memory_leak_counter_finalize()

void FLA_Memory_leak_counter_finalize ( void  )
53 {
54  // Output the memory leak counter, but only if it's currently enabled.
55  if ( FLA_Memory_leak_counter_status() == TRUE )
56  {
57  fprintf( stderr, "libflame: memory leak counter: %d\n", fla_mem_leak_counter );
58  fflush( stderr );
59  }
60 
61  // Destroy the memory leak counter lock, but only if we have locks in
62  // the first place (ie: only if multithreading is enabled).
63 #ifdef FLA_ENABLE_MULTITHREADING
64  FLA_Lock_destroy( &fla_mem_leak_counter_lock );
65 #endif
66 
67  // We leave the fla_mem_leak_counter_status variable alone.
68 
69  // Reset the counter, just for good measure.
70  fla_mem_leak_counter = 0;
71 }
void FLA_Lock_destroy(FLA_Lock *fla_lock_ptr)
Definition: FLA_Lock.c:73

References FLA_Memory_leak_counter_status().

◆ FLA_Memory_leak_counter_init()

void FLA_Memory_leak_counter_init ( void  )
27 {
28  // Initialize the memory leak counter to zero.
29  fla_mem_leak_counter = 0;
30 
31  // Initialize the memory leak counter status to whatever was requested at
32  // configure-time.
33 #ifdef FLA_ENABLE_MEMORY_LEAK_COUNTER
34  fla_mem_leak_counter_status = TRUE;
35 #else
36  fla_mem_leak_counter_status = FALSE;
37 #endif
38 
39  // Initialize the memory leak counter lock, but only if we have locks in
40  // the first place (ie: only if multithreading is enabled).
41 #ifdef FLA_ENABLE_MULTITHREADING
42  FLA_Lock_init( &fla_mem_leak_counter_lock );
43 #endif
44 }
void FLA_Lock_init(FLA_Lock *fla_lock_ptr)
Definition: FLA_Lock.c:28

◆ FLA_Memory_leak_counter_set()

FLA_Bool FLA_Memory_leak_counter_set ( FLA_Bool  new_status)
91 {
92  FLA_Bool old_status;
93 
94  // Grab the current status.
95  old_status = fla_mem_leak_counter_status;
96 
97  // Only make the change if the status is boolean. If the user provides us
98  // with garbage, we do nothing.
99  if ( new_status == TRUE || new_status == FALSE )
100  fla_mem_leak_counter_status = new_status;
101 
102  return old_status;
103 }
int FLA_Bool
Definition: FLA_type_defs.h:46

◆ FLA_Memory_leak_counter_status()

FLA_Bool FLA_Memory_leak_counter_status ( void  )
80 {
81  return fla_mem_leak_counter_status;
82 }

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

◆ FLA_realloc()

void* FLA_realloc ( void *  old_ptr,
size_t  size 
)
193 {
194  FLA_Error e_val;
195  void* new_ptr;
196 
197  // We can't do much if size is zero. To emulate realloc(), we must
198  // return a NULL pointer, regardless of the value of old_ptr.
199  if ( size == 0 )
200  {
201  // If the pointer is valid, free() it.
202  if ( old_ptr != NULL )
203  FLA_free( old_ptr );
204 
205  // If size is zero, we should return a NULL pointer.
206  new_ptr = NULL;
207  }
208  else
209  {
210  // If old_ptr is NULL, allocate size bytes as if it were a first-time
211  // FLA_malloc() request. Otherwise, proceed to realloc() the memory.
212  if ( old_ptr == NULL )
213  {
214  new_ptr = FLA_malloc( size );
215  }
216  else
217  {
218  // At this point, we know that size is non-zero and old_ptr is valid.
219 
220  // Since we may need aligned addresses, we don't really want to call
221  // realloc(), since it does not guarantee arbitrary aligned pointers.
222  // But we can't implement it ourselves either, because we don't know
223  // how large the original buffer is, therefor we don't know how much
224  // to copy over after the new buffer is allocated. So we're stuck with
225  // the system implementation.
226  new_ptr = realloc( old_ptr, size );
227 
228  if ( FLA_Check_error_level() >= FLA_MIN_ERROR_CHECKING )
229  {
230  e_val = FLA_Check_malloc_pointer( new_ptr );
231  FLA_Check_error_code( e_val );
232  }
233  }
234  }
235 
236  // Return the pointer (either NULL, or the return value from FLA_malloc()
237  // or realloc()).
238  return new_ptr;
239 }
void FLA_free(void *ptr)
Definition: FLA_Memory.c:247
void * FLA_malloc(size_t size)
Definition: FLA_Memory.c:111

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