XFusion API v1.3.0
载入中...
搜索中...
未找到
xf_alloc.c
浏览该文件的文档.
1
14/* ==================== [Includes] ========================================== */
15
16#include "xf_heap_config.h"
17#include "xf_alloc.h"
18
19/* ==================== [Defines] =========================================== */
20
21/* 字节对齐的掩码 */
22#define BYTE_ALIGNMENT_MASK (XF_HEAP_BYTE_ALIGNMENT - 1)
23
24/* 内存块最小所需的空间大小 */
25#define MINIMUM_BLOCK_SIZE ((unsigned int) (heap_struct_size << 1))
26
27/* ==================== [Typedefs] ========================================== */
28
33
34/* ==================== [Static Prototypes] ================================= */
35
36static void insert_block_into_free_list(block_link_t *block_to_insert);
37
38/* ==================== [Static Variables] ================================== */
39
40/* 计算内存块结构体占用大小,并内存对齐 */
41static const unsigned int heap_struct_size =
42 (sizeof(block_link_t)
43 + ((unsigned int)(XF_HEAP_BYTE_ALIGNMENT - 1))) & ~((unsigned int)BYTE_ALIGNMENT_MASK);
44
45/* 内存块大小的最高位掩码,最高位用于检测内存块是否为空闲 */
46static const unsigned int block_allocate_bit = ((unsigned int) 1) << ((sizeof(unsigned int) * 8) - 1);
47
54static block_link_t start, *end = (void *)0;
55
56/* ==================== [Macros] ============================================ */
57
58/* ==================== [Global Functions] ================================== */
59
60void *xf_heap_malloc(unsigned int size)
61{
62 block_link_t *block, *previous_block, *new_block_link;
63 void *ret = (void *) 0;
64
66
67 if ((size & block_allocate_bit) == 0) {
68 /* 申请内存大小进行对齐 */
69 if ((size > 0) && ((size + heap_struct_size) > size)) {
70 size += heap_struct_size;
71
72 if ((size & BYTE_ALIGNMENT_MASK) != 0x00) {
73 if ((size + (XF_HEAP_BYTE_ALIGNMENT - (size & BYTE_ALIGNMENT_MASK))) > size) {
75 } else {
76 size = 0;
77 }
78 }
79 } else {
80 size = 0;
81 }
82
87 if ((size > 0)) {
88 previous_block = &start;
89 block = start.next_free_block;
90
91 while ((block->block_size < size) && (block->next_free_block != (void *) 0)) {
92 previous_block = block;
93 block = block->next_free_block;
94 }
95
96 if (block != end) {
97 ret = (void *)(((unsigned char *) previous_block->next_free_block) + heap_struct_size);
98
99 previous_block->next_free_block = block->next_free_block;
100
101 if ((block->block_size - size) > MINIMUM_BLOCK_SIZE) {
102 new_block_link = (void *)((unsigned char *) block + size);
103
104 new_block_link->block_size = block->block_size - size;
105 block->block_size = size;
106
107 insert_block_into_free_list((new_block_link));
108 }
109
111 block->next_free_block = (void *) 0;
112 }
113 }
114 }
115
116 return ret;
117}
118
119void xf_heap_free(void *pv)
120{
121 unsigned char *puc = (unsigned char *) pv;
122 block_link_t *link;
123
124 if (pv != (void *) 0) {
125 puc -= heap_struct_size;
126
127 link = (void *) puc;
128
130 XF_HEAP_ASSERT(link->next_free_block == (void *) 0);
131
132 if ((link->block_size & block_allocate_bit) != 0) {
133 if (link->next_free_block == (void *) 0) {
134 link->block_size &= ~block_allocate_bit;
136 }
137 }
138 }
139}
140
141unsigned int xf_heap_region(const xf_heap_region_t *const heap_regions)
142{
143 block_link_t *first_free_block_in_region = (void *) 0, *previous_free_block;
144 xf_heap_intptr_t aligned_heap;
145 unsigned int total_region_size, total_heap_size = 0;
146 long defined_regions = 0;
147 xf_heap_intptr_t address;
148 const xf_heap_region_t *heap_region;
149
150 XF_HEAP_ASSERT(end == (void *) 0);
151
152 heap_region = &(heap_regions[defined_regions]);
153
154 /* 循环将heap_regions内的内存分别注册进空闲内存块链表里 */
155 while (heap_region->size_in_bytes > 0) {
156 total_region_size = heap_region->size_in_bytes;
157
158 address = (xf_heap_intptr_t) heap_region->stat_address;
159
160 if ((address & BYTE_ALIGNMENT_MASK) != 0) {
161 address += (XF_HEAP_BYTE_ALIGNMENT - 1);
162 address &= ~BYTE_ALIGNMENT_MASK;
163
164 total_region_size -= address - (xf_heap_intptr_t) heap_region->stat_address;
165 }
166
167 aligned_heap = address;
168
169 if (defined_regions == 0) {
170 start.next_free_block = (block_link_t *) aligned_heap;
171 start.block_size = (unsigned int) 0;
172 } else {
173 XF_HEAP_ASSERT(end != (void *) 0);
174 XF_HEAP_ASSERT(address > (unsigned int) end);
175 }
176
177 previous_free_block = end;
178 address = aligned_heap + total_region_size;
179 address -= heap_struct_size;
180 address &= ~BYTE_ALIGNMENT_MASK;
181 end = (block_link_t *) address;
182 end->block_size = 0;
183 end->next_free_block = (void *) 0;
184
185 first_free_block_in_region = (block_link_t *) aligned_heap;
186 first_free_block_in_region->block_size = address - (xf_heap_intptr_t) first_free_block_in_region;
187 first_free_block_in_region->next_free_block = end;
188
189 if (previous_free_block != (void *) 0) {
190 previous_free_block->next_free_block = first_free_block_in_region;
191 }
192
193 total_heap_size += first_free_block_in_region->block_size;
194
195 defined_regions++;
196 heap_region = &(heap_regions[defined_regions]);
197 }
198
199 XF_HEAP_ASSERT(total_heap_size);
200
201 return total_heap_size;
202}
203
204unsigned int xf_heap_get_block_size(void *pv)
205{
206 unsigned int block_size = 0;
207 unsigned char *puc = (unsigned char *) pv;
208 block_link_t *link;
209
210 if (pv != (void *) 0) {
211 puc -= heap_struct_size;
212
213 link = (void *) puc;
214
215 if ((link->block_size & block_allocate_bit) != 0) {
216 if (link->next_free_block == (void *) 0) {
217 block_size = link->block_size & (~block_allocate_bit);
218 return block_size;
219 }
220 }
221 }
222 return 0;
223}
224
225/* ==================== [Static Functions] ================================== */
226
232static void insert_block_into_free_list(block_link_t *block_to_insert)
233{
234 block_link_t *iterator;
235 unsigned char *puc;
236
237 for (iterator = &start; iterator->next_free_block < block_to_insert; iterator = iterator->next_free_block) {
238 }
239
240 puc = (unsigned char *) iterator;
241
242 if ((puc + iterator->block_size) == (unsigned char *) block_to_insert) {
243 iterator->block_size += block_to_insert->block_size;
244 block_to_insert = iterator;
245 }
246
247 puc = (unsigned char *) block_to_insert;
248
249 if ((puc + block_to_insert->block_size) == (unsigned char *) iterator->next_free_block) {
250 if (iterator->next_free_block != end) {
251 block_to_insert->block_size += iterator->next_free_block->block_size;
252 block_to_insert->next_free_block = iterator->next_free_block->next_free_block;
253 } else {
254 block_to_insert->next_free_block = end;
255 }
256 } else {
257 block_to_insert->next_free_block = iterator->next_free_block;
258 }
259
260 if (iterator != block_to_insert) {
261 iterator->next_free_block = block_to_insert;
262 }
263}
堆内存块结构体。
Definition xf_heap.h:67
unsigned int size_in_bytes
Definition xf_heap.h:69
unsigned char * stat_address
Definition xf_heap.h:68
static void insert_block_into_free_list(block_link_t *block_to_insert)
将内存块插入空闲链表中,前后内存连续则进行合并
Definition xf_alloc.c:232
void xf_heap_free(void *pv)
带内存管理的内存释放函数。
Definition xf_alloc.c:119
static const unsigned int block_allocate_bit
Definition xf_alloc.c:46
unsigned int xf_heap_get_block_size(void *pv)
获取内存块的实际大小。
Definition xf_alloc.c:204
unsigned int xf_heap_region(const xf_heap_region_t *const heap_regions)
内存注册,需要在使用 xf_heap_malloc 之前注册。
Definition xf_alloc.c:141
#define MINIMUM_BLOCK_SIZE
Definition xf_alloc.c:25
static block_link_t start
闲内存块链表的起点和终点。 用户在注册的时候末尾 next_free_block 为 (void*) 0,block_size 为 0
Definition xf_alloc.c:54
struct _block_link_t block_link_t
static const unsigned int heap_struct_size
Definition xf_alloc.c:41
void * xf_heap_malloc(unsigned int size)
带内存管理的内存申请函数。
Definition xf_alloc.c:60
static block_link_t * end
Definition xf_alloc.c:54
#define BYTE_ALIGNMENT_MASK
Definition xf_alloc.c:22
基于 heap5 的内存分配实现。
使用 xfusion 菜单配置 xf_heap 内部配置。
#define XF_HEAP_ASSERT(x)
#define XF_HEAP_BYTE_ALIGNMENT
XF_HEAP_INTPTR_TYPE xf_heap_intptr_t