| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /* | ||
| 2 | * Copyright (c) 2022-2023, The Puppy RTOS Authors | ||
| 3 | * | ||
| 4 | * SPDX-License-Identifier: Apache-2.0 | ||
| 5 | */ | ||
| 6 | |||
| 7 | #include <puppy.h> | ||
| 8 | #include <string.h> | ||
| 9 | |||
| 10 | #define KLOG_TAG "mem" | ||
| 11 | #define KLOG_LVL KLOG_WARNING | ||
| 12 | #include <puppy/klog.h> | ||
| 13 | |||
| 14 | #ifdef ENABLE_TLSF | ||
| 15 | #include "tlsf.h" | ||
| 16 | #endif | ||
| 17 | |||
| 18 | static tlsf_t tlsf_ptr = 0; | ||
| 19 | static struct _sem_obj heap_sem; | ||
| 20 | |||
| 21 | 1 | void p_system_heap_init(void *begin_addr, size_t size) | |
| 22 | { | ||
| 23 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | if (!tlsf_ptr) |
| 24 | { | ||
| 25 | 1 | tlsf_ptr = (tlsf_t)tlsf_create_with_pool(begin_addr, size); | |
| 26 | 1 | p_sem_init(&heap_sem, "heap_sem", 1, 1); | |
| 27 | } | ||
| 28 | else | ||
| 29 | { | ||
| 30 | ✗ | KLOG_ASSERT(0); | |
| 31 | } | ||
| 32 | 1 | } | |
| 33 | |||
| 34 | ✗ | void *p_malloc_align(size_t size, size_t align) | |
| 35 | { | ||
| 36 | ✗ | void *ptr = NULL; | |
| 37 | |||
| 38 | ✗ | if (tlsf_ptr) | |
| 39 | { | ||
| 40 | ✗ | p_sem_wait(&heap_sem); | |
| 41 | ✗ | ptr = tlsf_memalign(tlsf_ptr, align, size); | |
| 42 | ✗ | p_sem_post(&heap_sem); | |
| 43 | } | ||
| 44 | ✗ | return ptr; | |
| 45 | } | ||
| 46 | |||
| 47 | ✗ | void p_free_align(void *ptr) | |
| 48 | { | ||
| 49 | ✗ | p_free(ptr); | |
| 50 | ✗ | } | |
| 51 | |||
| 52 | 63 | void *p_malloc(size_t nbytes) | |
| 53 | { | ||
| 54 | 63 | void *ptr = NULL; | |
| 55 | |||
| 56 |
1/2✓ Branch 0 taken 63 times.
✗ Branch 1 not taken.
|
63 | if (tlsf_ptr) |
| 57 | { | ||
| 58 | 63 | p_sem_wait(&heap_sem); | |
| 59 | |||
| 60 | 63 | ptr = tlsf_malloc(tlsf_ptr, nbytes); | |
| 61 | |||
| 62 | 63 | p_sem_post(&heap_sem); | |
| 63 | } | ||
| 64 | 63 | return ptr; | |
| 65 | } | ||
| 66 | |||
| 67 | 48 | void p_free(void *ptr) | |
| 68 | { | ||
| 69 |
1/2✓ Branch 0 taken 48 times.
✗ Branch 1 not taken.
|
48 | if (tlsf_ptr) |
| 70 | { | ||
| 71 | 48 | p_sem_wait(&heap_sem); | |
| 72 | |||
| 73 | 48 | tlsf_free(tlsf_ptr, ptr); | |
| 74 | |||
| 75 | 48 | p_sem_post(&heap_sem); | |
| 76 | } | ||
| 77 | 48 | } | |
| 78 | |||
| 79 | ✗ | void *p_realloc(void *ptr, size_t nbytes) | |
| 80 | { | ||
| 81 | ✗ | if (tlsf_ptr) | |
| 82 | { | ||
| 83 | ✗ | p_sem_wait(&heap_sem); | |
| 84 | |||
| 85 | ✗ | ptr = tlsf_realloc(tlsf_ptr, ptr, nbytes); | |
| 86 | |||
| 87 | ✗ | p_sem_post(&heap_sem); | |
| 88 | } | ||
| 89 | ✗ | return ptr; | |
| 90 | } | ||
| 91 | |||
| 92 | ✗ | void *p_calloc(size_t count, size_t size) | |
| 93 | { | ||
| 94 | ✗ | void *ptr = NULL; | |
| 95 | size_t total_size; | ||
| 96 | |||
| 97 | ✗ | total_size = count * size; | |
| 98 | ✗ | ptr = p_malloc(total_size); | |
| 99 | ✗ | if (ptr != NULL) | |
| 100 | { | ||
| 101 | /* clean memory */ | ||
| 102 | ✗ | memset(ptr, 0, total_size); | |
| 103 | } | ||
| 104 | |||
| 105 | ✗ | return ptr; | |
| 106 | } | ||
| 107 | static size_t used_mem = 0; | ||
| 108 | static size_t total_mem = 0; | ||
| 109 | |||
| 110 | ✗ | static void mem_info(void *ptr, size_t size, int used, void *user) | |
| 111 | { | ||
| 112 | ✗ | if (used) | |
| 113 | { | ||
| 114 | ✗ | used_mem += size; | |
| 115 | } | ||
| 116 | ✗ | total_mem += size; | |
| 117 | ✗ | } | |
| 118 | |||
| 119 | ✗ | void list_mem(void) | |
| 120 | { | ||
| 121 | ✗ | used_mem = 0; | |
| 122 | ✗ | total_mem = 0; | |
| 123 | |||
| 124 | ✗ | tlsf_walk_pool(tlsf_get_pool(tlsf_ptr), mem_info, 0); | |
| 125 | ✗ | printk("total memory: %d\n", total_mem); | |
| 126 | ✗ | printk("used memory : %d\n", used_mem); | |
| 127 | ✗ | } | |
| 128 | #ifdef ENABLE_NR_SHELL | ||
| 129 | ✗ | void shell_free_cmd(char argc, char *argv) | |
| 130 | { | ||
| 131 | ✗ | list_mem(); | |
| 132 | ✗ | } | |
| 133 | #include <nr_micro_shell.h> | ||
| 134 | NR_SHELL_CMD_EXPORT(free, shell_free_cmd); | ||
| 135 | #endif | ||
| 136 |