1 #include "ltfat.h"
2 #include "ltfat/types.h"
3 #include "ltfat/memalloc.h"
4 
5 #ifdef FFTW
6 #include "ltfat/thirdparty/fftw3.h"
7 #endif
8 
9 #include <stdlib.h>
10 /* #include "ltfat/macros.h" */
11 
12 
13 void* (*ltfat_custom_malloc)(size_t) = NULL;
14 void (*ltfat_custom_free)(void*) = NULL;
15 
16 ltfat_memory_handler_t
ltfat_set_memory_handler(ltfat_memory_handler_t new_handler)17 ltfat_set_memory_handler (ltfat_memory_handler_t new_handler)
18 {
19     ltfat_memory_handler_t retVal = { ltfat_custom_malloc, ltfat_custom_free };
20 
21     ltfat_custom_malloc = new_handler.malloc;
22     ltfat_custom_free = new_handler.free;
23     return retVal;
24 }
25 
26 #ifdef KISS
27 #define ALIGNBOUNDARY 64
28 
29 static void*
ltfat_aligned_malloc(size_t size)30 ltfat_aligned_malloc(size_t size)
31 {
32     void* mem = malloc(size + sizeof(void*) + ALIGNBOUNDARY - 1);
33     void* ptr = (void**)
34                 (((size_t)mem + (ALIGNBOUNDARY - 1) + sizeof(void*)) &
35                  ~(ALIGNBOUNDARY - 1));
36 
37     ((void**) ptr)[-1] = mem;
38     return ptr;
39 }
40 
41 static void
ltfat_aligned_free(void * ptr)42 ltfat_aligned_free(void* ptr)
43 {
44     free(((void**) ptr)[-1]);
45 }
46 #endif
47 
48 LTFAT_API void*
ltfat_malloc(size_t n)49 ltfat_malloc (size_t n)
50 {
51     void* outp;
52 
53     if (ltfat_custom_malloc)
54         outp = (*ltfat_custom_malloc)(n);
55     else
56 #ifdef FFTW
57         outp = LTFAT_FFTW(malloc)(n);
58 #elif KISS
59         outp = ltfat_aligned_malloc(n);
60 #else
61 #error "No FFT backend specified. Use -DKISS or -DFFTW"
62 #endif
63     return outp;
64 }
65 
66 
67 LTFAT_API void*
ltfat_postpad(void * ptr,size_t nold,size_t nnew)68 ltfat_postpad (void* ptr, size_t nold, size_t nnew)
69 {
70     if(!ptr)
71         return ltfat_calloc(nnew, 1);
72 
73     if (nnew > nold)
74     {
75         void* outp = ltfat_realloc (ptr, nold, nnew);
76         if (!outp) return NULL;
77 
78         memset(((unsigned char*)outp) + nold, 0, nnew - nold);
79         return outp;
80     }
81     return ptr;
82 }
83 
84 LTFAT_API void*
ltfat_realloc(void * ptr,size_t nold,size_t nnew)85 ltfat_realloc (void* ptr, size_t nold, size_t nnew)
86 {
87     void* outp = ltfat_malloc(nnew);
88 
89     if (!outp) return NULL;
90 
91     if (ptr)
92     {
93         memcpy(outp, ptr, nold < nnew ? nold : nnew);
94         ltfat_free(ptr);
95     }
96 
97     return outp;
98 }
99 
100 LTFAT_API void*
ltfat_calloc(size_t nmemb,size_t size)101 ltfat_calloc (size_t nmemb, size_t size)
102 {
103     void* outp = ltfat_malloc(nmemb * size);
104 
105     if (!outp)
106         return NULL;
107 
108     memset(outp, 0, nmemb * size);
109 
110     return outp;
111 }
112 
113 LTFAT_API void
ltfat_free(const void * ptr)114 ltfat_free(const void* ptr)
115 {
116     if (ltfat_custom_free)
117         (*ltfat_custom_free)((void*)ptr);
118     else
119 #ifdef FFTW
120         LTFAT_FFTW(free)((void*)ptr);
121 #elif KISS
122         ltfat_aligned_free((void*)ptr);
123 #endif
124 }
125 
126 LTFAT_API void
ltfat_safefree(const void * ptr)127 ltfat_safefree(const void* ptr)
128 {
129     if (ptr)
130         ltfat_free((void*)ptr);
131 }
132