Skip to content

Commit

Permalink
Merge pull request #12031 from jcarrano/tlsf-malloc-fix-override
Browse files Browse the repository at this point in the history
 pkg/tlsf: Fix the way system functions are overriden.
  • Loading branch information
benpicco authored Sep 17, 2019
2 parents d5c272e + cc907fa commit f020951
Show file tree
Hide file tree
Showing 8 changed files with 316 additions and 92 deletions.
9 changes: 9 additions & 0 deletions pkg/tlsf/Makefile.dep
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
ifneq (,$(filter tlsf-malloc,$(USEMODULE)))
ifneq (,$(filter newlib,$(USEMODULE)))
USEMODULE += tlsf-malloc_newlib
else ifneq (,$(filter native,$(BOARD)))
USEMODULE += tlsf-malloc_native
else
$(warning tlsf-malloc can only be used on native or on platforms using newlib)
endif
endif
9 changes: 9 additions & 0 deletions pkg/tlsf/Makefile.include
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,12 @@ ifneq (,$(filter tlsf-malloc,$(USEMODULE)))
INCLUDES += -I$(RIOTPKG)/tlsf/contrib/include
DIRS += $(RIOTPKG)/tlsf/contrib
endif

PSEUDOMODULES += tlsf-malloc_newlib
PSEUDOMODULES += tlsf-malloc_native

ifneq (,$(filter tlsf-malloc_newlib,$(USEMODULE)))
UNDEF += $(BINDIR)/tlsf-malloc/newlib.o
else ifneq (,$(filter tlsf-malloc_native,$(BOARD)))
UNDEF += $(BINDIR)/tlsf-malloc/native.o
endif
4 changes: 3 additions & 1 deletion pkg/tlsf/contrib/Makefile
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
MODULE := tlsf-malloc
MODULE = tlsf-malloc
SUBMODULES = 1
SRC = tlsf-malloc.c

include $(RIOTBASE)/Makefile.base
3 changes: 2 additions & 1 deletion pkg/tlsf/contrib/include/tlsf-malloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#define TLSF_MALLOC_H

#include <stddef.h>

#include "tlsf.h"

#ifdef __cplusplus
Expand Down Expand Up @@ -86,7 +87,7 @@ int tlsf_add_global_pool(void *mem, size_t bytes);
*
* Use for debugging purposes only.
*/
tlsf_t *_tlsf_get_global_control(void);
tlsf_t _tlsf_get_global_control(void);


#ifdef __cplusplus
Expand Down
123 changes: 123 additions & 0 deletions pkg/tlsf/contrib/native.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/*
* Copyright (C) 2019 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup pkg_tlsf_malloc
* @ingroup pkg
* @ingroup sys
* @{
* @file
*
* @brief Definitions to use tlsf as malloc on native.
* @author Juan I Carrano
*
* This assumes glibc is bein used.
* see: https://www.gnu.org/software/libc/manual/html_node/Replacing-malloc.html
*
*/

#include <string.h>
#include <errno.h>

#include "irq.h"
#include "tlsf.h"
#include "tlsf-malloc.h"
#include "tlsf-malloc-internal.h"

/* TODO: Add defines for other compilers */
#if defined(__GNUC__) && !defined(__clang__) /* Clang supports __GNUC__ but
* not the alloc_size()
* attribute */

#define ATTR_MALLOC __attribute__((malloc, alloc_size(1)))
#define ATTR_CALLOC __attribute__((malloc, alloc_size(1,2)))
#define ATTR_MALIGN __attribute__((alloc_align(1), alloc_size(2), malloc))
#define ATTR_REALLOC __attribute__((alloc_size(2)))

#else /* No GNU C -> no alias attribute */

#define ATTR_MALLOC
#define ATTR_CALLOC
#define ATTR_MALIGN
#define ATTR_REALLOC

#endif /* __GNUC__ */

extern tlsf_t tlsf_malloc_gheap;

/**
* Allocate a block of size "bytes"
*/
ATTR_MALLOC void *malloc(size_t bytes)
{
unsigned old_state = irq_disable();
void *result = tlsf_malloc(tlsf_malloc_gheap, bytes);

if (result == NULL) {
errno = ENOMEM;
}

irq_restore(old_state);
return result;
}

/**
* Allocate and clear a block of size "bytes*count"
*/
ATTR_CALLOC void *calloc(size_t count, size_t bytes)
{
void *result = malloc(count * bytes);

if (result != NULL) {
memset(result, 0, count * bytes);
}
return result;
}

/**
* Allocate an aligned memory block.
*/
ATTR_MALIGN void *memalign(size_t align, size_t bytes)
{
unsigned old_state = irq_disable();
void *result = tlsf_memalign(tlsf_malloc_gheap, align, bytes);

if (result == NULL) {
errno = ENOMEM;
}

irq_restore(old_state);
return result;
}

/**
* Deallocate and reallocate with a different size.
*/
ATTR_REALLOC void *realloc(void *ptr, size_t size)
{
unsigned old_state = irq_disable();
void *result = tlsf_realloc(tlsf_malloc_gheap, ptr, size);

if (result == NULL) {
errno = ENOMEM;
}

irq_restore(old_state);
return result;
}


/**
* Deallocate a block of data.
*/
void free(void *ptr)
{
unsigned old_state = irq_disable();

tlsf_free(tlsf_malloc_gheap, ptr);
irq_restore(old_state);
}
128 changes: 128 additions & 0 deletions pkg/tlsf/contrib/newlib.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
/*
* Copyright (C) 2019 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup pkg_tlsf_malloc
* @ingroup pkg
* @ingroup sys
* @{
* @file
*
* @brief Reentrant definitions to replace newlib's malloc with TLSF.
* @author Juan I Carrano
*
* Newlib-nano implements malloc/free/etc in terms of the reentrant definitions
* in _malloc_r/_free_r/etc so the latter are the one that have to be
* overwritten.
*
*/

#include <string.h>
#include <reent.h>
#include <errno.h>

#include "irq.h"
#include "tlsf.h"
#include "tlsf-malloc.h"
#include "tlsf-malloc-internal.h"


/* TODO: Add defines for other compilers */
#if defined(__GNUC__) && !defined(__clang__) /* Clang supports __GNUC__ but
* not the alloc_size()
* attribute */

#define ATTR_MALLOCR __attribute__((malloc, alloc_size(2)))
#define ATTR_CALLOCR __attribute__((malloc, alloc_size(2,3)))
#define ATTR_MALIGNR __attribute__((alloc_align(2), alloc_size(3), malloc))
#define ATTR_REALLOCR __attribute__((alloc_size(3)))

#else /* No GNU C -> no alias attribute */

#define ATTR_MALLOCR
#define ATTR_CALLOCR
#define ATTR_MALIGNR
#define ATTR_REALLOCR

#endif /* __GNUC__ */

/**
* Allocate a block of size "bytes"
*/
ATTR_MALLOCR void *_malloc_r(struct _reent *reent_ptr, size_t bytes)
{
unsigned old_state = irq_disable();
void *result = tlsf_malloc(tlsf_malloc_gheap, bytes);

if (result == NULL) {
reent_ptr->_errno = ENOMEM;
}

irq_restore(old_state);
return result;
}

/**
* Allocate and clear a block of size "bytes*count"
*/
ATTR_CALLOCR void *_calloc_r(struct _reent *reent_ptr, size_t count, size_t bytes)
{
void *result = _malloc_r(reent_ptr, count * bytes);

if (result != NULL) {
memset(result, 0, count * bytes);
}
return result;
}

/**
* Allocate an aligned memory block.
*/
ATTR_MALIGNR void *_memalign_r(struct _reent *reent_ptr, size_t align, size_t bytes)
{
unsigned old_state = irq_disable();
void *result = tlsf_memalign(tlsf_malloc_gheap, align, bytes);

if (result == NULL) {
reent_ptr->_errno = ENOMEM;
}

irq_restore(old_state);
return result;
}

/**
* Deallocate and reallocate with a different size.
*/
ATTR_REALLOCR void *_realloc_r(struct _reent *reent_ptr, void *ptr, size_t size)
{
unsigned old_state = irq_disable();
void *result = tlsf_realloc(tlsf_malloc_gheap, ptr, size);

if (result == NULL) {
reent_ptr->_errno = ENOMEM;
}

irq_restore(old_state);
return result;
}

/**
* Deallocate a block of data.
*/
void _free_r(struct _reent *reent_ptr, void *ptr)
{
unsigned old_state = irq_disable();
(void)reent_ptr;

tlsf_free(tlsf_malloc_gheap, ptr);
irq_restore(old_state);
}

/**
* @}
*/
34 changes: 34 additions & 0 deletions pkg/tlsf/contrib/tlsf-malloc-internal.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright (C) 2014-2018 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup pkg_tlsf_malloc
* @{
* @file
* @internal
*
* @brief TLSF/malloc internal definitions
* @author Juan I Carrano
*
*/

#ifndef TLSF_MALLOC_INTERNAL_H
#define TLSF_MALLOC_INTERNAL_H

#include "tlsf.h"

#ifdef __cplusplus
extern "C" {
#endif

extern tlsf_t tlsf_malloc_gheap;

#ifdef __cplusplus
}
#endif

#endif /* TLSF_MALLOC_INTERNAL_H */
Loading

0 comments on commit f020951

Please sign in to comment.