agileRTOS (zrtos)  Version 0.8.0 (ghostbuster)
malloc.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2024 ykat UG (haftungsbeschraenkt) - All Rights Reserved
3  *
4  * Permission for non-commercial use is hereby granted,
5  * free of charge, without warranty of any kind.
6  */
7 #ifndef ZRTOS_MALLOC_H
8 #define ZRTOS_MALLOC_H
9 #ifdef __cplusplus
10 extern "C" {
11 #endif
12 
13 #include <zrtos/assert.h>
14 #include <zrtos/types.h>
15 #include <zrtos/cast.h>
16 #include <zrtos/debug.h>
17 
18 #ifdef ZRTOS_ARCH__BYTE_ALIGNMENT
19 #define ZRTOS_MALLOC__BYTE_ALIGNMENT ZRTOS_ARCH__BYTE_ALIGNMENT
20 #else
21 #define ZRTOS_MALLOC__BYTE_ALIGNMENT ZRTOS_TYPES__BYTE_ALIGNMENT
22 #endif
23 
24 typedef struct _zrtos_malloc_t{
26 }__attribute__((packed))zrtos_malloc_t;
27 
29 #ifndef ZRTOS_MALLOC__CFG_DISABLE_FREE
30  size_t length;
31 #endif
33 
34 typedef struct _zrtos_malloc_internal_t{
36  size_t length;
37 }__attribute__((aligned(ZRTOS_MALLOC__BYTE_ALIGNMENT))) zrtos_malloc_internal_t;
38 
39 #define ZRTOS_MALLOC__GET_REQUIRED_SIZE(type,count) \
40  ( sizeof(zrtos_malloc_internal_t) \
41  + ( \
42  ( \
43  sizeof(zrtos_malloc_heap_chunk_t) \
44  + zrtos_types__ceil_size_to_alignment(sizeof(type)) \
45  ) \
46  * (count) \
47  ) \
48  )
49 
50 #define ZRTOS_MALLOC__GLOBAL_HEAP_INIT(name) \
51  zrtos_malloc__init( \
52  name \
53  ,sizeof(name) / sizeof(name[0]) \
54  ); \
55  \
56  ZRTOS_DEBUG__CODE({ \
57  zrtos_debug__memset( \
58  zrtos_types__ptr_add(name,sizeof(zrtos_malloc_internal_t)) \
59  ,0xFF \
60  ,(sizeof(name) / sizeof(name[0])) \
61  -sizeof(zrtos_malloc_internal_t) \
62  ); \
63  });
64 
65 #define ZRTOS_MALLOC__GLOBAL_HEAP(name,len) \
66  zrtos_malloc_t name[ \
67  (len) \
68  ] __attribute__((aligned(ZRTOS_MALLOC__BYTE_ALIGNMENT))); \
69  \
70  ZRTOS_ASSERT__STATIC(len >= sizeof(zrtos_malloc_internal_t)); \
71  \
72  void *kmalloc(size_t length){ \
73  return zrtos_malloc__malloc( \
74  name \
75  ,length \
76  ); \
77  } \
78  \
79  void kfree(void *ptr){ \
80  zrtos_malloc__free(ptr); \
81  }
82 
83 #define ZRTOS_MALLOC__INIT(name,len) \
84  zrtos_malloc_t name[ \
85  (len) \
86  ] __attribute__((aligned(ZRTOS_MALLOC__BYTE_ALIGNMENT))); \
87  \
88  ZRTOS_ASSERT__STATIC(len >= sizeof(zrtos_malloc_internal_t)); \
89  \
90  zrtos_malloc__init( \
91  name \
92  ,sizeof(name) / sizeof(name[0]) \
93  )
94 
95 bool zrtos_malloc__init(zrtos_malloc_t *thiz,size_t length){
97  bool ret = false;
98  if(length >= sizeof(zrtos_malloc_internal_t)){
100  thiz_->length = length - sizeof(zrtos_malloc_internal_t);
101 
103  zrtos_debug__memset(thiz_->ptr,0xFF,length);
104  });
105 
106  ret = true;
107  }
108  return ret;
109 }
110 
111 #ifndef ZRTOS_MALLOC__CFG_DISABLE_FREE
113  zrtos_malloc_t *thiz
114  ,size_t length
115 ){
119  length <<= 1;
120 
121  while(chunk != last){
122  if((chunk->length & 1) == 0
123  && (chunk->length >> 1) == length){
124  return chunk;
125  }
127  chunk
128  ,sizeof(zrtos_malloc_heap_chunk_t) + (chunk->length>>1)
129  );
130  }
131 
132  return 0;
133 }
134 #endif
135 
136 /*
137 ** defined(ZRTOS_MALLOC__CFG_DISABLE_FREE)
138 ** ? allocates a new memory block
139 ** : either returns a recently freed memory block with the exact same
140 ** length or allocates a new memory block
141 **/
142 void *zrtos_malloc__malloc(zrtos_malloc_t *thiz,size_t length){
143 #ifndef ZRTOS_MALLOC__CFG_DISABLE_FREE
145  zrtos_malloc_heap_chunk_t *chunk = 0;
146  size_t aligned_length = zrtos_types__ceil_size_to_alignment(length);
147  size_t total_length = sizeof(zrtos_malloc_heap_chunk_t) + aligned_length;
148  bool has_free_space = (thiz_->length
150  thiz_->ptr
151  ,(thiz_ + 1)
152  ))
153  >= total_length
154  ;
155 
156  if(aligned_length > (SIZE_MAX>>1)){
157  //out of bounds
158  goto L_OUT;
159  }else if((chunk = zrtos_malloc__get_free_chunk(thiz,aligned_length))){
160  chunk->length |= 1;
161  }else if(has_free_space){
162  chunk = (zrtos_malloc_heap_chunk_t*)thiz_->ptr;
163  chunk->length = (aligned_length << 1) | 1;
164  thiz_->ptr += total_length;
165  }else{
166  goto L_OUT;
167  }
168 
169  chunk++;
170 
172  static uint8_t pattern = 0x20;
173  zrtos_debug__memset(chunk,pattern++,aligned_length);
174  });
175 
176 L_OUT:
177  return chunk;
178 #else
180  void *ret = 0;
181  size_t aligned_length = zrtos_types__ceil_size_to_alignment(length);
182  bool has_free_space = (thiz_->length
184  thiz_->ptr
185  ,thiz_
186  ))
187  >= aligned_length
188  ;
189 
190  if(has_free_space){
191  ret = thiz_->ptr;
192  thiz_->ptr += aligned_length;
193  }
194 
196  static uint8_t pattern = 0x20;
197  zrtos_debug__memset(ret,pattern++,aligned_length);
198  });
199 
200  return ret;
201 #endif
202 }
203 
204 #ifndef ZRTOS_MALLOC__CFG_DISABLE_FREE
205 size_t zrtos_malloc__get_length(void *ptr){
208  ,ptr
209  );
210  --chunk;
211  return (chunk->length >> 1);
212 }
213 #endif
214 
215 /*
216 ** defined(ZRTOS_MALLOC__CFG_DISABLE_FREE)
217 ** ? noop
218 ** : the memory adressed by the pointer will only be marked as unused
219 **/
220 void zrtos_malloc__free(void *ptr){
221 #ifndef ZRTOS_MALLOC__CFG_DISABLE_FREE
224  ,ptr
225  );
226  --chunk;
227  chunk->length &= ~((size_t)1);
228 
230  zrtos_debug__memset(ptr,0xFF,(chunk->length >> 1));
231  });
232 #endif
233 }
234 
235 
236 #ifdef __cplusplus
237 }
238 #endif
239 #endif
#define ZRTOS_CAST(type, value)
Definition: cast.h:18
#define ZRTOS_DEBUG__CODE(code)
Definition: debug.h:47
bool zrtos_malloc__init(zrtos_malloc_t *thiz, size_t length)
Definition: malloc.h:95
#define ZRTOS_MALLOC__BYTE_ALIGNMENT
Definition: malloc.h:21
size_t zrtos_malloc__get_length(void *ptr)
Definition: malloc.h:205
void * zrtos_malloc__malloc(zrtos_malloc_t *thiz, size_t length)
Definition: malloc.h:142
void zrtos_malloc__free(void *ptr)
Definition: malloc.h:220
struct _zrtos_malloc_heap_chunk_t zrtos_malloc_heap_chunk_t
uint16_t size_t
Definition: types.h:22
void * zrtos_types__ptr_add(void *ptr, size_t byte_len)
Definition: types.h:35
size_t zrtos_types__ptr_get_byte_distance(void *bigger, void *smaller)
Definition: types.h:43
static zrtos_malloc_heap_chunk_t * zrtos_malloc__get_free_chunk(zrtos_malloc_t *thiz, size_t length)
Definition: malloc.h:112
struct _zrtos_malloc_t zrtos_malloc_t
size_t zrtos_types__ceil_size_to_alignment(size_t len)
Definition: types.h:59
struct _zrtos_malloc_internal_t zrtos_malloc_internal_t
uint8_t value
Definition: malloc.h:25
static uint8_t
Definition: mcp2515.h:159