mirror of https://github.com/rusefi/ChibiOS.git
Core allocator enhancements.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@12637 110e8d01-0319-4d1e-a829-52ad28d1bb01
This commit is contained in:
parent
073e26a9db
commit
08c11b47be
|
@ -82,17 +82,33 @@ typedef struct {
|
|||
/**
|
||||
* @brief Next free address.
|
||||
*/
|
||||
uint8_t *nextmem;
|
||||
uint8_t *basemem;
|
||||
/**
|
||||
* @brief Final address.
|
||||
*/
|
||||
uint8_t *endmem;
|
||||
uint8_t *topmem;
|
||||
} memcore_t;
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Allocates a memory block.
|
||||
* @note This is a generic form with unspecified allocation position.
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
#define chCoreAllocAlignedWithOffsetI chCoreAllocFromTopI
|
||||
|
||||
/**
|
||||
* @brief Allocates a memory block.
|
||||
* @note This is a generic form with unspecified allocation position.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define chCoreAllocAlignedWithOffset chCoreAllocFromTop
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
@ -105,12 +121,10 @@ extern memcore_t ch_memcore;
|
|||
extern "C" {
|
||||
#endif
|
||||
void _core_init(void);
|
||||
void *chCoreAllocAlignedWithOffsetI(size_t size,
|
||||
unsigned align,
|
||||
size_t offset);
|
||||
void *chCoreAllocAlignedWithOffset(size_t size,
|
||||
unsigned align,
|
||||
size_t offset);
|
||||
void *chCoreAllocFromBaseI(size_t size, unsigned align, size_t offset);
|
||||
void *chCoreAllocFromTopI(size_t size, unsigned align, size_t offset);
|
||||
void *chCoreAllocFromBase(size_t size, unsigned align, size_t offset);
|
||||
void *chCoreAllocFromTop(size_t size, unsigned align, size_t offset);
|
||||
size_t chCoreGetStatusX(void);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -124,6 +138,7 @@ extern "C" {
|
|||
* @brief Allocates a memory block.
|
||||
* @details The allocated block is guaranteed to be properly aligned to the
|
||||
* specified alignment.
|
||||
* @note This is a generic form with unspecified allocation position.
|
||||
*
|
||||
* @param[in] size the size of the block to be allocated.
|
||||
* @param[in] align desired memory alignment
|
||||
|
@ -141,6 +156,7 @@ static inline void *chCoreAllocAlignedI(size_t size, unsigned align) {
|
|||
* @brief Allocates a memory block.
|
||||
* @details The allocated block is guaranteed to be properly aligned to the
|
||||
* specified alignment.
|
||||
* @note This is a generic form with unspecified allocation position.
|
||||
*
|
||||
* @param[in] size the size of the block to be allocated
|
||||
* @param[in] align desired memory alignment
|
||||
|
@ -150,19 +166,15 @@ static inline void *chCoreAllocAlignedI(size_t size, unsigned align) {
|
|||
* @api
|
||||
*/
|
||||
static inline void *chCoreAllocAligned(size_t size, unsigned align) {
|
||||
void *p;
|
||||
|
||||
chSysLock();
|
||||
p = chCoreAllocAlignedWithOffsetI(size, align, 0U);
|
||||
chSysUnlock();
|
||||
|
||||
return p;
|
||||
return chCoreAllocAlignedWithOffset(size, align, 0U);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Allocates a memory block.
|
||||
* @details The allocated block is guaranteed to be properly aligned for a
|
||||
* pointer data type.
|
||||
* @note This is a generic form with unspecified allocation position.
|
||||
*
|
||||
* @param[in] size the size of the block to be allocated.
|
||||
* @return A pointer to the allocated memory block.
|
||||
|
@ -179,6 +191,7 @@ static inline void *chCoreAllocI(size_t size) {
|
|||
* @brief Allocates a memory block.
|
||||
* @details The allocated block is guaranteed to be properly aligned for a
|
||||
* pointer data type.
|
||||
* @note This is a generic form with unspecified allocation position.
|
||||
*
|
||||
* @param[in] size the size of the block to be allocated.
|
||||
* @return A pointer to the allocated memory block.
|
||||
|
|
|
@ -84,19 +84,19 @@ void _core_init(void) {
|
|||
extern uint8_t __heap_end__[];
|
||||
|
||||
/*lint -save -e9033 [10.8] Required cast operations.*/
|
||||
ch_memcore.nextmem = __heap_base__;
|
||||
ch_memcore.endmem = __heap_end__;
|
||||
ch_memcore.basemem = __heap_base__;
|
||||
ch_memcore.topmem = __heap_end__;
|
||||
/*lint restore*/
|
||||
#else
|
||||
static uint8_t static_heap[CH_CFG_MEMCORE_SIZE];
|
||||
|
||||
ch_memcore.nextmem = &static_heap[0];
|
||||
ch_memcore.endmem = &static_heap[CH_CFG_MEMCORE_SIZE];
|
||||
ch_memcore.basemem = &static_heap[0];
|
||||
ch_memcore.topmem = &static_heap[CH_CFG_MEMCORE_SIZE];
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Allocates a memory block.
|
||||
* @brief Allocates a memory block starting from the lowest address upward.
|
||||
* @details This function allocates a block of @p offset + @p size bytes. The
|
||||
* returned pointer has @p offset bytes before its address and
|
||||
* @p size bytes after.
|
||||
|
@ -109,30 +109,60 @@ void _core_init(void) {
|
|||
*
|
||||
* @iclass
|
||||
*/
|
||||
void *chCoreAllocAlignedWithOffsetI(size_t size,
|
||||
unsigned align,
|
||||
size_t offset) {
|
||||
void *chCoreAllocFromBaseI(size_t size, unsigned align, size_t offset) {
|
||||
uint8_t *p, *next;
|
||||
|
||||
chDbgCheckClassI();
|
||||
chDbgCheck(MEM_IS_VALID_ALIGNMENT(align));
|
||||
|
||||
size = MEM_ALIGN_NEXT(size, align);
|
||||
p = (uint8_t *)MEM_ALIGN_NEXT(ch_memcore.nextmem + offset, align);
|
||||
p = (uint8_t *)MEM_ALIGN_NEXT(ch_memcore.basemem + offset, align);
|
||||
next = p + size;
|
||||
|
||||
/* Considering also the case where there is numeric overflow.*/
|
||||
if ((next > ch_memcore.endmem) || (next < ch_memcore.nextmem)) {
|
||||
if ((next > ch_memcore.topmem) || (next < ch_memcore.basemem)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ch_memcore.nextmem = next;
|
||||
ch_memcore.basemem = next;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Allocates a memory block.
|
||||
* @brief Allocates a memory block starting from the top address downward.
|
||||
* @details This function allocates a block of @p offset + @p size bytes. The
|
||||
* returned pointer has @p offset bytes before its address and
|
||||
* @p size bytes after.
|
||||
*
|
||||
* @param[in] size the size of the block to be allocated.
|
||||
* @param[in] align desired memory alignment
|
||||
* @param[in] offset aligned pointer offset
|
||||
* @return A pointer to the allocated memory block.
|
||||
* @retval NULL allocation failed, core memory exhausted.
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
void *chCoreAllocFromTopI(size_t size, unsigned align, size_t offset) {
|
||||
uint8_t *p, *prev;
|
||||
|
||||
chDbgCheckClassI();
|
||||
chDbgCheck(MEM_IS_VALID_ALIGNMENT(align));
|
||||
|
||||
p = (uint8_t *)MEM_ALIGN_PREV(ch_memcore.topmem - size, align);
|
||||
prev = p - offset;
|
||||
|
||||
/* Considering also the case where there is numeric overflow.*/
|
||||
if ((prev < ch_memcore.basemem) || (prev > ch_memcore.topmem)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ch_memcore.topmem = prev;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Allocates a memory block starting from the lowest address upward.
|
||||
* @details This function allocates a block of @p offset + @p size bytes. The
|
||||
* returned pointer has @p offset bytes before its address and
|
||||
* @p size bytes after.
|
||||
|
@ -145,13 +175,35 @@ void *chCoreAllocAlignedWithOffsetI(size_t size,
|
|||
*
|
||||
* @api
|
||||
*/
|
||||
void *chCoreAllocAlignedWithOffset(size_t size,
|
||||
unsigned align,
|
||||
size_t offset) {
|
||||
void *chCoreAllocFromBase(size_t size, unsigned align, size_t offset) {
|
||||
void *p;
|
||||
|
||||
chSysLock();
|
||||
p = chCoreAllocAlignedWithOffsetI(size, align, offset);
|
||||
p = chCoreAllocFromBaseI(size, align, offset);
|
||||
chSysUnlock();
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Allocates a memory block starting from the top address downward.
|
||||
* @details This function allocates a block of @p offset + @p size bytes. The
|
||||
* returned pointer has @p offset bytes before its address and
|
||||
* @p size bytes after.
|
||||
*
|
||||
* @param[in] size the size of the block to be allocated.
|
||||
* @param[in] align desired memory alignment
|
||||
* @param[in] offset aligned pointer offset
|
||||
* @return A pointer to the allocated memory block.
|
||||
* @retval NULL allocation failed, core memory exhausted.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
void *chCoreAllocFromTop(size_t size, unsigned align, size_t offset) {
|
||||
void *p;
|
||||
|
||||
chSysLock();
|
||||
p = chCoreAllocFromTopI(size, align, offset);
|
||||
chSysUnlock();
|
||||
|
||||
return p;
|
||||
|
@ -167,7 +219,7 @@ void *chCoreAllocAlignedWithOffset(size_t size,
|
|||
size_t chCoreGetStatusX(void) {
|
||||
|
||||
/*lint -save -e9033 [10.8] The cast is safe.*/
|
||||
return (size_t)(ch_memcore.endmem - ch_memcore.nextmem);
|
||||
return (size_t)(ch_memcore.topmem - ch_memcore.basemem);
|
||||
/*lint -restore*/
|
||||
}
|
||||
#endif /* CH_CFG_USE_MEMCORE == TRUE */
|
||||
|
|
|
@ -1,58 +1,58 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
|
||||
ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
|
||||
|
||||
Licensed 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
|
||||
Licensed 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
|
||||
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.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
/*
|
||||
* **** This file incorporates work covered by the following copyright and ****
|
||||
* **** permission notice: ****
|
||||
*
|
||||
* Copyright (c) 2009 by Michael Fischer. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the author nor the names of its contributors may
|
||||
* be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************
|
||||
* History:
|
||||
*
|
||||
* 28.03.09 mifi First Version, based on the original syscall.c from
|
||||
* newlib version 1.17.0
|
||||
* 17.08.09 gdisirio Modified the file for use under ChibiOS/RT
|
||||
* 15.11.09 gdisirio Added read and write handling
|
||||
****************************************************************************/
|
||||
* **** This file incorporates work covered by the following copyright and ****
|
||||
* **** permission notice: ****
|
||||
*
|
||||
* Copyright (c) 2009 by Michael Fischer. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the author nor the names of its contributors may
|
||||
* be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************
|
||||
* History:
|
||||
*
|
||||
* 28.03.09 mifi First Version, based on the original syscall.c from
|
||||
* newlib version 1.17.0
|
||||
* 17.08.09 gdisirio Modified the file for use under ChibiOS/RT
|
||||
* 15.11.09 gdisirio Added read and write handling
|
||||
****************************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
@ -68,8 +68,7 @@
|
|||
/***************************************************************************/
|
||||
|
||||
__attribute__((used))
|
||||
int _read_r(struct _reent *r, int file, char * ptr, int len)
|
||||
{
|
||||
int _read_r(struct _reent *r, int file, char * ptr, int len) {
|
||||
(void)r;
|
||||
#if defined(STDIN_SD)
|
||||
if (!len || (file != 0)) {
|
||||
|
@ -82,7 +81,7 @@ int _read_r(struct _reent *r, int file, char * ptr, int len)
|
|||
(void)file;
|
||||
(void)ptr;
|
||||
(void)len;
|
||||
__errno_r(r) = EINVAL;
|
||||
__errno_r(r) = EINVAL;
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
@ -90,8 +89,7 @@ int _read_r(struct _reent *r, int file, char * ptr, int len)
|
|||
/***************************************************************************/
|
||||
|
||||
__attribute__((used))
|
||||
int _lseek_r(struct _reent *r, int file, int ptr, int dir)
|
||||
{
|
||||
int _lseek_r(struct _reent *r, int file, int ptr, int dir) {
|
||||
(void)r;
|
||||
(void)file;
|
||||
(void)ptr;
|
||||
|
@ -103,8 +101,7 @@ int _lseek_r(struct _reent *r, int file, int ptr, int dir)
|
|||
/***************************************************************************/
|
||||
|
||||
__attribute__((used))
|
||||
int _write_r(struct _reent *r, int file, char * ptr, int len)
|
||||
{
|
||||
int _write_r(struct _reent *r, int file, char * ptr, int len) {
|
||||
(void)r;
|
||||
(void)file;
|
||||
(void)ptr;
|
||||
|
@ -121,8 +118,7 @@ int _write_r(struct _reent *r, int file, char * ptr, int len)
|
|||
/***************************************************************************/
|
||||
|
||||
__attribute__((used))
|
||||
int _close_r(struct _reent *r, int file)
|
||||
{
|
||||
int _close_r(struct _reent *r, int file) {
|
||||
(void)r;
|
||||
(void)file;
|
||||
|
||||
|
@ -132,16 +128,15 @@ int _close_r(struct _reent *r, int file)
|
|||
/***************************************************************************/
|
||||
|
||||
__attribute__((used))
|
||||
caddr_t _sbrk_r(struct _reent *r, int incr)
|
||||
{
|
||||
caddr_t _sbrk_r(struct _reent *r, int incr) {
|
||||
#if CH_CFG_USE_MEMCORE
|
||||
void *p;
|
||||
|
||||
chDbgCheck(incr >= 0);
|
||||
|
||||
p = chCoreAlloc((size_t)incr);
|
||||
p = chCoreAllocFromBase((size_t)incr, 1U, 0U);
|
||||
if (p == NULL) {
|
||||
__errno_r(r) = ENOMEM;
|
||||
__errno_r(r) = ENOMEM;
|
||||
return (caddr_t)-1;
|
||||
}
|
||||
return (caddr_t)p;
|
||||
|
@ -155,8 +150,7 @@ caddr_t _sbrk_r(struct _reent *r, int incr)
|
|||
/***************************************************************************/
|
||||
|
||||
__attribute__((used))
|
||||
int _fstat_r(struct _reent *r, int file, struct stat * st)
|
||||
{
|
||||
int _fstat_r(struct _reent *r, int file, struct stat * st) {
|
||||
(void)r;
|
||||
(void)file;
|
||||
|
||||
|
@ -168,8 +162,7 @@ int _fstat_r(struct _reent *r, int file, struct stat * st)
|
|||
/***************************************************************************/
|
||||
|
||||
__attribute__((used))
|
||||
int _isatty_r(struct _reent *r, int fd)
|
||||
{
|
||||
int _isatty_r(struct _reent *r, int fd) {
|
||||
(void)r;
|
||||
(void)fd;
|
||||
|
||||
|
|
|
@ -74,6 +74,14 @@
|
|||
*****************************************************************************
|
||||
|
||||
*** Next ***
|
||||
- VAR: Modified syscalls.c to allocate memory from bottom upward, ChibiOS
|
||||
allocators take memory from top downward. This way the memory taken
|
||||
using _sbrk_r() does not contain "holes" caused by other allocators.
|
||||
- LIB: Modified core allocator to be able to get blocks starting from bottom
|
||||
or top of the available memory range.
|
||||
Removed alignment enforcements for requested block size. Alignment is
|
||||
only ensured on the returned pointer, this should reduce memory usage
|
||||
is some cases.
|
||||
- HAL: Added mcuconf.h updater tool for STM32F407 (backported to 19.1.1).
|
||||
- NIL: Integrated NIL 4.0.
|
||||
- FIX: Fixed wrong mcuconf.h in some testex demos related to STM32F407
|
||||
|
|
Loading…
Reference in New Issue