rp2040/component/mm/tlsf/port_tlsf.c

165 lines
6.2 KiB
C
Raw Normal View History

2025-06-29 17:14:59 +08:00
/****************************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include "mem.h"
#include "tlsf.h"
#include "common.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
#if 0
#define TLSF_MALLOC_ASSERT(heap, x, size) \
{ \
if (!(x)) { \
printf("tlsf malloc %d bytes failed at function %s using heap base:%p\r\n", size, __FUNCTION__, heap->heapstart); \
port_irq_save(); \
while (1) \
; \
} \
}
#else
#define TLSF_MALLOC_ASSERT(heap, x, size) \
{ \
if (!(x)) { \
printf("tlsf malloc %d bytes failed at function %s using heap base:%p\r\n", size, __FUNCTION__, heap->heapstart); \
} \
}
#endif
/****************************************************************************
* Name: mem_tlfsinfo_walker
****************************************************************************/
static void mem_tlfsinfo_walker(void *ptr, size_t size, int used,
void *user)
{
struct meminfo *info = user;
if (!used) {
info->free_node++;
info->free_size += size;
if (size > info->max_free_size) {
info->max_free_size = size;
}
}
}
/****************************************************************************
* Functions
****************************************************************************/
void port_mem_init(struct mem_heap_s *heap, void *heapstart, size_t heapsize)
{
heap->heapstart = (uint8_t *)heapstart + tlsf_size();
heap->heapsize = heapsize - tlsf_size();
heap->priv = tlsf_create_with_pool(heapstart, heapsize);
}
void *port_malloc(struct mem_heap_s *heap, size_t nbytes)
{
void *ret = NULL;
uint32_t flag;
flag = save_and_disable_interrupt();
ret = tlsf_memalign(heap->priv, 32, nbytes);
TLSF_MALLOC_ASSERT(heap, ret != NULL, nbytes);
restore_interrupt(flag);
return ret;
}
void port_free(struct mem_heap_s *heap, void *ptr)
{
uint32_t flag;
flag = save_and_disable_interrupt();
tlsf_free(heap->priv, ptr);
restore_interrupt(flag);
}
void *port_realloc(struct mem_heap_s *heap, void *ptr, size_t nbytes)
{
void *ret = NULL;
uint32_t flag;
flag = save_and_disable_interrupt();
ret = tlsf_realloc(heap->priv, ptr, nbytes);
TLSF_MALLOC_ASSERT(heap, ((nbytes != 0 && ret != NULL) || (nbytes == 0 && ret == NULL)), nbytes);
restore_interrupt(flag);
return ret;
}
void *port_calloc(struct mem_heap_s *heap, size_t count, size_t size)
{
void *ptr = NULL;
size_t total = count * size;
uint32_t flag;
flag = save_and_disable_interrupt();
if (count > 0 && size > 0) {
if (count <= (SIZE_MAX / size)) {
ptr = tlsf_malloc(heap->priv, total);
if (ptr) {
memset(ptr, 0, total);
}
}
}
restore_interrupt(flag);
return ptr;
}
void *port_malloc_align(struct mem_heap_s *heap, size_t align, size_t size)
{
void *ret = NULL;
uint32_t flag;
flag = save_and_disable_interrupt();
ret = tlsf_memalign(heap->priv, align, size);
TLSF_MALLOC_ASSERT(heap, ret != NULL, size);
restore_interrupt(flag);
return ret;
}
void port_mem_usage(struct mem_heap_s *heap, struct meminfo *info)
{
uint32_t flag;
memset(info, 0, sizeof(struct meminfo));
flag = save_and_disable_interrupt();
tlsf_walk_pool(heap->heapstart, mem_tlfsinfo_walker, info);
restore_interrupt(flag);
info->total_size = heap->heapsize;
info->used_size = info->total_size - info->free_size;
}