Line data Source code
1 : /*
2 : * libpino - memory.c
3 : *
4 : * Copyright (c) 2025 Go Kudo
5 : *
6 : * This library is licensed under the BSD 3-Clause License.
7 : * For license details, please refer to the LICENSE file.
8 : *
9 : * SPDX-FileCopyrightText: Go Kudo <zeriyoshi@gmail.com>
10 : * SPDX-License-Identifier: BSD-3-Clause
11 : */
12 :
13 : #include <pino.h>
14 : #include <pino/handler.h>
15 :
16 : #include <pino_internal.h>
17 :
18 248 : static inline bool glow_mm(mm_t *mm, size_t step)
19 : {
20 : void **ptrs;
21 : size_t i;
22 :
23 248 : ptrs = (void **)prealloc(mm->ptrs, (mm->capacity + step) * sizeof(void *));
24 : /* LCOV_EXCL_START */
25 : if (!ptrs) {
26 : PINO_SUPRTF("prealloc failed");
27 : return false;
28 : }
29 : /* LCOV_EXCL_STOP */
30 :
31 2232 : for (i = mm->capacity; i < mm->capacity + step; i++) {
32 1984 : ptrs[i] = NULL;
33 : }
34 :
35 248 : mm->ptrs = ptrs;
36 248 : mm->capacity += step;
37 :
38 : PINO_SUPRTF("glowed capacity: %zu, usage: %zu", mm->capacity, mm->usage);
39 :
40 248 : return true;
41 : }
42 :
43 1026 : extern bool pino_memory_manager_obj_init(mm_t *mm, size_t initialize_size)
44 : {
45 : /* LCOV_EXCL_START */
46 : if (initialize_size == 0) {
47 : return false;
48 : }
49 : /* LCOV_EXCL_STOP */
50 :
51 1026 : mm->usage = 0;
52 1026 : mm->capacity = 0;
53 1026 : mm->ptrs = (void **)pcalloc(initialize_size, sizeof(void *));
54 : /* LCOV_EXCL_START */
55 : if (!mm->ptrs) {
56 : return false;
57 : }
58 : /* LCOV_EXCL_STOP */
59 :
60 1026 : mm->usage = 0;
61 1026 : mm->capacity = initialize_size;
62 :
63 : PINO_SUPRTF("usage: %zu, capacity: %zu", mm->usage, mm->capacity);
64 :
65 1026 : return mm;
66 : }
67 :
68 1026 : extern void pino_memory_manager_obj_free(mm_t *mm)
69 : {
70 : size_t i;
71 :
72 1026 : if (!mm) {
73 : return; /* LCOV_EXCL_LINE */
74 : }
75 :
76 19426 : for (i = 0; i < mm->capacity; i++) {
77 18400 : if (mm->ptrs[i]) {
78 1006 : pfree(mm->ptrs[i]);
79 1006 : mm->ptrs[i] = NULL;
80 1006 : --mm->usage;
81 :
82 : PINO_SUPRTF("freeing: %zu, usage: %zu, capacity: %zu", i, mm->usage, mm->capacity);
83 : }
84 : }
85 :
86 1026 : pfree(mm->ptrs);
87 1026 : mm->ptrs = NULL;
88 1026 : mm->usage = 0;
89 1026 : mm->capacity = 0;
90 : }
91 :
92 4024 : extern void *pino_memory_manager_malloc(/* handler_entry_t */ void *entry, size_t size)
93 : {
94 : size_t i;
95 :
96 4024 : if (!entry || size == 0) {
97 : PINO_SUPRTF("entry or size is NULL");
98 1006 : return NULL;
99 : }
100 :
101 3018 : if (((handler_entry_t *)entry)->mm.usage >= ((handler_entry_t *)entry)->mm.capacity) {
102 : /* LCOV_EXCL_START */
103 : if (!glow_mm(&((handler_entry_t *)entry)->mm, HANDLER_STEP)) {
104 : PINO_SUPRTF("glow_mm failed");
105 : return NULL;
106 : }
107 : /* LCOV_EXCL_STOP */
108 : }
109 :
110 3002042 : for (i = 0; i < ((handler_entry_t *)entry)->mm.capacity; i++) {
111 3002042 : if (!((handler_entry_t *)entry)->mm.ptrs[i]) {
112 3018 : ((handler_entry_t *)entry)->mm.ptrs[i] = pmalloc(size);
113 : /* LCOV_EXCL_START */
114 : if (!((handler_entry_t *)entry)->mm.ptrs[i]) {
115 : PINO_SUPRTF("pmalloc failed");
116 : return NULL;
117 : }
118 : /* LCOV_EXCL_STOP */
119 :
120 3018 : ++((handler_entry_t *)entry)->mm.usage;
121 :
122 : PINO_SUPRTF("magic: %.4s, using: %zu, usage: %zu, capacity: %zu",
123 : ((handler_entry_t *)entry)->magic,
124 : i,
125 : ((handler_entry_t *)entry)->mm.usage,
126 : ((handler_entry_t *)entry)->mm.capacity
127 : );
128 :
129 3018 : return ((handler_entry_t *)entry)->mm.ptrs[i];
130 : }
131 : }
132 : /* LCOV_EXCL_START */
133 : PINO_SUPUNREACH();
134 : return NULL;
135 : /* LCOV_EXCL_STOP */
136 : }
137 :
138 2012 : extern void *pino_memory_manager_calloc(/* handler_entry_t */ void *entry, size_t count, size_t size)
139 : {
140 : void *ptr;
141 :
142 2012 : ptr = pino_memory_manager_malloc(entry, count * size);
143 : /* LCOV_EXCL_START */
144 : if (!ptr) {
145 : PINO_SUPRTF("pino_memory_manager_malloc failed");
146 : return NULL;
147 : }
148 : /* LCOV_EXCL_STOP */
149 :
150 2012 : memset(ptr, 0, count * size);
151 :
152 2012 : return ptr;
153 : }
154 :
155 3018 : extern void pino_memory_manager_free(/* handler_entry_t */ void *entry, void *ptr)
156 : {
157 : size_t i;
158 :
159 3018 : if (!entry || !ptr) {
160 : PINO_SUPRTF("mm or ptr is NULL");
161 1006 : return;
162 : }
163 :
164 2002032 : for (i = 0; i < ((handler_entry_t *)entry)->mm.capacity; i++) {
165 2002032 : if (((handler_entry_t *)entry)->mm.ptrs[i] && ((handler_entry_t *)entry)->mm.ptrs[i] == ptr) {
166 2012 : pfree(ptr);
167 2012 : ((handler_entry_t *)entry)->mm.ptrs[i] = NULL;
168 2012 : ptr = NULL;
169 2012 : --((handler_entry_t *)entry)->mm.usage;
170 :
171 : PINO_SUPRTF("freeing: %zu, usage: %zu, capacity: %zu",
172 : i, ((handler_entry_t *)entry)->mm.usage, ((handler_entry_t *)entry)->mm.capacity);
173 :
174 2012 : return;
175 : }
176 : }
177 :
178 : /* LCOV_EXCL_START */
179 : PINO_SUPUNREACH();
180 : return;
181 : /* LCOV_EXCL_STOP */
182 : }
|