165 lines
6.2 KiB
C
Executable File
165 lines
6.2 KiB
C
Executable File
/****************************************************************************
|
|
*
|
|
* 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;
|
|
}
|