agileRTOS (zrtos)  Version 0.8.0 (ghostbuster)
vheap.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_VHEAP_H
8 #define ZRTOS_VHEAP_H
9 #ifdef __cplusplus
10 extern "C" {
11 #endif
12 
13 
14 #include <zrtos/debug.h>
15 #include <zrtos/mem.h>
16 #include <zrtos/vheap_chunk.h>
17 
18 
19 #define ZRTOS_VHEAP__INIT(name,heap_size) \
20  static struct{ \
21  uint8_t heap[heap_size]; \
22  }__attribute__((aligned(ZRTOS_ARCH__BYTE_ALIGNMENT)))name;
23 
24 
25 #define ZRTOS_VHEAP__GET(name) \
26  ((zrtos_vheap_t*)&(name.heap[0]))
27 
28 typedef struct _zrtos_vheap_t{
29  void *ptr;
30  size_t length;//index length
31  size_t heap_size;
32  size_t total_size;
34 
36  zrtos_vheap_t *thiz
37  ,void *heap
38  ,size_t heap_size
39 ){
41  zrtos_debug__memset(heap,0xEE,heap_size);
42  );
43 
44  thiz->ptr = heap;
45  thiz->length = 0;
46  thiz->heap_size = 0;
47  thiz->total_size = heap_size;
48 
49  return true;
50 }
51 
53  return zrtos_types__ptr_add(thiz->ptr,thiz->total_size);
54 }
55 
58 }
59 
60 size_t _zrtos_vheap__get_free_space_ex(zrtos_vheap_t *thiz,void *stack_ptr){
61  return
62  thiz->ptr < stack_ptr
65  stack_ptr
67  )
68  ,thiz->ptr
69  )
70  : 0
71  ;
72 }
73 
76  thiz
78  );
79 }
80 
82  zrtos_vheap_t *thiz
84 ){
85  zrtos_vheap_chunk_t *node = thiz->ptr;
86  for(size_t l = thiz->length;l--;node++){
87  if(node->uid.uid == uid.uid){
88  return node;
89  }
90  }
91  return 0;
92 }
93 
95  zrtos_vheap_t *thiz
97 ){
98  zrtos_vheap_chunk_t *node = thiz->ptr;
99  for(size_t l = thiz->length;l--;node++){
100  if(node->type.type == type.type){
101  return node;
102  }
103  }
104  return 0;
105 }
106 
108  zrtos_vheap_t *thiz
109  ,zrtos_vheap_type_t type
110 ){
112  zrtos_vheap_chunk_type__init(&tmp,type);
114  thiz
115  ,tmp
116  );
117 }
118 
120  zrtos_vheap_t *thiz
121 ){
122  static zrtos_vheap_chunk_uid_t uid = {
123  .uid = 1
124  };
126  .uid = uid.uid++
127  };
128 
129  while(ret.uid == 0 || zrtos_vheap__get_by_id(
130  thiz
131  ,ret
132  )){
133  ret.uid++;
134  }
135 
136  return ret;
137 }
138 
140  zrtos_vheap_t *thiz
141 ){
142  return thiz->length / sizeof(zrtos_vheap_chunk_t);
143 }
144 
146  zrtos_vheap_t *thiz
148  ,zrtos_vheap_type_t type
149  ,size_t length
150 ){
151  zrtos_vheap_chunk_t *chunk = 0;
152  size_t free_space = _zrtos_vheap__get_free_space(thiz);
153  size_t length_total = sizeof(zrtos_vheap_chunk_t) + length;
154  if(free_space >= length_total){
155  zrtos_vheap_chunk_t *node;
156  size_t index_length = (sizeof(zrtos_vheap_chunk_t) * thiz->length);
157  size_t heap_length = thiz->heap_size - index_length;
158 
159  uint8_t *src = thiz->ptr + thiz->heap_size;
160  uint8_t *dest = src + sizeof(zrtos_vheap_chunk_t);
161 
162  thiz->heap_size += length_total;
163 
165  dest - heap_length
166  ,src - heap_length
167  ,heap_length
168  );
169 
170  chunk = &((zrtos_vheap_chunk_t*)thiz->ptr)[thiz->length++];
171  chunk->first[0] = 0x55;
172  chunk->first[1] = 0x55;
173 
174  chunk->ptr = thiz->ptr + thiz->heap_size - length;
175  chunk->length = length;
176  chunk->uid = zrtos_vheap__get_next_uid(thiz);
177  chunk->parent = parent;
178  chunk->type.type = type;
179  chunk->last[0] = 0x66;
180  chunk->last[1] = 0x66;
181 
182  //update index
183  node = &((zrtos_vheap_chunk_t*)thiz->ptr)[0];
184  for(;node < chunk;node++){
185  node->ptr += sizeof(zrtos_vheap_chunk_t);
186  }
187 
189  static uint8_t pattern = 0xE0;
190  zrtos_debug__memset(chunk->ptr,(int)(pattern++),chunk->length);
191  );
192  }
193  return chunk;
194 }
195 
197  zrtos_vheap_t *thiz
199  ,zrtos_vheap_type_t type
200  ,size_t length
201 ){
203  thiz
204  ,parent
205  ,type
206  ,length
207  );
208  if(chunk){
209  return chunk->uid;
210  }
212 }
213 
215  zrtos_vheap_t *thiz
216  ,zrtos_vheap_chunk_t *chunk
217  ,size_t sizeof_mem_chunk
218 ){
219  size_t length = chunk->length;
220  zrtos_vheap_chunk_t *node = &((zrtos_vheap_chunk_t*)thiz->ptr)[0];
221  zrtos_vheap_chunk_t *sentinel = &((zrtos_vheap_chunk_t*)thiz->ptr)[thiz->length];
222  for(;node < sentinel;node++){
223  node->ptr -= sizeof_mem_chunk/*sizeof(zrtos_vheap_chunk_t)*/ + (node > chunk ? length : 0);
224  }
225 }
226 
228  zrtos_vheap_chunk_t *node = &((zrtos_vheap_chunk_t*)thiz->ptr)[0];
229  zrtos_vheap_chunk_t *sentinel = &((zrtos_vheap_chunk_t*)thiz->ptr)[thiz->length];
230  zrtos_vheap_chunk_t *ret = 0;
231  for(;node < sentinel;node++){
232  if(zrtos_vheap_chunk_uid__cmp(&chunk->uid,&node->parent)){
233  ret = node;
234  break;
235  }
236  }
237  return ret;
238 }
239 
241  /// @todo cancel running task...
242  uint8_t *dest = (uint8_t*)chunk;
243  uint8_t *src = dest + sizeof(zrtos_vheap_chunk_t);
244  zrtos_vheap_chunk_t *sentinel;
245  size_t length = chunk->length;
246  size_t length_total = sizeof(zrtos_vheap_chunk_t) + length;
247  int lp = 1;
248  void *chunk_ptr = chunk->ptr;
249 
250  //update index
252 
253  //1st loop delete index, 2nd loop delete element
254  sentinel = chunk_ptr;//zrtos_types__ptr_add(chunk->ptr,sizeof(zrtos_vheap_chunk_t));
255  do{
256  while(src < ((uint8_t*)sentinel)){
257  *dest++ = *src++;
258  }
259  src += length;
260  sentinel = zrtos_types__ptr_add(thiz->ptr,thiz->heap_size);
261  }while(lp--);
262 
263  thiz->length--;
264  thiz->heap_size -= length_total;
265 
267  zrtos_debug__memset(
268  zrtos_types__ptr_add(thiz->ptr,thiz->heap_size)
269  ,0xEE
270  ,length_total
271  );
272  );
273 }
274 
276  while(true){
277  zrtos_vheap_chunk_t *node = zrtos_vheap__get_child(thiz,chunk);
278  if(node){
279  zrtos_vheap_chunk_t *last = node;
280  while((node = zrtos_vheap__get_child(thiz,node))){
281  last = node;
282  }
283  _zrtos_vheap__free_helper(thiz,last);
284  }else{
285  break;
286  }
287  }
288  _zrtos_vheap__free_helper(thiz,chunk);
289 }
290 
293  thiz
294  ,uid
295  );
296  _zrtos_vheap__free(thiz,chunk);
297 }
298 
300  void *heap
301  ,size_t heap_length
302  ,size_t used_length
303  ,size_t chunk_offset
304  ,size_t chunk_length
305 ){
306  uint8_t *buffer = heap;
307  void *ret = buffer + heap_length - chunk_length;
309  buffer + chunk_offset
310  ,chunk_length
311  ,used_length - chunk_offset
312  );
314  ret//buffer + heap_length - chunk_length
315  ,buffer + used_length - chunk_length
316  ,chunk_length
317  );
318  return ret;
319 }
320 
322  zrtos_vheap_t *thiz
323  ,zrtos_vheap_chunk_t *chunk
324 ){
325  size_t index_length = (sizeof(zrtos_vheap_chunk_t) * thiz->length);
326  void *ptr_index = zrtos_types__ptr_add(thiz->ptr,index_length);
327  void *chunk_ptr = chunk->ptr;
328  void *ret;
329 
330  //update index
331  _zrtos_vheap__update_index_ptr(thiz,chunk,0);
332 
334  ptr_index
335  ,thiz->total_size - index_length
336  ,thiz->heap_size - index_length
337  ,zrtos_types__ptr_get_byte_distance(chunk_ptr,ptr_index)
338  ,chunk->length
339  );
340 
341  thiz->heap_size -= chunk->length;
342  //chunk->ptr = 0;
343  chunk->length = 0;
345 
346  return ret;
347 }
348 
350  zrtos_vheap_t *thiz
351  ,zrtos_vheap_chunk_t *chunk
352  ,size_t length
353 ){
354  uint8_t *heap_end_ptr = zrtos_types__ptr_add(thiz->ptr,thiz->heap_size);
356  heap_end_ptr
357  ,zrtos_types__ptr_add(thiz->ptr,thiz->total_size - length)
358  ,length
359  );
360 
361  thiz->heap_size += length;
362 
363  chunk->ptr = heap_end_ptr;
364  chunk->length = length;
366  chunk
367  ,(
370  : chunk->type.type
371  )
372  );
373 
374  //move chunk to end of index
375  size_t index_length = (sizeof(zrtos_vheap_chunk_t) * thiz->length);
377  chunk
378  ,sizeof(zrtos_vheap_chunk_t)
381  thiz->ptr
382  ,index_length
383  )
384  ,chunk
385  )
386  );
387 
389  zrtos_debug__memset(
390  zrtos_types__ptr_add(heap_end_ptr,length)
391  ,0xEE
392  ,thiz->total_size - thiz->heap_size
393  );
394  );
395 }
396 
397 #define ZRTOS_VHEAP__EACH_EX_BEGIN(thiz,start_offset,l,type,value) \
398  for(size_t l = start_offset,len__=(thiz)->length;l < len__;l++){ \
399  zrtos_vheap_chunk_t *value = &((zrtos_vheap_chunk_t*)((thiz)->ptr))[l]; \
400  if(zrtos_vheap_chunk__is_type_eq(value,type)){
401 
402 #define ZRTOS_VHEAP__EACH_EX_END \
403  } \
404  }
405 
406 #define ZRTOS_VHEAP__EACH_BEGIN(thiz,type,value) \
407  for(size_t l__ = 0,len__=(thiz)->length;l__ < len__;l__++){ \
408  zrtos_vheap_chunk_t *value = &((zrtos_vheap_chunk_t*)((thiz)->ptr))[l]; \
409  if(zrtos_vheap_chunk__is_type_eq(value,type))
410 
411 #define ZRTOS_VHEAP__EACH_END \
412  } \
413  }
414 
415 #ifdef __cplusplus
416 }
417 #endif
418 #endif
struct _zrtos_vheap_chunk_t zrtos_vheap_chunk_t
void _zrtos_vheap__free(zrtos_vheap_t *thiz, zrtos_vheap_chunk_t *chunk)
Definition: vheap.h:275
#define ZRTOS_DEBUG__CODE(code)
Definition: debug.h:47
void zrtos_mem__left_rotate(void *ptr, size_t length, size_t buffer_length)
Definition: mem.h:50
void * ptr
Definition: vheap.h:29
void zrtos_mem__move_right_overlapping(void *dest, void *src, size_t length)
Definition: mem.h:78
zrtos_vheap_chunk_t * zrtos_vheap__get_by_type(zrtos_vheap_t *thiz, zrtos_vheap_chunk_type_t type)
Definition: vheap.h:94
zrtos_vheap_chunk_t * zrtos_vheap__get_by_id(zrtos_vheap_t *thiz, zrtos_vheap_chunk_uid_t uid)
Definition: vheap.h:81
zrtos_vheap_chunk_t * zrtos_vheap__get_by_type_ex(zrtos_vheap_t *thiz, zrtos_vheap_type_t type)
Definition: vheap.h:107
int zrtos_vheap_chunk_uid__cmp(zrtos_vheap_chunk_uid_t *a, zrtos_vheap_chunk_uid_t *b)
size_t length
Definition: vheap.h:30
static zrtos_vheap_chunk_uid_t zrtos_vheap__get_next_uid(zrtos_vheap_t *thiz)
Definition: vheap.h:119
size_t heap_size
Definition: vheap.h:31
zrtos_vheap_chunk_t * zrtos_vheap__get_child(zrtos_vheap_t *thiz, zrtos_vheap_chunk_t *chunk)
Definition: vheap.h:227
void zrtos_vheap__free_helper(zrtos_vheap_t *thiz, zrtos_vheap_chunk_t *chunk)
Definition: vheap.h:240
#define ZRTOS_TYPES__MIN(a, b)
Definition: types.h:78
zrtos_vheap_chunk_t * _zrtos_vheap__malloc(zrtos_vheap_t *thiz, zrtos_vheap_chunk_uid_t parent, zrtos_vheap_type_t type, size_t length)
Definition: vheap.h:145
static void * _zrtos_vheap__swap_to_heap_end(void *heap, size_t heap_length, size_t used_length, size_t chunk_offset, size_t chunk_length)
Definition: vheap.h:299
void * zrtos_types__ptr_add(void *ptr, size_t byte_len)
Definition: types.h:35
void zrtos_vheap__free(zrtos_vheap_t *thiz, zrtos_vheap_chunk_uid_t uid)
Definition: vheap.h:291
size_t zrtos_vheap__get_chunk_count(zrtos_vheap_t *thiz)
Definition: vheap.h:139
bool zrtos_vheap__init(zrtos_vheap_t *thiz, void *heap, size_t heap_size)
Definition: vheap.h:35
size_t total_size
Definition: vheap.h:32
void * zrtos_vheap__get_last_address(zrtos_vheap_t *thiz)
Definition: vheap.h:52
size_t zrtos_types__ptr_get_byte_distance(void *bigger, void *smaller)
Definition: types.h:43
zrtos_vheap_type_t
Definition: vheap_type.h:14
zrtos_vheap_chunk_uid_t zrtos_vheap_chunk_uid__error(void)
struct _zrtos_vheap_t zrtos_vheap_t
static void _zrtos_vheap__update_index_ptr(zrtos_vheap_t *thiz, zrtos_vheap_chunk_t *chunk, size_t sizeof_mem_chunk)
Definition: vheap.h:214
zrtos_vheap_chunk_uid_t uid
Definition: vheap_chunk.h:23
zrtos_vheap_chunk_uid_t zrtos_vheap__malloc(zrtos_vheap_t *thiz, zrtos_vheap_chunk_uid_t parent, zrtos_vheap_type_t type, size_t length)
Definition: vheap.h:196
zrtos_vheap_chunk_type_t type
Definition: vheap_chunk.h:22
void zrtos_vheap_chunk__set_type(zrtos_vheap_chunk_t *thiz, zrtos_vheap_type_t type)
Definition: vheap_chunk.h:46
size_t _zrtos_vheap__get_free_space(zrtos_vheap_t *thiz)
Definition: vheap.h:74
void * zrtos_vheap__page_in(zrtos_vheap_t *thiz, zrtos_vheap_chunk_t *chunk)
Definition: vheap.h:321
static uint8_t
Definition: mcp2515.h:159
zrtos_vheap_type_t type
bool zrtos_vheap_chunk_type__init(zrtos_vheap_chunk_type_t *thiz, zrtos_vheap_type_t type)
size_t _zrtos_vheap__get_free_space_ex(zrtos_vheap_t *thiz, void *stack_ptr)
Definition: vheap.h:60
#define ZRTOS_ARCH__GET_STACK_PTR()
Definition: atmega2560.h:35
void * zrtos_vheap__get_stack_ptr(zrtos_vheap_t *thiz)
Definition: vheap.h:56
void zrtos_mem__move_left_overlapping(void *dest, void *src, size_t length)
Definition: mem.h:92
void zrtos_vheap__page_out(zrtos_vheap_t *thiz, zrtos_vheap_chunk_t *chunk, size_t length)
Definition: vheap.h:349
zrtos_vheap_chunk_uid_t parent
Definition: vheap_chunk.h:24