1 /* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */
2
3 #include <assert.h>
4
5 #include "libmctp.h"
6 #include "libmctp-alloc.h"
7
8 #ifdef HAVE_CONFIG_H
9 #include "config.h"
10 #endif
11
12 #include "compiler.h"
13
14 #if defined(MCTP_DEFAULT_ALLOC) && defined(MCTP_CUSTOM_ALLOC)
15 #error Default and Custom alloc are incompatible
16 #endif
17
18 #ifdef MCTP_DEFAULT_ALLOC
default_msg_malloc(size_t size,void * ctx __unused)19 static void *default_msg_malloc(size_t size, void *ctx __unused)
20 {
21 void *ptr = __mctp_alloc(size);
22 return ptr;
23 }
24
default_msg_free(void * msg,void * ctx __unused)25 static void default_msg_free(void *msg, void *ctx __unused)
26 {
27 __mctp_free(msg);
28 }
29 #endif
30
31 /* Allocators provided as functions to call */
32 #ifdef MCTP_CUSTOM_ALLOC
33 extern void *mctp_custom_malloc(size_t size);
34 extern void mctp_custom_free(void *ptr);
35 extern void *mctp_custom_msg_alloc(size_t size, void *ctx);
36 extern void mctp_custom_msg_free(void *msg, void *ctx);
37 #endif
38
39 #ifdef MCTP_CUSTOM_ALLOC
40 const
41 #endif
42 struct {
43 void *(*m_alloc)(size_t);
44 void (*m_free)(void *);
45 /* Final argument is ctx */
46 void *(*m_msg_alloc)(size_t, void *);
47 void (*m_msg_free)(void *, void *);
48 } alloc_ops = {
49 #ifdef MCTP_DEFAULT_ALLOC
50 malloc,
51 free,
52 default_msg_malloc,
53 default_msg_free,
54 #endif
55 #ifdef MCTP_CUSTOM_ALLOC
56 mctp_custom_malloc,
57 mctp_custom_free,
58 mctp_custom_msg_alloc,
59 mctp_custom_msg_free,
60 #endif
61 };
62
63 /* internal-only allocation functions */
__mctp_alloc(size_t size)64 void *__mctp_alloc(size_t size)
65 {
66 if (alloc_ops.m_alloc)
67 return alloc_ops.m_alloc(size);
68 assert(0);
69 return NULL;
70 }
71
__mctp_free(void * ptr)72 void __mctp_free(void *ptr)
73 {
74 if (alloc_ops.m_free)
75 alloc_ops.m_free(ptr);
76 else
77 assert(0);
78 }
79
__mctp_msg_alloc(size_t size,struct mctp * mctp)80 void *__mctp_msg_alloc(size_t size, struct mctp *mctp)
81 {
82 void *ctx = mctp_get_alloc_ctx(mctp);
83 if (alloc_ops.m_msg_alloc)
84 return alloc_ops.m_msg_alloc(size, ctx);
85 assert(0);
86 return NULL;
87 }
88
__mctp_msg_free(void * ptr,struct mctp * mctp)89 void __mctp_msg_free(void *ptr, struct mctp *mctp)
90 {
91 void *ctx = mctp_get_alloc_ctx(mctp);
92 if (alloc_ops.m_msg_free)
93 alloc_ops.m_msg_free(ptr, ctx);
94 }
95
96 #ifndef MCTP_CUSTOM_ALLOC
mctp_set_alloc_ops(void * (* m_alloc)(size_t),void (* m_free)(void *),void * (* m_msg_alloc)(size_t,void *),void (* m_msg_free)(void *,void *))97 void mctp_set_alloc_ops(void *(*m_alloc)(size_t), void (*m_free)(void *),
98 void *(*m_msg_alloc)(size_t, void *),
99 void (*m_msg_free)(void *, void *))
100 {
101 alloc_ops.m_alloc = m_alloc;
102 alloc_ops.m_free = m_free;
103 alloc_ops.m_msg_alloc = m_msg_alloc;
104 alloc_ops.m_msg_free = m_msg_free;
105 }
106 #endif // MCTP_CUSTOM_ALLOC
107