diff options
author | Gregory Nutt <gnutt@nuttx.org> | 2014-08-23 12:43:21 -0600 |
---|---|---|
committer | Gregory Nutt <gnutt@nuttx.org> | 2014-08-23 12:43:21 -0600 |
commit | 32f7202819eba7bfb6451764eda7e46483fd2d08 (patch) | |
tree | 47685b2d6105fe7e8857863575d4cd4a99c909d2 /nuttx/mm | |
parent | 0b22d58560f5854ddde7a35e61ef615e59945081 (diff) | |
download | px4-nuttx-32f7202819eba7bfb6451764eda7e46483fd2d08.tar.gz px4-nuttx-32f7202819eba7bfb6451764eda7e46483fd2d08.tar.bz2 px4-nuttx-32f7202819eba7bfb6451764eda7e46483fd2d08.zip |
gran_reserve(): Add a new function to reserve unallocatable regions in the granule heap
Diffstat (limited to 'nuttx/mm')
-rw-r--r-- | nuttx/mm/Makefile | 3 | ||||
-rw-r--r-- | nuttx/mm/mm_gran.h | 21 | ||||
-rw-r--r-- | nuttx/mm/mm_granalloc.c | 70 | ||||
-rw-r--r-- | nuttx/mm/mm_granmark.c | 132 | ||||
-rw-r--r-- | nuttx/mm/mm_granreserve.c | 144 |
5 files changed, 299 insertions, 71 deletions
diff --git a/nuttx/mm/Makefile b/nuttx/mm/Makefile index d1d0204a1..56b1157d2 100644 --- a/nuttx/mm/Makefile +++ b/nuttx/mm/Makefile @@ -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 diff --git a/nuttx/mm/mm_gran.h b/nuttx/mm/mm_gran.h index 2dd1aef36..657aa68b6 100644 --- a/nuttx/mm/mm_gran.h +++ b/nuttx/mm/mm_gran.h @@ -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 */ diff --git a/nuttx/mm/mm_granalloc.c b/nuttx/mm/mm_granalloc.c index f92e44ef0..71647f954 100644 --- a/nuttx/mm/mm_granalloc.c +++ b/nuttx/mm/mm_granalloc.c @@ -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 * diff --git a/nuttx/mm/mm_granmark.c b/nuttx/mm/mm_granmark.c new file mode 100644 index 000000000..a2c9e9054 --- /dev/null +++ b/nuttx/mm/mm_granmark.c @@ -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 */ diff --git a/nuttx/mm/mm_granreserve.c b/nuttx/mm/mm_granreserve.c new file mode 100644 index 000000000..e336a228b --- /dev/null +++ b/nuttx/mm/mm_granreserve.c @@ -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 */ |