1 /*
2 * Copyright (c) 2019 Intel Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6 #include <zephyr/sys/sys_heap.h>
7 #include <zephyr/sys/util.h>
8 #include <zephyr/kernel.h>
9 #include "heap.h"
10
11 /*
12 * Print heap info for debugging / analysis purpose
13 */
heap_print_info(struct z_heap * h,bool dump_chunks)14 static void heap_print_info(struct z_heap *h, bool dump_chunks)
15 {
16 int i, nb_buckets = bucket_idx(h, h->end_chunk) + 1;
17 size_t free_bytes, allocated_bytes, total, overhead;
18
19 printk("Heap at %p contains %d units in %d buckets\n\n",
20 chunk_buf(h), h->end_chunk, nb_buckets);
21
22 printk(" bucket# min units total largest largest\n"
23 " threshold chunks (units) (bytes)\n"
24 " -----------------------------------------------------------\n");
25 for (i = 0; i < nb_buckets; i++) {
26 chunkid_t first = h->buckets[i].next;
27 chunksz_t largest = 0;
28 int count = 0;
29
30 if (first) {
31 chunkid_t curr = first;
32
33 do {
34 count++;
35 largest = MAX(largest, chunk_size(h, curr));
36 curr = next_free_chunk(h, curr);
37 } while (curr != first);
38 }
39 if (count) {
40 printk("%9d %12d %12d %12d %12zd\n",
41 i, (1 << i) - 1 + min_chunk_size(h), count,
42 largest, chunksz_to_bytes(h, largest));
43 }
44 }
45
46 if (dump_chunks) {
47 printk("\nChunk dump:\n");
48 for (chunkid_t c = 0; ; c = right_chunk(h, c)) {
49 printk("chunk %4d: [%c] size=%-4d left=%-4d right=%d\n",
50 c,
51 chunk_used(h, c) ? '*'
52 : solo_free_header(h, c) ? '.'
53 : '-',
54 chunk_size(h, c),
55 left_chunk(h, c),
56 right_chunk(h, c));
57 if (c == h->end_chunk) {
58 break;
59 }
60 }
61 }
62
63 get_alloc_info(h, &allocated_bytes, &free_bytes);
64 /* The end marker chunk has a header. It is part of the overhead. */
65 total = h->end_chunk * CHUNK_UNIT + chunk_header_bytes(h);
66 overhead = total - free_bytes - allocated_bytes;
67 printk("\n%zd free bytes, %zd allocated bytes, overhead = %zd bytes (%zd.%zd%%)\n",
68 free_bytes, allocated_bytes, overhead,
69 (1000 * overhead + total / 2) / total / 10,
70 (1000 * overhead + total / 2) / total % 10);
71 }
72
sys_heap_print_info(struct sys_heap * heap,bool dump_chunks)73 void sys_heap_print_info(struct sys_heap *heap, bool dump_chunks)
74 {
75 heap_print_info(heap->heap, dump_chunks);
76 }
77