LCOV - code coverage report
Current view: top level - AP_MultiHeap - MultiHeap_malloc.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 30 39 76.9 %
Date: 2026-09-09 11:02:08 Functions: 4 4 100.0 %

          Line data    Source code
       1             : #include "AP_MultiHeap.h"
       2             : #include <AP_HAL/AP_HAL_Boards.h>
       3             : 
       4             : #if CONFIG_HAL_BOARD != HAL_BOARD_CHIBIOS
       5             : 
       6             : /*
       7             :   on systems other than chibios we map the allocation to the system
       8             :   malloc/free functions
       9             :  */
      10             : 
      11             : #include <AP_InternalError/AP_InternalError.h>
      12             : #include <stdlib.h>
      13             : 
      14             : /*
      15             :   low level allocator interface using system malloc
      16             :  */
      17             : /*
      18             :   default functions for heap management for lua scripting for systems
      19             :   that don't have the ability to create separable heaps
      20             :  */
      21             : 
      22             : struct heap_allocation_header {
      23             :     struct heap *hp;
      24             :     uint32_t allocation_size; // size of allocated block, not including this header
      25             : };
      26             : 
      27             : #define HEAP_MAGIC 0x5681ef9f
      28             : 
      29             : struct heap {
      30             :     uint32_t magic;
      31             :     uint32_t max_heap_size;
      32             :     uint32_t current_heap_usage;
      33             : };
      34             : 
      35          99 : void *MultiHeap::heap_create(uint32_t size)
      36             : {
      37          99 :     struct heap *new_heap = (struct heap*)malloc(sizeof(struct heap));
      38          99 :     if (new_heap != nullptr) {
      39          99 :         new_heap->magic = HEAP_MAGIC;
      40          99 :         new_heap->max_heap_size = size;
      41             :     }
      42          99 :     return (void *)new_heap;
      43             : }
      44             : 
      45          58 : void MultiHeap::heap_destroy(void *heap_ptr)
      46             : {
      47          58 :     struct heap *heapp = (struct heap*)heap_ptr;
      48          58 :     if (heapp->magic != HEAP_MAGIC) {
      49           0 :         INTERNAL_ERROR(AP_InternalError::error_t::flow_of_control);
      50           0 :         return;
      51             :     }
      52             : 
      53             : #if CONFIG_HAL_BOARD == HAL_BOARD_SITL
      54          57 :     if (heapp->current_heap_usage != 0) {
      55             :         // lua should guarantee that there is no memory still
      56             :         // allocated when we destroy the heap. Throw an error in SITL
      57             :         // if this proves not to be true
      58           0 :         INTERNAL_ERROR(AP_InternalError::error_t::flow_of_control);
      59             :     }
      60             : #endif
      61             : 
      62             :     // free the heap structure
      63          58 :     free(heapp);
      64             : }
      65             : 
      66             : /*
      67             :   allocate memory on a specific heap
      68             :  */
      69     1924481 : void *MultiHeap::heap_allocate(void *heap_ptr, uint32_t size)
      70             : {
      71     1924481 :     if (heap_ptr == nullptr || size == 0) {
      72           0 :         return nullptr;
      73             :     }
      74     1924481 :     struct heap *heapp = (struct heap*)heap_ptr;
      75     1924481 :     if (heapp->magic != HEAP_MAGIC) {
      76           0 :         INTERNAL_ERROR(AP_InternalError::error_t::flow_of_control);
      77           0 :         return nullptr;
      78             :     }
      79             : 
      80     1924481 :     if (heapp->current_heap_usage + size > heapp->max_heap_size) {
      81             :         // fail the allocation as we don't have the memory. Note that
      82             :         // we don't simulate the fragmentation that we would get with
      83             :         // HAL_ChibiOS
      84           3 :         return nullptr;
      85             :     }
      86             : 
      87     1924478 :     auto *header = (heap_allocation_header *)malloc(size + sizeof(heap_allocation_header));
      88     1924478 :     if (header == nullptr) {
      89             :         // can't allocate the new memory
      90           0 :         return nullptr;
      91             :     }
      92     1924478 :     header->hp = heapp;
      93     1924478 :     header->allocation_size = size;
      94             : 
      95     1924478 :     heapp->current_heap_usage += size;
      96             : 
      97     1924478 :     return header + 1;
      98             : }
      99             : 
     100             : /*
     101             :   free memory from a previous heap_allocate call
     102             :  */
     103     1900638 : void MultiHeap::heap_free(void *ptr)
     104             : {
     105             :     // extract header
     106     1900638 :     auto *header = ((struct heap_allocation_header *)ptr)-1;
     107     1900638 :     auto *heapp = header->hp;
     108     1900638 :     if (heapp->magic != HEAP_MAGIC) {
     109           0 :         INTERNAL_ERROR(AP_InternalError::error_t::flow_of_control);
     110           0 :         return;
     111             :     }
     112     1900638 :     const uint32_t size = header->allocation_size;
     113     1900638 :     heapp->current_heap_usage -= size;
     114             : 
     115             :     // free the memory
     116     1900638 :     free(header);
     117             : }
     118             : 
     119             : #endif // CONFIG_HAL_BOARD != HAL_BOARD_CHIBIOS

Generated by: LCOV version 1.14