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 |