Skip to content

Commit

Permalink
Merge pull request #5 from yangjie11/tlsf
Browse files Browse the repository at this point in the history
[add]add apis for tlsf: heap add/remove, malloc/free align, list_mem
  • Loading branch information
Guozhanxin authored Jun 16, 2021
2 parents 4e24985 + be7a9e1 commit 6464dbc
Show file tree
Hide file tree
Showing 4 changed files with 154 additions and 11 deletions.
30 changes: 28 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,9 @@ It also leverages the TLSF 2.0 improvement to shrink the per-block overhead from
* First release

-----
## How to use tlsf package
## How to use TLSF

### Select TLSF package

Enable the user heap algorithm:

Expand All @@ -105,12 +107,36 @@ Enable the user heap algorithm:
( ) Small Memory Algorithm
( ) SLAB Algorithm for large memory
( ) Use all of memheap objects as heap
(X) Use user heap
(X) Use user heap Algorithm
```
And enable the tlsf packages:

```
-> RT-Thread online packages
-> system packages
[*] TLSF: A dynamic memory allocation algorithm with predictable execution time and low fragmentation.
[ ] Enable TLSF align
Version (latest) --->
```

- Enable TLSF align:Using TLSF align (malloc align and free align) algorithm if it is selected. Using system align algorithm if it is not selected.
- Version: The version of TLSF package.

### Multiple heaps

When the system is initialized, one heap(pool) is added automatically. If multiple heaps(pools) are needed, use the APIs show below:

add another heap(pool):

```c
void *heap = rt_system_heap_add((void *)SRAM_START_ADDR, (void *)SRAM_END_ADDR);
```

remove the heap(pool):

```c
rt_system_heap_remove(heap);
```
Note: the maximum number of heaps is 255.
110 changes: 104 additions & 6 deletions rt_tlsf.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,22 @@
*/

#include <rtthread.h>
#include "tlsf.h"
#include "rt_tlsf.h"

#if defined (RT_USING_USERHEAP) && defined (PKG_USING_TLSF)

static tlsf_t tlsf_ptr = 0;
static struct rt_semaphore heap_sem;

struct pool_list
{
pool_t pool_addr;
rt_slist_t list;
};
typedef struct pool_list *pool_list_t;

static pool_list_t pools_list;

#ifdef RT_USING_HOOK
static void (*rt_malloc_hook)(void *ptr, rt_size_t size);
static void (*rt_free_hook)(void *ptr);
Expand All @@ -33,6 +42,7 @@ void rt_free_sethook(void (*hook)(void *ptr))
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;
Expand All @@ -44,14 +54,85 @@ void rt_system_heap_init(void *begin_addr, void *end_addr)
if (!tlsf_ptr)
{
tlsf_ptr = (tlsf_t)tlsf_create_with_pool(begin_addr, size);
rt_sem_init(&heap_sem, "heap", 1, RT_IPC_FLAG_PRIO);

pools_list = rt_malloc(sizeof(struct pool_list));
rt_slist_init(&pools_list->list);
pools_list->pool_addr = tlsf_get_pool(tlsf_ptr);
}
else
{
RT_ASSERT(0);
}
}

void *rt_system_heap_add(void *begin_addr, void *end_addr)
{
pool_t tlsf_pool;
size_t size;
pool_list_t heap;

if (begin_addr < end_addr)
{
size = (rt_uint32_t)end_addr - (rt_uint32_t)begin_addr;
}
else
{
RT_ASSERT(0);
}

if (tlsf_ptr)
{
tlsf_pool = tlsf_add_pool(tlsf_ptr, begin_addr, size);
if (tlsf_pool != RT_NULL)
{
heap = rt_malloc(sizeof(struct pool_list));
rt_slist_append(&pools_list->list, &heap->list);
heap->pool_addr = tlsf_pool;
return heap;
}
}
return RT_NULL;
}

void rt_system_heap_remove(void *heap)
{
RT_ASSERT(heap != RT_NULL);

pool_list_t pool_node = (pool_list_t)heap;
pool_t pool = pool_node->pool_addr;

if (tlsf_ptr)
{
rt_slist_remove(&pools_list->list, &pool_node->list);
rt_free(pool_node);
tlsf_remove_pool(tlsf_ptr, pool);
}
}

#ifdef PKG_TLSF_USING_ALIGN
void *rt_malloc_align(rt_size_t size, rt_size_t align)
{
void *ptr = RT_NULL;

if (tlsf_ptr)
{
rt_sem_take(&heap_sem, RT_WAITING_FOREVER);
ptr = tlsf_memalign(tlsf_ptr, align, size);
rt_sem_release(&heap_sem);
}
return ptr;
}

rt_sem_init(&heap_sem, "heap", 1, RT_IPC_FLAG_FIFO);
void rt_free_align(void *ptr)
{
rt_free(ptr);
}
#endif

void *rt_malloc(rt_size_t nbytes)
{
void *ptr;
void *ptr = RT_NULL;

if (tlsf_ptr)
{
Expand All @@ -64,6 +145,7 @@ void *rt_malloc(rt_size_t nbytes)
}
return ptr;
}
RTM_EXPORT(rt_malloc);

void rt_free(void *ptr)
{
Expand All @@ -77,6 +159,7 @@ void rt_free(void *ptr)
rt_sem_release(&heap_sem);
}
}
RTM_EXPORT(rt_free);

void *rt_realloc(void *ptr, rt_size_t nbytes)
{
Expand All @@ -90,10 +173,11 @@ void *rt_realloc(void *ptr, rt_size_t nbytes)
}
return ptr;
}
RTM_EXPORT(rt_realloc);

void *rt_calloc(rt_size_t count, rt_size_t size)
{
void *ptr;
void *ptr = RT_NULL;
rt_size_t total_size;

total_size = count * size;
Expand All @@ -106,6 +190,7 @@ void *rt_calloc(rt_size_t count, rt_size_t size)

return ptr;
}
RTM_EXPORT(rt_calloc);

static size_t used_mem = 0;
static size_t total_mem = 0;
Expand Down Expand Up @@ -135,13 +220,26 @@ void rt_memory_info(rt_uint32_t *total,

void list_mem(void)
{
rt_uint8_t i = 0;
rt_uint8_t len = 0;

pool_list_t pool_node;
struct rt_slist_node *node;
node = &pools_list->list;

used_mem = 0;
total_mem = 0;

tlsf_walk_pool(tlsf_get_pool(tlsf_ptr), mem_info, 0);

len = rt_slist_len(node) + 1;
for (i = 0; i < len; i++)
{
pool_node = rt_container_of(node, struct pool_list, list);
tlsf_walk_pool(pool_node->pool_addr, mem_info, 0);
node = node->next;
}
rt_kprintf("total memory: %d\n", total_mem);
rt_kprintf("used memory : %d\n", used_mem);
}

#endif

18 changes: 18 additions & 0 deletions rt_tlsf.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-06-11 Joyce the first version
*/
#ifndef RT_TLSF_H_
#define RT_TLSF_H_

#include "tlsf.h"

void *rt_system_heap_add(void *begin_addr, void *end_addr);
void rt_system_heap_remove(void *heap);

#endif /* RT_TLSF_H_ */
7 changes: 4 additions & 3 deletions src/tlsf.c
Original file line number Diff line number Diff line change
Expand Up @@ -927,7 +927,7 @@ void tlsf_walk_pool(pool_t pool, tlsf_walker walker, void *user)
{
tlsf_walker pool_walker = walker ? walker : default_walker;
block_header_t *block =
offset_to_block(pool, -(int)block_header_overhead);
offset_to_block(pool, -(size_t)block_header_overhead);

while (block && !block_is_last(block))
{
Expand Down Expand Up @@ -1033,7 +1033,7 @@ pool_t tlsf_add_pool(tlsf_t tlsf, void *mem, size_t bytes)
** so that the prev_phys_block field falls outside of the pool -
** it will never be used.
*/
block = offset_to_block(mem, -(tlsfptr_t)block_header_overhead);
block = offset_to_block(mem, -(size_t)block_header_overhead);
block_set_size(block, pool_bytes);
block_set_free(block);
block_set_prev_used(block);
Expand All @@ -1051,7 +1051,7 @@ pool_t tlsf_add_pool(tlsf_t tlsf, void *mem, size_t bytes)
void tlsf_remove_pool(tlsf_t tlsf, pool_t pool)
{
control_t *control = tlsf_cast(control_t *, tlsf);
block_header_t *block = offset_to_block(pool, -(int)block_header_overhead);
block_header_t *block = offset_to_block(pool, -(size_t)block_header_overhead);

int fl = 0, sl = 0;

Expand Down Expand Up @@ -1284,3 +1284,4 @@ void *tlsf_realloc(tlsf_t tlsf, void *ptr, size_t size)

return p;
}

0 comments on commit 6464dbc

Please sign in to comment.