/**************************************************************************** * * 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; }