1
0
mirror of https://github.com/TREX-CoE/qmckl.git synced 2024-11-19 20:42:50 +01:00
qmckl/src/qmckl_memory.org
2021-03-10 12:58:38 +01:00

4.1 KiB

Memory management

We override the allocation functions to enable the possibility of optimized libraries to fine-tune the memory allocation.

Memory allocation inside the library should be done with qmckl_malloc. It lets the library choose how the memory will be allocated, and a pointer is returned to the user. The context is passed to let the library store data related to the allocation inside the context. In this particular implementation of the library, we store a list of allocated pointers so that all the memory can be properly freed when the library is de-initialized. If the allocation failed, the NULL pointer is returned.

void* qmckl_malloc(qmckl_context context,
                 const size_t size);
void* qmckl_malloc(qmckl_context context, const size_t size) {

void * pointer = malloc( (size_t) size );

if (qmckl_context_check(context) != QMCKL_NULL_CONTEXT) {
  qmckl_exit_code rc;
  rc = qmckl_context_append_memory(context, pointer, size);
  assert (rc == QMCKL_SUCCESS);
}

return pointer;
}
interface
   type (c_ptr) function qmckl_malloc (context, size) bind(C)
     use, intrinsic :: iso_c_binding
     integer (c_int64_t), intent(in), value :: context
     integer (c_int64_t), intent(in), value :: size
   end function qmckl_malloc
end interface

qmckl_free

The context is passed, in case some important information has been stored related to memory allocation and needs to be updated.

qmckl_exit_code qmckl_free(qmckl_context context,
                         void *ptr);
interface
   integer (c_int32_t) function qmckl_free (context, ptr) bind(C)
     use, intrinsic :: iso_c_binding
     integer (c_int64_t), intent(in), value :: context
     type (c_ptr), intent(in), value :: ptr
   end function qmckl_free
end interface

Source

qmckl_exit_code qmckl_free(qmckl_context context, void *ptr) {
if (qmckl_context_check(context) != QMCKL_NULL_CONTEXT) {

 if (ptr == NULL) {
   return qmckl_failwith(context,
                         QMCKL_INVALID_ARG_2,
                         "qmckl_free",
                         "NULL pointer");
 }
 
 qmckl_exit_code rc;
 rc = qmckl_context_remove_memory(context, ptr);

 assert (rc == QMCKL_SUCCESS);
}
free(ptr);
return QMCKL_SUCCESS;
}