2020-11-05 15:34:58 +01:00
|
|
|
** Memory management
|
2020-10-22 01:24:14 +02:00
|
|
|
|
2020-11-05 15:34:58 +01:00
|
|
|
We override the allocation functions to enable the possibility of
|
|
|
|
optimized libraries to fine-tune the memory allocation.
|
2020-10-16 23:56:22 +02:00
|
|
|
|
2020-11-05 15:34:58 +01:00
|
|
|
2 files are produced:
|
|
|
|
- a source file : =qmckl_memory.c=
|
|
|
|
- a test file : =test_qmckl_memory.c=
|
2020-10-16 23:56:22 +02:00
|
|
|
|
2020-11-05 15:34:58 +01:00
|
|
|
*** Headers :noexport:
|
|
|
|
#+BEGIN_SRC C :tangle qmckl_memory.c
|
2020-10-16 23:56:22 +02:00
|
|
|
#include "qmckl.h"
|
2021-02-19 01:39:42 +01:00
|
|
|
#include <assert.h>
|
2020-11-05 15:34:58 +01:00
|
|
|
#+END_SRC
|
2020-10-16 23:56:22 +02:00
|
|
|
|
2020-11-05 15:34:58 +01:00
|
|
|
#+BEGIN_SRC C :tangle test_qmckl_memory.c
|
2020-10-17 01:10:54 +02:00
|
|
|
#include "qmckl.h"
|
|
|
|
#include "munit.h"
|
2020-10-21 19:50:18 +02:00
|
|
|
MunitResult test_qmckl_memory() {
|
2020-11-05 15:34:58 +01:00
|
|
|
#+END_SRC
|
2020-10-16 23:56:22 +02:00
|
|
|
|
2020-12-03 18:57:15 +01:00
|
|
|
*** ~qmckl_malloc~
|
2020-11-05 15:27:25 +01:00
|
|
|
|
2020-11-05 15:34:58 +01:00
|
|
|
Memory allocation function, letting the library choose how the
|
|
|
|
memory will be allocated, and a pointer is returned to the user.
|
2021-02-19 01:39:42 +01:00
|
|
|
The context is passed to let the library store data related to the
|
|
|
|
allocation inside the context.
|
2020-11-05 15:27:25 +01:00
|
|
|
|
2020-11-05 15:34:58 +01:00
|
|
|
#+BEGIN_SRC C :tangle qmckl.h
|
2020-10-22 00:50:07 +02:00
|
|
|
void* qmckl_malloc(const qmckl_context ctx, const size_t size);
|
2020-11-05 15:34:58 +01:00
|
|
|
#+END_SRC
|
2020-10-16 23:56:22 +02:00
|
|
|
|
2020-11-05 15:34:58 +01:00
|
|
|
#+BEGIN_SRC f90 :tangle qmckl_f.f90
|
2020-11-05 15:27:25 +01:00
|
|
|
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
|
2020-11-05 15:34:58 +01:00
|
|
|
#+END_SRC
|
2020-11-05 15:27:25 +01:00
|
|
|
|
2020-11-05 15:34:58 +01:00
|
|
|
**** Source
|
|
|
|
#+BEGIN_SRC C :tangle qmckl_memory.c
|
2020-10-22 00:50:07 +02:00
|
|
|
void* qmckl_malloc(const qmckl_context ctx, const size_t size) {
|
2021-02-19 01:39:42 +01:00
|
|
|
if (ctx == (qmckl_context) 0) {}; /* Avoid unused argument warning */
|
|
|
|
void * result = malloc( (size_t) size );
|
|
|
|
assert (result != NULL) ;
|
|
|
|
return result;
|
2020-10-16 23:56:22 +02:00
|
|
|
}
|
|
|
|
|
2020-11-05 15:34:58 +01:00
|
|
|
#+END_SRC
|
2020-10-22 01:24:14 +02:00
|
|
|
|
2020-11-05 15:34:58 +01:00
|
|
|
**** Test :noexport:
|
|
|
|
#+BEGIN_SRC C :tangle test_qmckl_memory.c
|
2021-02-19 01:39:42 +01:00
|
|
|
int *a = NULL;
|
|
|
|
munit_assert(a == NULL);
|
2020-11-05 15:27:25 +01:00
|
|
|
a = (int*) qmckl_malloc( (qmckl_context) 1, 3*sizeof(int));
|
2021-02-19 01:39:42 +01:00
|
|
|
munit_assert(a != NULL);
|
2020-11-05 15:27:25 +01:00
|
|
|
a[0] = 1;
|
|
|
|
a[1] = 2;
|
|
|
|
a[2] = 3;
|
|
|
|
munit_assert_int(a[0], ==, 1);
|
|
|
|
munit_assert_int(a[1], ==, 2);
|
|
|
|
munit_assert_int(a[2], ==, 3);
|
2020-11-05 15:34:58 +01:00
|
|
|
#+END_SRC
|
2020-10-16 23:56:22 +02:00
|
|
|
|
2020-12-03 18:57:15 +01:00
|
|
|
*** ~qmckl_free~
|
2020-10-16 23:56:22 +02:00
|
|
|
|
2021-03-05 03:45:30 +01:00
|
|
|
The context is passed, in case some important information has been
|
|
|
|
stored related to memory allocation and needs to be updated.
|
|
|
|
|
2020-11-05 15:34:58 +01:00
|
|
|
#+BEGIN_SRC C :tangle qmckl.h
|
2021-03-05 03:45:30 +01:00
|
|
|
qmckl_exit_code qmckl_free(qmckl_context context, void *ptr);
|
2020-11-05 15:34:58 +01:00
|
|
|
#+END_SRC
|
2020-10-16 23:56:22 +02:00
|
|
|
|
2020-11-05 15:34:58 +01:00
|
|
|
#+BEGIN_SRC f90 :tangle qmckl_f.f90
|
2020-11-05 15:27:25 +01:00
|
|
|
interface
|
2021-03-05 03:45:30 +01:00
|
|
|
integer (c_int32_t) function qmckl_free (context, ptr) bind(C)
|
2020-11-05 15:27:25 +01:00
|
|
|
use, intrinsic :: iso_c_binding
|
2021-03-05 03:45:30 +01:00
|
|
|
integer (c_int64_t), intent(in), value :: context
|
2020-11-05 15:27:25 +01:00
|
|
|
type (c_ptr), intent(in), value :: ptr
|
2021-02-19 01:39:42 +01:00
|
|
|
end function qmckl_free
|
2020-11-05 15:27:25 +01:00
|
|
|
end interface
|
2020-11-05 15:34:58 +01:00
|
|
|
#+END_SRC
|
2021-03-05 03:45:30 +01:00
|
|
|
|
2020-11-05 15:34:58 +01:00
|
|
|
**** Source
|
|
|
|
#+BEGIN_SRC C :tangle qmckl_memory.c
|
2021-03-05 03:45:30 +01:00
|
|
|
qmckl_exit_code qmckl_free(qmckl_context context, void *ptr) {
|
|
|
|
if (context == 0) return QMCKL_INVALID_ARG_1;
|
|
|
|
if (ptr == NULL) return QMCKL_INVALID_ARG_2;
|
2020-10-16 23:56:22 +02:00
|
|
|
free(ptr);
|
2021-03-05 03:45:30 +01:00
|
|
|
return QMCKL_SUCCESS;
|
2020-10-16 23:56:22 +02:00
|
|
|
}
|
2020-11-05 15:34:58 +01:00
|
|
|
#+END_SRC
|
2020-10-22 01:24:14 +02:00
|
|
|
|
2020-11-05 15:34:58 +01:00
|
|
|
**** Test :noexport:
|
|
|
|
#+BEGIN_SRC C :tangle test_qmckl_memory.c
|
2021-02-19 01:39:42 +01:00
|
|
|
munit_assert(a != NULL);
|
2021-03-05 03:45:30 +01:00
|
|
|
qmckl_exit_code rc;
|
|
|
|
rc = qmckl_free( (qmckl_context) 1, a);
|
|
|
|
munit_assert(rc == QMCKL_SUCCESS);
|
2021-02-19 01:39:42 +01:00
|
|
|
|
2020-11-05 15:34:58 +01:00
|
|
|
#+END_SRC
|
2020-10-16 23:56:22 +02:00
|
|
|
|
2020-11-05 15:34:58 +01:00
|
|
|
*** End of files :noexport:
|
2020-10-16 23:56:22 +02:00
|
|
|
|
2020-11-05 15:34:58 +01:00
|
|
|
**** Test
|
|
|
|
#+BEGIN_SRC C :comments org :tangle test_qmckl_memory.c
|
2020-10-17 01:10:54 +02:00
|
|
|
return MUNIT_OK;
|
2020-10-22 01:24:14 +02:00
|
|
|
}
|
2020-10-17 01:10:54 +02:00
|
|
|
|
2020-11-05 15:34:58 +01:00
|
|
|
#+END_SRC
|
2020-11-05 15:27:25 +01:00
|
|
|
|
|
|
|
|
2020-11-05 15:34:58 +01:00
|
|
|
# -*- mode: org -*-
|
|
|
|
# vim: syntax=c
|