|
|
@@ -10,116 +10,138 @@
|
|
|
#include <rtthread.h>
|
|
|
#include "rt_tlsf.h"
|
|
|
|
|
|
-#define REGISTER register
|
|
|
+#if defined (RT_USING_USERHEAP) && defined (PKG_USING_TLSF)
|
|
|
|
|
|
-static tlsf_t base_heap = 0;
|
|
|
-static rt_mutex_t tlsflock;
|
|
|
+static tlsf_t tlsf_ptr = 0;
|
|
|
+static struct rt_semaphore heap_sem;
|
|
|
|
|
|
-#define RT_MEM_CTOR(pheap, mem, size) \
|
|
|
- do { \
|
|
|
- TLSF_LOCK_INIT(); \
|
|
|
- (pheap) = (tlsf_t)tlsf_create_with_pool(mem, size); \
|
|
|
- } while (0)
|
|
|
+#ifdef RT_USING_HOOK
|
|
|
+static void (*rt_malloc_hook)(void *ptr, rt_size_t size);
|
|
|
+static void (*rt_free_hook)(void *ptr);
|
|
|
|
|
|
-/*
|
|
|
- * destory memory management
|
|
|
- */
|
|
|
-#define VP_MEM_DTOR(pheap) \
|
|
|
- do { \
|
|
|
- tlsf_destroy((tlsf_t)(pheap)); \
|
|
|
- TLSF_LOCK_DEINIT(); \
|
|
|
- } while (0)
|
|
|
-
|
|
|
-/*
|
|
|
- * add memory to management
|
|
|
- */
|
|
|
-#if CFG_VP_TLSF_LOCK_TYPE == 0
|
|
|
-#define VP_MEM_ADD(pheap, mem, size) tlsf_add_pool((tlsf_t)(pheap), mem, size)
|
|
|
-#else
|
|
|
-#define VP_MEM_ADD(pheap, mem, size) \
|
|
|
- do { \
|
|
|
- TLSF_LOCK(); \
|
|
|
- tlsf_add_pool((tlsf_t)(pheap), mem, size); \
|
|
|
- TLSF_UNLOCK(); \
|
|
|
- } while (0)
|
|
|
-#endif /* CFG_VP_TLSF_LOCK_TYPE */
|
|
|
+void rt_malloc_sethook(void (*hook)(void *ptr, rt_size_t size))
|
|
|
+{
|
|
|
+ rt_malloc_hook = hook;
|
|
|
+}
|
|
|
|
|
|
-/*
|
|
|
- * allocate memory
|
|
|
- */
|
|
|
-static void *RT_MEM_MALLOC(tlsf_t pheap, size_t nbytes)
|
|
|
+void rt_free_sethook(void (*hook)(void *ptr))
|
|
|
{
|
|
|
- REGISTER void *ret;
|
|
|
+ rt_free_hook = hook;
|
|
|
+}
|
|
|
+#endif
|
|
|
|
|
|
- TLSF_LOCK();
|
|
|
- ret = tlsf_malloc((tlsf_t)(pheap), nbytes);
|
|
|
- TLSF_UNLOCK();
|
|
|
+void rt_system_heap_init(void *begin_addr, void *end_addr)
|
|
|
+{
|
|
|
+ size_t size;
|
|
|
+ if (begin_addr < end_addr)
|
|
|
+ {
|
|
|
+ size = (rt_uint32_t)end_addr - (rt_uint32_t)begin_addr;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (!tlsf_ptr)
|
|
|
+ {
|
|
|
+ tlsf_ptr = (tlsf_t)tlsf_create_with_pool(begin_addr, size);
|
|
|
+ }
|
|
|
|
|
|
- return (ret);
|
|
|
+ rt_sem_init(&heap_sem, "heap", 1, RT_IPC_FLAG_FIFO);
|
|
|
}
|
|
|
|
|
|
-/*
|
|
|
- * allocate memory align
|
|
|
- */
|
|
|
-void *RT_MEM_MALLOC_ALIGN(tlsf_t pheap, size_t nbytes, size_t align)
|
|
|
+void *rt_malloc(rt_size_t nbytes)
|
|
|
{
|
|
|
- REGISTER void *ret;
|
|
|
+ void *ptr;
|
|
|
+
|
|
|
+ if (tlsf_ptr)
|
|
|
+ {
|
|
|
+ rt_sem_take(&heap_sem, RT_WAITING_FOREVER);
|
|
|
|
|
|
- TLSF_LOCK();
|
|
|
- ret = tlsf_memalign((tlsf_t)(pheap), align, nbytes);
|
|
|
- TLSF_UNLOCK();
|
|
|
+ ptr = tlsf_malloc(tlsf_ptr, nbytes);
|
|
|
+ RT_OBJECT_HOOK_CALL(rt_malloc_hook, ((void *)ptr, nbytes));
|
|
|
|
|
|
- return (ret);
|
|
|
+ rt_sem_release(&heap_sem);
|
|
|
+ }
|
|
|
+ return ptr;
|
|
|
}
|
|
|
|
|
|
-/*
|
|
|
- * re-allocate memory
|
|
|
- */
|
|
|
-void *RT_MEM_REALLOC(tlsf_t pheap, void *ptr, size_t new_size)
|
|
|
+void rt_free(void *ptr)
|
|
|
{
|
|
|
- REGISTER void *ret;
|
|
|
+ if (tlsf_ptr)
|
|
|
+ {
|
|
|
+ rt_sem_take(&heap_sem, RT_WAITING_FOREVER);
|
|
|
|
|
|
- TLSF_LOCK();
|
|
|
- ret = tlsf_realloc((tlsf_t)(pheap), ptr, new_size);
|
|
|
- TLSF_UNLOCK();
|
|
|
+ tlsf_free(tlsf_ptr, ptr);
|
|
|
+ RT_OBJECT_HOOK_CALL(rt_free_hook, (ptr));
|
|
|
|
|
|
- return (ret);
|
|
|
+ rt_sem_release(&heap_sem);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
-/*
|
|
|
- * free memory
|
|
|
- */
|
|
|
-#define RT_MEM_FREE(pheap, ptr) \
|
|
|
- do { \
|
|
|
- TLSF_LOCK(); \
|
|
|
- tlsf_free((tlsf_t)(pheap), ptr); \
|
|
|
- TLSF_UNLOCK(); \
|
|
|
- } while (0)
|
|
|
-
|
|
|
-
|
|
|
-void rt_app_heap_init(void *begin_addr, uint32_t size)
|
|
|
+void *rt_realloc(void *ptr, rt_size_t nbytes)
|
|
|
{
|
|
|
- if (!base_heap)
|
|
|
+ if (tlsf_ptr)
|
|
|
{
|
|
|
- RT_MEM_CTOR(base_heap, begin_addr, size);
|
|
|
+ rt_sem_take(&heap_sem, RT_WAITING_FOREVER);
|
|
|
+
|
|
|
+ tlsf_realloc(tlsf_ptr, ptr, nbytes);
|
|
|
+
|
|
|
+ rt_sem_release(&heap_sem);
|
|
|
}
|
|
|
+ return ptr;
|
|
|
}
|
|
|
|
|
|
-void *malloc(size_t nbytes)
|
|
|
+void *rt_calloc(rt_size_t count, rt_size_t size)
|
|
|
{
|
|
|
- return RT_MEM_MALLOC(base_heap, nbytes);
|
|
|
+ void *ptr;
|
|
|
+ rt_size_t total_size;
|
|
|
+
|
|
|
+ total_size = count * size;
|
|
|
+ ptr = rt_malloc(total_size);
|
|
|
+ if (ptr != RT_NULL)
|
|
|
+ {
|
|
|
+ /* clean memory */
|
|
|
+ rt_memset(ptr, 0, total_size);
|
|
|
+ }
|
|
|
+
|
|
|
+ return ptr;
|
|
|
}
|
|
|
-void *realloc(void *ptr, unsigned newsize)
|
|
|
+
|
|
|
+static size_t used_mem = 0;
|
|
|
+static size_t total_mem = 0;
|
|
|
+
|
|
|
+static void mem_info(void *ptr, size_t size, int used, void *user)
|
|
|
{
|
|
|
- return RT_MEM_REALLOC(base_heap, ptr, newsize);
|
|
|
+ if (used)
|
|
|
+ {
|
|
|
+ used_mem += size;
|
|
|
+ }
|
|
|
+ total_mem += size;
|
|
|
}
|
|
|
-void *calloc(size_t count, size_t size)
|
|
|
+
|
|
|
+void rt_memory_info(rt_uint32_t *total,
|
|
|
+ rt_uint32_t *used,
|
|
|
+ rt_uint32_t *max_used)
|
|
|
{
|
|
|
- return malloc(count * size);
|
|
|
+ used_mem = 0;
|
|
|
+ total_mem = 0;
|
|
|
+
|
|
|
+ tlsf_walk_pool(tlsf_get_pool(tlsf_ptr), mem_info, 0);
|
|
|
+
|
|
|
+ *total = total_mem;
|
|
|
+ *used = used_mem;
|
|
|
+ *max_used = used_mem;
|
|
|
}
|
|
|
|
|
|
-void free(void *ptr)
|
|
|
+void list_mem(void)
|
|
|
{
|
|
|
- RT_MEM_FREE(base_heap, ptr);
|
|
|
- return;
|
|
|
+ used_mem = 0;
|
|
|
+ total_mem = 0;
|
|
|
+
|
|
|
+ tlsf_walk_pool(tlsf_get_pool(tlsf_ptr), mem_info, 0);
|
|
|
+
|
|
|
+ rt_kprintf("total memory: %d\n", total_mem);
|
|
|
+ rt_kprintf("used memory : %d\n", used_mem);
|
|
|
}
|
|
|
+
|
|
|
+#endif
|