53#if defined (RT_USING_SMALL_MEM)
55#define DBG_TAG "kernel.mem"
56#define DBG_LVL DBG_INFO
59struct rt_small_mem_item
64#ifdef RT_USING_MEMTRACE
78 struct rt_memory parent;
80 struct rt_small_mem_item *heap_end;
81 struct rt_small_mem_item *lfree;
85#define MIN_SIZE (sizeof(rt_uintptr_t) + sizeof(rt_size_t) + sizeof(rt_size_t))
87#define MEM_MASK ((~(rt_size_t)0) - 1)
89#define MEM_USED(_mem) ((((rt_uintptr_t)(_mem)) & MEM_MASK) | 0x1)
90#define MEM_FREED(_mem) ((((rt_uintptr_t)(_mem)) & MEM_MASK) | 0x0)
91#define MEM_ISUSED(_mem) \
92 (((rt_uintptr_t)(((struct rt_small_mem_item *)(_mem))->pool_ptr)) & (~MEM_MASK))
93#define MEM_POOL(_mem) \
94 ((struct rt_small_mem *)(((rt_uintptr_t)(((struct rt_small_mem_item *)(_mem))->pool_ptr)) & (MEM_MASK)))
95#define MEM_SIZE(_heap, _mem) \
96 (((struct rt_small_mem_item *)(_mem))->next - ((rt_uintptr_t)(_mem) - \
97 (rt_uintptr_t)((_heap)->heap_ptr)) - RT_ALIGN(sizeof(struct rt_small_mem_item), RT_ALIGN_SIZE))
99#define MIN_SIZE_ALIGNED RT_ALIGN(MIN_SIZE, RT_ALIGN_SIZE)
100#define SIZEOF_STRUCT_MEM RT_ALIGN(sizeof(struct rt_small_mem_item), RT_ALIGN_SIZE)
102#ifdef RT_USING_MEMTRACE
103rt_inline
void rt_smem_setname(
struct rt_small_mem_item *mem,
const char *name)
106 for (index = 0; index <
sizeof(mem->thread); index ++)
108 if (name[index] ==
'\0')
break;
109 mem->thread[index] = name[index];
112 for (; index <
sizeof(mem->thread); index ++)
114 mem->thread[index] =
' ';
119static void plug_holes(
struct rt_small_mem *m,
struct rt_small_mem_item *mem)
121 struct rt_small_mem_item *nmem;
122 struct rt_small_mem_item *pmem;
128 nmem = (
struct rt_small_mem_item *)&m->heap_ptr[mem->next];
135 if (m->lfree == nmem)
140 mem->next = nmem->next;
141 ((
struct rt_small_mem_item *)&m->heap_ptr[nmem->next])->prev = (
rt_uint8_t *)mem - m->heap_ptr;
145 pmem = (
struct rt_small_mem_item *)&m->heap_ptr[mem->prev];
154 pmem->next = mem->next;
155 ((
struct rt_small_mem_item *)&m->heap_ptr[mem->next])->prev = (
rt_uint8_t *)pmem - m->heap_ptr;
174 struct rt_small_mem_item *mem;
175 struct rt_small_mem *small_mem;
176 rt_uintptr_t start_addr, begin_align, end_align, mem_size;
179 start_addr = (
rt_uintptr_t)small_mem +
sizeof(*small_mem);
192 rt_kprintf(
"mem init, error begin address 0x%x, and end address 0x%x\n",
198 rt_memset(small_mem, 0,
sizeof(*small_mem));
202 small_mem->parent.
address = begin_align;
203 small_mem->parent.
total = mem_size;
204 small_mem->mem_size_aligned = mem_size;
207 small_mem->heap_ptr = (
rt_uint8_t *)begin_align;
209 LOG_D(
"mem init, heap begin address 0x%x, size %d",
210 (
rt_uintptr_t)small_mem->heap_ptr, small_mem->mem_size_aligned);
213 mem = (
struct rt_small_mem_item *)small_mem->heap_ptr;
217#ifdef RT_USING_MEMTRACE
218 rt_smem_setname(mem,
"INIT");
222 small_mem->heap_end = (
struct rt_small_mem_item *)&small_mem->heap_ptr[mem->next];
223 small_mem->heap_end->pool_ptr =
MEM_USED(small_mem);
226#ifdef RT_USING_MEMTRACE
227 rt_smem_setname(small_mem->heap_end,
"INIT");
231 small_mem->lfree = (
struct rt_small_mem_item *)small_mem->heap_ptr;
233 return &small_mem->parent;
274 struct rt_small_mem_item *mem, *mem2;
275 struct rt_small_mem *small_mem;
284 small_mem = (
struct rt_small_mem *)m;
286 size =
RT_ALIGN(size, RT_ALIGN_SIZE);
292 if (size > small_mem->mem_size_aligned)
299 for (ptr = (
rt_uint8_t *)small_mem->lfree - small_mem->heap_ptr;
300 ptr <= small_mem->mem_size_aligned - size;
301 ptr = ((
struct rt_small_mem_item *)&small_mem->heap_ptr[ptr])->next)
303 mem = (
struct rt_small_mem_item *)&small_mem->heap_ptr[ptr];
326 mem2 = (
struct rt_small_mem_item *)&small_mem->heap_ptr[ptr2];
328 mem2->next = mem->next;
330#ifdef RT_USING_MEMTRACE
331 rt_smem_setname(mem2,
" ");
339 ((
struct rt_small_mem_item *)&small_mem->heap_ptr[mem2->next])->prev = ptr2;
342 if (small_mem->parent.
max < small_mem->parent.
used)
343 small_mem->parent.
max = small_mem->parent.
used;
354 small_mem->parent.
used += mem->next - ((
rt_uint8_t *)mem - small_mem->heap_ptr);
355 if (small_mem->parent.
max < small_mem->parent.
used)
356 small_mem->parent.
max = small_mem->parent.
used;
359 mem->pool_ptr =
MEM_USED(small_mem);
360#ifdef RT_USING_MEMTRACE
364 rt_smem_setname(mem,
"NONE");
367 if (mem == small_mem->lfree)
370 while (
MEM_ISUSED(small_mem->lfree) && small_mem->lfree != small_mem->heap_end)
371 small_mem->lfree = (
struct rt_small_mem_item *)&small_mem->heap_ptr[small_mem->lfree->next];
379 LOG_D(
"allocate memory at 0x%x, size: %d",
407 struct rt_small_mem_item *mem, *mem2;
408 struct rt_small_mem *small_mem;
415 small_mem = (
struct rt_small_mem *)m;
417 newsize =
RT_ALIGN(newsize, RT_ALIGN_SIZE);
418 if (newsize > small_mem->mem_size_aligned)
420 LOG_D(
"realloc: out of memory");
424 else if (newsize == 0)
441 ptr = (
rt_uint8_t *)mem - small_mem->heap_ptr;
452 small_mem->parent.
used -= (size - newsize);
455 mem2 = (
struct rt_small_mem_item *)&small_mem->heap_ptr[ptr2];
457 mem2->next = mem->next;
459#ifdef RT_USING_MEMTRACE
460 rt_smem_setname(mem2,
" ");
465 ((
struct rt_small_mem_item *)&small_mem->heap_ptr[mem2->next])->prev = ptr2;
468 if (mem2 < small_mem->lfree)
471 small_mem->lfree = mem2;
474 plug_holes(small_mem, mem2);
483 rt_memcpy(nmem, rmem, size < newsize ? size : newsize);
499 struct rt_small_mem_item *mem;
500 struct rt_small_mem *small_mem;
519 LOG_D(
"release memory 0x%x, size: %d",
525#ifdef RT_USING_MEMTRACE
526 rt_smem_setname(mem,
" ");
529 if (mem < small_mem->lfree)
532 small_mem->lfree = mem;
535 small_mem->parent.
used -= (mem->next - ((
rt_uint8_t *)mem - small_mem->heap_ptr));
538 plug_holes(small_mem, mem);
545#ifdef RT_USING_MEMTRACE
546static int memcheck(
int argc,
char *argv[])
550 struct rt_small_mem_item *mem;
551 struct rt_small_mem *m;
572 m = (
struct rt_small_mem *)
object;
573 if(rt_strncmp(m->parent.
algorithm,
"small", RT_NAME_MAX) != 0)
579 for (mem = (
struct rt_small_mem_item *)m->heap_ptr; mem != m->heap_end; mem = (
struct rt_small_mem_item *)&m->heap_ptr[mem->next])
582 if (position < 0)
goto __exit;
583 if (position > (
int)m->mem_size_aligned)
goto __exit;
584 if (
MEM_POOL(mem) != m)
goto __exit;
602static int memtrace(
int argc,
char **argv)
604 struct rt_small_mem_item *mem;
605 struct rt_small_mem *m;
625 m = (
struct rt_small_mem *)
object;
626 if(rt_strncmp(m->parent.
algorithm,
"small", RT_NAME_MAX) != 0)
636 rt_kprintf(
"heap_ptr: 0x%08x\n", m->heap_ptr);
638 rt_kprintf(
"heap_end: 0x%08x\n", m->heap_end);
639 rt_kprintf(
"\n--memory item information --\n");
640 for (mem = (
struct rt_small_mem_item *)m->heap_ptr; mem != m->heap_end; mem = (
struct rt_small_mem_item *)&m->heap_ptr[mem->next])
647 else if (size < 1024 * 1024)
652 rt_kprintf(
"] %c%c%c%c", mem->thread[0], mem->thread[1], mem->thread[2], mem->thread[3]);
#define RT_ALIGN(size, align)
#define RT_ALIGN_DOWN(size, align)
void rt_object_init(struct rt_object *object, enum rt_object_class_type type, const char *name)
This function will initialize an object and add it to object system management.
rt_bool_t rt_object_is_systemobject(rt_object_t object)
This function will judge the object is system object or not.
struct rt_object_information * rt_object_get_information(enum rt_object_class_type type)
This function will return the specified type of object information.
rt_uint8_t rt_object_get_type(rt_object_t object)
This function will return the type of object without RT_Object_Class_Static flag.
void rt_object_detach(rt_object_t object)
This function will detach a static object from object system, and the memory of static object is not ...
#define rt_list_entry(node, type, member)
get the struct for this entry
void rt_smem_free(void *rmem)
This function will release the previously allocated memory block by rt_mem_alloc. The released memory...
void * rt_smem_alloc(rt_smem_t m, rt_size_t size)
Allocate a block of memory with a minimum of 'size' bytes.
void * rt_smem_realloc(rt_smem_t m, void *rmem, rt_size_t newsize)
This function will change the size of previously allocated memory block.
rt_smem_t rt_smem_init(const char *name, void *begin_addr, rt_size_t size)
This function will initialize small memory management algorithm.
rt_err_t rt_smem_detach(rt_smem_t m)
This function will remove a small mem from the system.
rt_thread_t rt_thread_self(void)
This function will return self thread object.
#define MSH_CMD_EXPORT(...)
#define MEM_SIZE(_heap, _mem)
#define SIZEOF_STRUCT_MEM
void rt_hw_interrupt_enable(rt_base_t level)
rt_base_t rt_hw_interrupt_disable(void)
#define RTM_EXPORT(symbol)
struct rt_list_node * next