gran_reserve(): Add a new function to reserve unallocatable regions in the granule heap

This commit is contained in:
Gregory Nutt 2014-08-23 12:43:21 -06:00
parent 3bd810b316
commit 7cd8db9425
7 changed files with 340 additions and 83 deletions

View File

@ -52,12 +52,13 @@ fi
# the CodeSourcery toolchain in any other location
#export TOOLCHAIN_BIN="/cygdrive/c/Program Files (x86)/CodeSourcery/Sourcery G++ Lite/bin"
export TOOLCHAIN_BIN="/cygdrive/c/Program Files (x86)/CodeSourcery/Sourcery_CodeBench_Lite_for_ARM_EABI/bin"
#export TOOLCHAIN_BIN="/cygdrive/c/Users/MyName/MentorGraphics/Sourcery_CodeBench_Lite_for_ARM_EABI/bin"
# This the Cygwin path to the location where I build the buildroot
# toolchain.
#export TOOLCHAIN_BIN="${WD}/../misc/buildroot/build_arm_nofpu/staging_dir/bin"
# Add the path to the toolchain to the PATH varialble
#export PATH="${TOOLCHAIN_BIN}:/sbin:/usr/sbin:${PATH_ORIG}"
export PATH="${TOOLCHAIN_BIN}:/sbin:/usr/sbin:${PATH_ORIG}"
echo "PATH : ${PATH}"

View File

@ -2,7 +2,7 @@
* include/nuttx/gran.h
* General purpose granule memory allocator.
*
* Copyright (C) 2012 Gregory Nutt. All rights reserved.
* Copyright (C) 2012, 2014 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -134,16 +134,44 @@ extern "C" {
*
* Returned Value:
* On success, a non-NULL handle is returned that may be used with other
* granual allocator interfaces.
* granule allocator interfaces.
*
****************************************************************************/
#ifdef CONFIG_GRAN_SINGLE
EXTERN int gran_initialize(FAR void *heapstart, size_t heapsize,
uint8_t log2gran, uint8_t log2align);
int gran_initialize(FAR void *heapstart, size_t heapsize, uint8_t log2gran,
uint8_t log2align);
#else
EXTERN GRAN_HANDLE gran_initialize(FAR void *heapstart, size_t heapsize,
uint8_t log2gran, uint8_t log2align);
GRAN_HANDLE gran_initialize(FAR void *heapstart, size_t heapsize,
uint8_t log2gran, uint8_t log2align);
#endif
/****************************************************************************
* Name: gran_reserve
*
* Description:
* Reserve memory in the granule heap. This will reserve the granules
* that contain the start and end addresses plus all of the granules
* in between. This should be done early in the initialization sequence
* before any other allocations are made.
*
* Reserved memory can never be allocated (it can be freed however which
* essentially unreserves the memory).
*
* Input Parameters:
* handle - The handle previously returned by gran_initialize
* start - The address of the beginning of the region to be reserved.
* size - The size of the region to be reserved
*
* Returned Value:
* None
*
****************************************************************************/
#ifdef CONFIG_GRAN_SINGLE
void gran_reserve(uintptr_t start, size_t size);
#else
void gran_reserve(GRAN_HANDLE handle, uintptr_t start, size_t size);
#endif
/****************************************************************************
@ -167,9 +195,9 @@ EXTERN GRAN_HANDLE gran_initialize(FAR void *heapstart, size_t heapsize,
****************************************************************************/
#ifdef CONFIG_GRAN_SINGLE
EXTERN FAR void *gran_alloc(size_t size);
FAR void *gran_alloc(size_t size);
#else
EXTERN FAR void *gran_alloc(GRAN_HANDLE handle, size_t size);
FAR void *gran_alloc(GRAN_HANDLE handle, size_t size);
#endif
/****************************************************************************
@ -180,7 +208,7 @@ EXTERN FAR void *gran_alloc(GRAN_HANDLE handle, size_t size);
*
* Input Parameters:
* handle - The handle previously returned by gran_initialize
* memory - A pointer to memory previoiusly allocated by gran_alloc.
* memory - A pointer to memory previously allocated by gran_alloc.
*
* Returned Value:
* None
@ -188,9 +216,9 @@ EXTERN FAR void *gran_alloc(GRAN_HANDLE handle, size_t size);
****************************************************************************/
#ifdef CONFIG_GRAN_SINGLE
EXTERN void gran_free(FAR void *memory, size_t size);
void gran_free(FAR void *memory, size_t size);
#else
EXTERN void gran_free(GRAN_HANDLE handle, FAR void *memory, size_t size);
void gran_free(GRAN_HANDLE handle, FAR void *memory, size_t size);
#endif
#undef EXTERN

View File

@ -67,7 +67,8 @@ endif
# An optional granule allocator
ifeq ($(CONFIG_GRAN),y)
CSRCS += mm_graninit.c mm_granalloc.c mm_granfree.c mm_grancritical.c
CSRCS += mm_graninit.c mm_granreserve.c mm_granalloc.c mm_granmark.c
CSRCS += mm_granfree.c mm_grancritical.c
endif
BINDIR ?= bin

View File

@ -83,7 +83,7 @@
* Public Types
****************************************************************************/
/* This structure represents the state of on granual allocation */
/* This structure represents the state of on granule allocation */
struct gran_s
{
@ -129,4 +129,23 @@ extern FAR struct gran_s *g_graninfo;
void gran_enter_critical(FAR struct gran_s *priv);
void gran_leave_critical(FAR struct gran_s *priv);
/****************************************************************************
* Name: gran_mark_allocated
*
* Description:
* Mark a range of granules as allocated.
*
* Input Parameters:
* priv - The granule heap state structure.
* alloc - The address of the allocation.
* ngranules - The number of granules allocated
*
* Returned Value:
* None
*
****************************************************************************/
void gran_mark_allocated(FAR struct gran_s *priv, uintptr_t alloc,
unsigned int ngranules);
#endif /* __MM_MM_GRAN_H */

View File

@ -52,77 +52,9 @@
****************************************************************************/
/****************************************************************************
* Name: gran_common_alloc
*
* Description:
* Allocate memory from the granule heap.
*
* Input Parameters:
* priv - The granule heap state structure.
* alloc - The adress of the allocation.
* ngranules - The number of granules allocated
*
* Returned Value:
* None
*
* Private Functions
****************************************************************************/
static inline void gran_mark_allocated(FAR struct gran_s *priv,
uintptr_t alloc,
unsigned int ngranules)
{
unsigned int granno;
unsigned int gatidx;
unsigned int gatbit;
unsigned int avail;
uint32_t gatmask;
/* Determine the granule number of the allocation */
granno = (alloc - priv->heapstart) >> priv->log2gran;
/* Determine the GAT table index associated with the allocation */
gatidx = granno >> 5;
gatbit = granno & 31;
/* Mark bits in the GAT entry or entries */
avail = 32 - gatbit;
if (ngranules > avail)
{
/* Mark bits in the first GAT entry */
gatmask =0xffffffff << gatbit;
DEBUGASSERT((priv->gat[gatidx] & gatmask) == 0);
priv->gat[gatidx] |= gatmask;
ngranules -= avail;
/* Mark bits in the second GAT entry */
gatmask = 0xffffffff >> (32 - ngranules);
DEBUGASSERT((priv->gat[gatidx+1] & gatmask) == 0);
priv->gat[gatidx+1] |= gatmask;
}
/* Handle the case where where all of the granules come from one entry */
else
{
/* Mark bits in a single GAT entry */
gatmask = 0xffffffff >> (32 - ngranules);
gatmask <<= gatbit;
DEBUGASSERT((priv->gat[gatidx] & gatmask) == 0);
priv->gat[gatidx] |= gatmask;
return;
}
}
/****************************************************************************
* Name: gran_common_alloc
*

132
mm/mm_granmark.c Normal file
View File

@ -0,0 +1,132 @@
/****************************************************************************
* mm/mm_granmark.c
*
* Copyright (C) 2012, 2014 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* 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 NuttX 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.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <assert.h>
#include <nuttx/gran.h>
#include "mm_gran.h"
#ifdef CONFIG_GRAN
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: gran_mark_allocated
*
* Description:
* Mark a range of granules as allocated.
*
* Input Parameters:
* priv - The granule heap state structure.
* alloc - The address of the allocation.
* ngranules - The number of granules allocated
*
* Returned Value:
* None
*
****************************************************************************/
void gran_mark_allocated(FAR struct gran_s *priv, uintptr_t alloc,
unsigned int ngranules)
{
unsigned int granno;
unsigned int gatidx;
unsigned int gatbit;
unsigned int avail;
uint32_t gatmask;
/* Determine the granule number of the allocation */
granno = (alloc - priv->heapstart) >> priv->log2gran;
/* Determine the GAT table index associated with the allocation */
gatidx = granno >> 5;
gatbit = granno & 31;
/* Mark bits in the GAT entry or entries */
avail = 32 - gatbit;
if (ngranules > avail)
{
/* Mark bits in the first GAT entry */
gatmask =0xffffffff << gatbit;
DEBUGASSERT((priv->gat[gatidx] & gatmask) == 0);
priv->gat[gatidx] |= gatmask;
ngranules -= avail;
/* Mark bits in the second GAT entry */
gatmask = 0xffffffff >> (32 - ngranules);
DEBUGASSERT((priv->gat[gatidx+1] & gatmask) == 0);
priv->gat[gatidx+1] |= gatmask;
}
/* Handle the case where where all of the granules come from one entry */
else
{
/* Mark bits in a single GAT entry */
gatmask = 0xffffffff >> (32 - ngranules);
gatmask <<= gatbit;
DEBUGASSERT((priv->gat[gatidx] & gatmask) == 0);
priv->gat[gatidx] |= gatmask;
return;
}
}
#endif /* CONFIG_GRAN */

144
mm/mm_granreserve.c Normal file
View File

@ -0,0 +1,144 @@
/****************************************************************************
* mm/mm_granreserve.c
*
* Copyright (C) 2014 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* 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 NuttX 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.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <assert.h>
#include <nuttx/gran.h>
#include "mm_gran.h"
#ifdef CONFIG_GRAN
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: gran_common_reserve
*
* Description:
* Reserve memory in the granule heap. This will reserve the granules
* that contain the start and end addresses plus all of the granules
* in between. This should be done early in the initialization sequence
* before any other allocations are made.
*
* Reserved memory can never be allocated (it can be freed however which
* essentially unreserves the memory).
*
* Input Parameters:
* priv - The granule heap state structure.
* start - The address of the beginning of the region to be reserved.
* size - The size of the region to be reserved
*
* Returned Value:
* None
*
****************************************************************************/
static inline void gran_common_reserve(FAR struct gran_s *priv,
uintptr_t start, size_t size)
{
if (size > 0)
{
uintptr_t mask = (1 << priv->log2gran) - 1;
uintptr_t end = start + size - 1;
unsigned int ngranules;
/* Get the aligned (down) start address and the aligned (up) end
* address
*/
start &= ~mask;
end = (end + mask) & ~mask;
/* Calculate the new size in granuales */
ngranules = ((end - start) >> priv->log2gran) + 1;
/* And reserve the granules */
gran_mark_allocated(priv, start, ngranules);
}
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: gran_reserve
*
* Description:
* Reserve memory in the granule heap. This will reserve the granules
* that contain the start and end addresses plus all of the granules
* in between. This should be done early in the initialization sequence
* before any other allocations are made.
*
* Reserved memory can never be allocated (it can be freed however which
* essentially unreserves the memory).
*
* Input Parameters:
* handle - The handle previously returned by gran_initialize
* start - The address of the beginning of the region to be reserved.
* size - The size of the region to be reserved
*
* Returned Value:
* None
*
****************************************************************************/
#ifdef CONFIG_GRAN_SINGLE
void gran_reserve(uintptr_t start, size_t size)
{
return gran_common_reserve(g_graninfo, start, size);
}
#else
void gran_reserve(GRAN_HANDLE handle, uintptr_t start, size_t size)
{
return gran_common_reserve((FAR struct gran_s *)handle, start, size);
}
#endif
#endif /* CONFIG_GRAN */