mirror of
https://github.com/apache/nuttx.git
synced 2026-06-05 15:58:59 +08:00
mm/mm_gran: remove allocation size limitation
This patch refactors granule allocator to remove the 32 granules limitation with the help of a gran_range_s structure and related functions, see "mm_grantable.h" for details. Below are the major functions explaining how this works: - The gran_match() checks if a gran range all in the given state. it gives last mismatch position when fails free range matching. - The gran_search() tries to find the position of a free range. It leverages last mismatch position from gran_match() to speed up the search. range size handling is mainly in gran_match() and gran_set_(). Signed-off-by: Yanfeng Liu <yfliu2008@qq.com>
This commit is contained in:
committed by
Alan Carvalho de Assis
parent
db7c8be61f
commit
102a62c7e3
@@ -22,15 +22,9 @@
|
|||||||
|
|
||||||
if(CONFIG_GRAN)
|
if(CONFIG_GRAN)
|
||||||
|
|
||||||
set(SRCS
|
set(SRCS mm_graninit.c mm_granrelease.c mm_graninfo.c mm_grancritical.c)
|
||||||
mm_graninit.c
|
list(APPEND SRCS mm_grantable.c mm_granfree.c mm_granalloc.c)
|
||||||
mm_granrelease.c
|
list(APPEND SRCS mm_granreserve.c)
|
||||||
mm_granreserve.c
|
|
||||||
mm_granalloc.c
|
|
||||||
mm_granmark.c
|
|
||||||
mm_granfree.c
|
|
||||||
mm_graninfo.c
|
|
||||||
mm_grancritical.c)
|
|
||||||
|
|
||||||
# A page allocator based on the granule allocator
|
# A page allocator based on the granule allocator
|
||||||
|
|
||||||
|
|||||||
@@ -21,8 +21,9 @@
|
|||||||
# An optional granule allocator
|
# An optional granule allocator
|
||||||
|
|
||||||
ifeq ($(CONFIG_GRAN),y)
|
ifeq ($(CONFIG_GRAN),y)
|
||||||
CSRCS += mm_graninit.c mm_granrelease.c mm_granreserve.c mm_granalloc.c
|
|
||||||
CSRCS += mm_granmark.c mm_granfree.c mm_graninfo.c mm_grancritical.c
|
CSRCS += mm_graninit.c mm_granrelease.c mm_graninfo.c mm_grancritical.c
|
||||||
|
CSRCS += mm_grantable.c mm_granfree.c mm_granalloc.c mm_granreserve.c
|
||||||
|
|
||||||
# A page allocator based on the granule allocator
|
# A page allocator based on the granule allocator
|
||||||
|
|
||||||
|
|||||||
@@ -47,7 +47,7 @@
|
|||||||
|
|
||||||
/* Debug */
|
/* Debug */
|
||||||
|
|
||||||
#ifdef CONFIG_DEBUG_GRAM
|
#ifdef CONFIG_DEBUG_GRAN
|
||||||
# define granerr _err
|
# define granerr _err
|
||||||
# define granwarn _warn
|
# define granwarn _warn
|
||||||
# define graninfo _info
|
# define graninfo _info
|
||||||
|
|||||||
+35
-203
@@ -25,10 +25,12 @@
|
|||||||
#include <nuttx/config.h>
|
#include <nuttx/config.h>
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
#include <nuttx/mm/gran.h>
|
#include <nuttx/mm/gran.h>
|
||||||
|
|
||||||
#include "mm_gran/mm_gran.h"
|
#include "mm_gran/mm_gran.h"
|
||||||
|
#include "mm_gran/mm_grantable.h"
|
||||||
|
|
||||||
#ifdef CONFIG_GRAN
|
#ifdef CONFIG_GRAN
|
||||||
|
|
||||||
@@ -36,215 +38,45 @@
|
|||||||
* Public Functions
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Name: gran_alloc
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* Allocate memory from the granule heap.
|
|
||||||
*
|
|
||||||
* NOTE: The current implementation also restricts the maximum allocation
|
|
||||||
* size to 32 granules. That restriction could be eliminated with some
|
|
||||||
* additional coding effort.
|
|
||||||
*
|
|
||||||
* Input Parameters:
|
|
||||||
* handle - The handle previously returned by gran_initialize
|
|
||||||
* size - The size of the memory region to allocate.
|
|
||||||
*
|
|
||||||
* Returned Value:
|
|
||||||
* On success, a non-NULL pointer to the allocated memory is returned;
|
|
||||||
* NULL is returned on failure.
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
FAR void *gran_alloc(GRAN_HANDLE handle, size_t size)
|
FAR void *gran_alloc(GRAN_HANDLE handle, size_t size)
|
||||||
{
|
{
|
||||||
FAR struct gran_s *priv = (FAR struct gran_s *)handle;
|
FAR gran_t *gran = (FAR gran_t *)handle;
|
||||||
unsigned int ngranules;
|
size_t ngran;
|
||||||
size_t tmpmask;
|
int posi;
|
||||||
uintptr_t alloc;
|
int ret;
|
||||||
uint32_t curr;
|
uintptr_t retp;
|
||||||
uint32_t next;
|
|
||||||
uint32_t mask;
|
|
||||||
int granidx;
|
|
||||||
int gatidx;
|
|
||||||
int bitidx;
|
|
||||||
int shift;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
DEBUGASSERT(priv != NULL && size <= 32 * (1 << priv->log2gran));
|
DEBUGASSERT(gran);
|
||||||
|
ngran = NGRANULE(gran, size);
|
||||||
if (priv != NULL && size > 0)
|
if (!ngran || ngran > gran->ngranules)
|
||||||
{
|
{
|
||||||
/* Get exclusive access to the GAT */
|
return NULL;
|
||||||
|
|
||||||
ret = gran_enter_critical(priv);
|
|
||||||
if (ret < 0)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* How many contiguous granules we we need to find? */
|
|
||||||
|
|
||||||
tmpmask = (1 << priv->log2gran) - 1;
|
|
||||||
ngranules = (size + tmpmask) >> priv->log2gran;
|
|
||||||
|
|
||||||
/* Then create mask for that number of granules */
|
|
||||||
|
|
||||||
DEBUGASSERT(ngranules <= 32);
|
|
||||||
mask = 0xffffffff >> (32 - ngranules);
|
|
||||||
|
|
||||||
/* Now search the granule allocation table for that number
|
|
||||||
* of contiguous
|
|
||||||
*/
|
|
||||||
|
|
||||||
for (granidx = 0; granidx < priv->ngranules; granidx += 32)
|
|
||||||
{
|
|
||||||
/* Get the GAT index associated with the granule table entry */
|
|
||||||
|
|
||||||
gatidx = granidx >> 5;
|
|
||||||
curr = priv->gat[gatidx];
|
|
||||||
|
|
||||||
/* Handle the case where there are no free granules in the entry */
|
|
||||||
|
|
||||||
if (curr == 0xffffffff)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the next entry from the GAT to support a 64 bit shift */
|
|
||||||
|
|
||||||
if (granidx + 32 < priv->ngranules)
|
|
||||||
{
|
|
||||||
next = priv->gat[gatidx + 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Use all ones when are at the last entry in the GAT (meaning
|
|
||||||
* nothing can be allocated.
|
|
||||||
*/
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
next = 0xffffffff;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Search through the allocations in the 'curr' GAT entry
|
|
||||||
* to see if we can satisfy the allocation starting in that
|
|
||||||
* entry.
|
|
||||||
*
|
|
||||||
* This loop continues until either all of the bits have been
|
|
||||||
* examined (bitidx >= 32), or until there are insufficient
|
|
||||||
* granules left to satisfy the allocation.
|
|
||||||
*/
|
|
||||||
|
|
||||||
alloc = priv->heapstart + (granidx << priv->log2gran);
|
|
||||||
|
|
||||||
for (bitidx = 0;
|
|
||||||
bitidx < 32 &&
|
|
||||||
(granidx + bitidx + ngranules) <= priv->ngranules;
|
|
||||||
)
|
|
||||||
{
|
|
||||||
/* Break out if there are no further free bits in 'curr'.
|
|
||||||
* All of the zero bits might have gotten shifted out.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (curr == 0xffffffff)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check for the first zero bit in the lower or upper 16-bits.
|
|
||||||
* From the test above, we know that at least one of the 32-
|
|
||||||
* bits in 'curr' is zero.
|
|
||||||
*/
|
|
||||||
|
|
||||||
else if ((curr & 0x0000ffff) == 0x0000ffff)
|
|
||||||
{
|
|
||||||
/* Not in the lower 16 bits. The first free bit must be
|
|
||||||
* in the upper 16 bits.
|
|
||||||
*/
|
|
||||||
|
|
||||||
shift = 16;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We know that the first free bit is now within the lower 16
|
|
||||||
* bits of 'curr'. Is it in the upper or lower byte?
|
|
||||||
*/
|
|
||||||
|
|
||||||
else if ((curr & 0x0000ff) == 0x000000ff)
|
|
||||||
{
|
|
||||||
/* Not in the lower 8 bits. The first free bit must be in
|
|
||||||
* the upper 8 bits.
|
|
||||||
*/
|
|
||||||
|
|
||||||
shift = 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We know that the first free bit is now within the lower 4
|
|
||||||
* bits of 'curr'. Is it in the upper or lower nibble?
|
|
||||||
*/
|
|
||||||
|
|
||||||
else if ((curr & 0x00000f) == 0x0000000f)
|
|
||||||
{
|
|
||||||
/* Not in the lower 4 bits. The first free bit must be in
|
|
||||||
* the upper 4 bits.
|
|
||||||
*/
|
|
||||||
|
|
||||||
shift = 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We know that the first free bit is now within the lower 4
|
|
||||||
* bits of 'curr'. Is it in the upper or lower pair?
|
|
||||||
*/
|
|
||||||
|
|
||||||
else if ((curr & 0x000003) == 0x00000003)
|
|
||||||
{
|
|
||||||
/* Not in the lower 2 bits. The first free bit must be in
|
|
||||||
* the upper 2 bits.
|
|
||||||
*/
|
|
||||||
|
|
||||||
shift = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We know that the first free bit is now within the lower 4
|
|
||||||
* bits of 'curr'. Check if we have the allocation at this
|
|
||||||
* bit position.
|
|
||||||
*/
|
|
||||||
|
|
||||||
else if ((curr & mask) == 0)
|
|
||||||
{
|
|
||||||
/* Yes.. mark these granules allocated */
|
|
||||||
|
|
||||||
gran_mark_allocated(priv, alloc, ngranules);
|
|
||||||
|
|
||||||
/* And return the allocation address */
|
|
||||||
|
|
||||||
gran_leave_critical(priv);
|
|
||||||
return (FAR void *)alloc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The free allocation does not start at this position */
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
shift = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set up for the next time through the loop. Perform a 64
|
|
||||||
* bit shift to move to the next gran position and increment
|
|
||||||
* to the next candidate allocation address.
|
|
||||||
*/
|
|
||||||
|
|
||||||
alloc += (shift << priv->log2gran);
|
|
||||||
curr = (curr >> shift) | (next << (32 - shift));
|
|
||||||
next >>= shift;
|
|
||||||
bitidx += shift;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
gran_leave_critical(priv);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
ret = gran_enter_critical(gran);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
posi = gran_search(gran, ngran);
|
||||||
|
if (posi >= 0)
|
||||||
|
{
|
||||||
|
gran_set(gran, posi, ngran);
|
||||||
|
}
|
||||||
|
|
||||||
|
gran_leave_critical(gran);
|
||||||
|
if (posi < 0)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
retp = gran->heapstart + (posi << gran->log2gran);
|
||||||
|
graninfo("heap=%"PRIxPTR" posi=%d retp=%"PRIxPTR" size=%zu n=%zu\n",
|
||||||
|
gran->heapstart, posi, retp, size, ngran);
|
||||||
|
DEBUGASSERT(retp >= gran->heapstart);
|
||||||
|
DEBUGASSERT(retp < gran->heapstart + GRANBYTE(gran));
|
||||||
|
return (FAR void *)retp;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_GRAN */
|
#endif /* CONFIG_GRAN */
|
||||||
|
|||||||
+20
-84
@@ -25,11 +25,12 @@
|
|||||||
#include <nuttx/config.h>
|
#include <nuttx/config.h>
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <errno.h>
|
#include <debug.h>
|
||||||
|
|
||||||
#include <nuttx/mm/gran.h>
|
#include <nuttx/mm/gran.h>
|
||||||
|
|
||||||
#include "mm_gran/mm_gran.h"
|
#include "mm_gran/mm_gran.h"
|
||||||
|
#include "mm_gran/mm_grantable.h"
|
||||||
|
|
||||||
#ifdef CONFIG_GRAN
|
#ifdef CONFIG_GRAN
|
||||||
|
|
||||||
@@ -37,100 +38,35 @@
|
|||||||
* Public Functions
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Name: gran_free
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* Return memory to the granule heap.
|
|
||||||
*
|
|
||||||
* Input Parameters:
|
|
||||||
* handle - The handle previously returned by gran_initialize
|
|
||||||
* memory - A pointer to memory previoiusly allocated by gran_alloc.
|
|
||||||
*
|
|
||||||
* Returned Value:
|
|
||||||
* None
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
void gran_free(GRAN_HANDLE handle, FAR void *memory, size_t size)
|
void gran_free(GRAN_HANDLE handle, FAR void *memory, size_t size)
|
||||||
{
|
{
|
||||||
FAR struct gran_s *priv = (FAR struct gran_s *)handle;
|
FAR gran_t *gran = (FAR gran_t *)handle;
|
||||||
unsigned int granno;
|
uint ngran;
|
||||||
unsigned int gatidx;
|
size_t posi;
|
||||||
unsigned int gatbit;
|
int ret;
|
||||||
unsigned int granmask;
|
|
||||||
unsigned int ngranules;
|
|
||||||
unsigned int avail;
|
|
||||||
uint32_t gatmask;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
DEBUGASSERT(priv != NULL && memory && size <= 32 * (1 << priv->log2gran));
|
DEBUGASSERT(gran && memory && size);
|
||||||
|
DEBUGASSERT(GRAN_PRODUCT(gran, memory));
|
||||||
|
DEBUGASSERT(GRAN_INRANGE(gran, (((uintptr_t)memory) + size - 1)));
|
||||||
|
|
||||||
/* Get exclusive access to the GAT */
|
posi = MEM2GRAN(gran, memory);
|
||||||
|
ngran = NGRANULE(gran, size);
|
||||||
|
|
||||||
|
graninfo(" heap=%"PRIxPTR" posi=%zu addr=%zx size=%zu n=%d\n",
|
||||||
|
gran->heapstart, posi, (size_t)memory, size, ngran);
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
ret = gran_enter_critical(priv);
|
ret = gran_enter_critical(gran);
|
||||||
|
|
||||||
/* The only error Should happen on task cancellation. We must
|
|
||||||
* try again in this case to avoid stranding the granule memory.
|
|
||||||
*/
|
|
||||||
|
|
||||||
DEBUGASSERT(ret == OK || ret == -ECANCELED);
|
DEBUGASSERT(ret == OK || ret == -ECANCELED);
|
||||||
}
|
}
|
||||||
while (ret < 0);
|
while (ret < 0); /* Retry upon task cancellation */
|
||||||
|
|
||||||
/* Determine the granule number of the first granule in the allocation */
|
/* check double free */
|
||||||
|
|
||||||
granno = ((uintptr_t)memory - priv->heapstart) >> priv->log2gran;
|
DEBUGASSERT(gran_match(gran, posi, ngran, 1, NULL));
|
||||||
|
gran_clear(gran, posi, ngran);
|
||||||
/* Determine the GAT table index and bit number associated with the
|
gran_leave_critical(gran);
|
||||||
* allocation.
|
|
||||||
*/
|
|
||||||
|
|
||||||
gatidx = granno >> 5;
|
|
||||||
gatbit = granno & 31;
|
|
||||||
|
|
||||||
/* Determine the number of granules in the allocation */
|
|
||||||
|
|
||||||
granmask = (1 << priv->log2gran) - 1;
|
|
||||||
ngranules = (size + granmask) >> priv->log2gran;
|
|
||||||
|
|
||||||
/* Clear bits in the GAT entry or entries */
|
|
||||||
|
|
||||||
avail = 32 - gatbit;
|
|
||||||
if (ngranules > avail)
|
|
||||||
{
|
|
||||||
/* Clear bits in the first GAT entry */
|
|
||||||
|
|
||||||
gatmask = (0xffffffff << gatbit);
|
|
||||||
DEBUGASSERT((priv->gat[gatidx] & gatmask) == gatmask);
|
|
||||||
|
|
||||||
priv->gat[gatidx] &= ~gatmask;
|
|
||||||
ngranules -= avail;
|
|
||||||
|
|
||||||
/* Clear bits in the second GAT entry */
|
|
||||||
|
|
||||||
gatmask = 0xffffffff >> (32 - ngranules);
|
|
||||||
DEBUGASSERT((priv->gat[gatidx + 1] & gatmask) == gatmask);
|
|
||||||
|
|
||||||
priv->gat[gatidx + 1] &= ~gatmask;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Handle the case where where all of the granules came from one entry */
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Clear bits in a single GAT entry */
|
|
||||||
|
|
||||||
gatmask = 0xffffffff >> (32 - ngranules);
|
|
||||||
gatmask <<= gatbit;
|
|
||||||
DEBUGASSERT((priv->gat[gatidx] & gatmask) == gatmask);
|
|
||||||
|
|
||||||
priv->gat[gatidx] &= ~gatmask;
|
|
||||||
}
|
|
||||||
|
|
||||||
gran_leave_critical(priv);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_GRAN */
|
#endif /* CONFIG_GRAN */
|
||||||
|
|||||||
@@ -1,121 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* mm/mm_gran/mm_granmark.c
|
|
||||||
*
|
|
||||||
* 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 <nuttx/config.h>
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
#include <nuttx/mm/gran.h>
|
|
||||||
|
|
||||||
#include "mm_gran/mm_gran.h"
|
|
||||||
|
|
||||||
#ifdef CONFIG_GRAN
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* 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:
|
|
||||||
* On success, a non-NULL pointer to the allocated memory is returned;
|
|
||||||
* NULL is returned on failure.
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
FAR 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)
|
|
||||||
{
|
|
||||||
uint32_t gatmask2;
|
|
||||||
|
|
||||||
gatmask = 0xffffffff << gatbit;
|
|
||||||
ngranules -= avail;
|
|
||||||
gatmask2 = 0xffffffff >> (32 - ngranules);
|
|
||||||
|
|
||||||
/* Check that the area is free, from both mask words */
|
|
||||||
|
|
||||||
if (((priv->gat[gatidx] & gatmask) != 0) ||
|
|
||||||
((priv->gat[gatidx + 1] & gatmask2) != 0))
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Mark bits in the first and second GAT entry */
|
|
||||||
|
|
||||||
priv->gat[gatidx] |= gatmask;
|
|
||||||
priv->gat[gatidx + 1] |= gatmask2;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Handle the case where where all of the granules come from one entry */
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
gatmask = 0xffffffff >> (32 - ngranules);
|
|
||||||
gatmask <<= gatbit;
|
|
||||||
|
|
||||||
/* Check that the area is free */
|
|
||||||
|
|
||||||
if ((priv->gat[gatidx] & gatmask) != 0)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Mark bits in a single GAT entry */
|
|
||||||
|
|
||||||
priv->gat[gatidx] |= gatmask;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (FAR void *)alloc;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* CONFIG_GRAN */
|
|
||||||
+48
-55
@@ -25,10 +25,12 @@
|
|||||||
#include <nuttx/config.h>
|
#include <nuttx/config.h>
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
#include <nuttx/mm/gran.h>
|
#include <nuttx/mm/gran.h>
|
||||||
|
|
||||||
#include "mm_gran/mm_gran.h"
|
#include "mm_gran/mm_gran.h"
|
||||||
|
#include "mm_gran/mm_grantable.h"
|
||||||
|
|
||||||
#ifdef CONFIG_GRAN
|
#ifdef CONFIG_GRAN
|
||||||
|
|
||||||
@@ -36,67 +38,58 @@
|
|||||||
* Public Functions
|
* 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:
|
|
||||||
* On success, a non-NULL pointer to the allocated memory is returned;
|
|
||||||
* NULL is returned on failure.
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
FAR void *gran_reserve(GRAN_HANDLE handle, uintptr_t start, size_t size)
|
FAR void *gran_reserve(GRAN_HANDLE handle, uintptr_t start, size_t size)
|
||||||
{
|
{
|
||||||
FAR struct gran_s *priv = (FAR struct gran_s *)handle;
|
FAR gran_t *gran = (FAR gran_t *)handle;
|
||||||
FAR void *ret = NULL;
|
uintptr_t end;
|
||||||
|
size_t ngran;
|
||||||
|
size_t posi;
|
||||||
|
bool avail;
|
||||||
|
|
||||||
DEBUGASSERT(priv != NULL);
|
DEBUGASSERT(gran);
|
||||||
|
if (!size || size > GRANBYTE(gran))
|
||||||
if (size > 0)
|
|
||||||
{
|
{
|
||||||
uintptr_t mask = (1 << priv->log2gran) - 1;
|
return NULL;
|
||||||
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 granules */
|
|
||||||
|
|
||||||
ngranules = ((end - start) >> priv->log2gran) + 1;
|
|
||||||
|
|
||||||
/* Must lock the granule allocator */
|
|
||||||
|
|
||||||
if (gran_enter_critical(priv) < 0)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* And reserve the granules */
|
|
||||||
|
|
||||||
ret = gran_mark_allocated(priv, start, ngranules);
|
|
||||||
gran_leave_critical(priv);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
/* align down/up start/ending addresses */
|
||||||
|
|
||||||
|
end = END_RSRV(gran, start, size);
|
||||||
|
if (!GRAN_INRANGE(gran, end))
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
start = MEM_RSRV(gran, start);
|
||||||
|
if (!GRAN_INRANGE(gran, start))
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* convert unit to granule */
|
||||||
|
|
||||||
|
posi = MEM2GRAN(gran, start);
|
||||||
|
ngran = ((end - start) >> gran->log2gran) + 1;
|
||||||
|
|
||||||
|
/* lock the granule allocator */
|
||||||
|
|
||||||
|
if (gran_enter_critical(gran) < 0)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
avail = gran_match(gran, posi, ngran, 0, NULL);
|
||||||
|
if (avail)
|
||||||
|
{
|
||||||
|
gran_set(gran, posi, ngran);
|
||||||
|
}
|
||||||
|
|
||||||
|
gran_leave_critical(gran);
|
||||||
|
|
||||||
|
graninfo("%s posi=%zu retp=%zx size=%zu n=%zu\n",
|
||||||
|
avail ? " done" : " error", posi, (size_t)start, size, ngran);
|
||||||
|
|
||||||
|
return avail ? (FAR void *)start : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_GRAN */
|
#endif /* CONFIG_GRAN */
|
||||||
|
|||||||
@@ -0,0 +1,291 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* mm/mm_gran/mm_grantable.c
|
||||||
|
*
|
||||||
|
* 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 <nuttx/config.h>
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <strings.h>
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
#include <nuttx/bits.h>
|
||||||
|
#include <nuttx/mm/gran.h>
|
||||||
|
|
||||||
|
#include "mm_gran/mm_gran.h"
|
||||||
|
#include "mm_gran/mm_grantable.h"
|
||||||
|
|
||||||
|
#ifdef CONFIG_GRAN
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Preprocessors
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#define GATCFULL 0xffffffffu /* a full GAT cell */
|
||||||
|
#define DEBRUJIN_NUM 0x077CB531UL /* the de Bruijn Sequence */
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private data
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#if !defined(CONFIG_HAVE_BUILTIN_CLZ) || !defined(CONFIG_HAVE_BUILTIN_CTZ)
|
||||||
|
|
||||||
|
/* The de Bruijn lookup table to get n from BIT(n). */
|
||||||
|
|
||||||
|
static const uint8_t DEBRUJIN_LUT[32] =
|
||||||
|
{
|
||||||
|
0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
|
||||||
|
31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/* return BIT(MSB(n)) */
|
||||||
|
|
||||||
|
uint32_t msb_mask(uint32_t n)
|
||||||
|
{
|
||||||
|
/* see https://www.geeksforgeeks.org/find-significant-set-bit-number */
|
||||||
|
|
||||||
|
DEBUGASSERT(n);
|
||||||
|
n |= n >> 1;
|
||||||
|
n |= n >> 2;
|
||||||
|
n |= n >> 4;
|
||||||
|
n |= n >> 8;
|
||||||
|
n |= n >> 16;
|
||||||
|
|
||||||
|
n = ((n + 1) >> 1) | (n & (1 << ((sizeof(n) << 3)-1)));
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* return BIT(LSB(n)) */
|
||||||
|
|
||||||
|
uint32_t lsb_mask(uint32_t n)
|
||||||
|
{
|
||||||
|
DEBUGASSERT(n);
|
||||||
|
return (-n & n) & GATCFULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set or clear a GAT cell with given bit mask */
|
||||||
|
|
||||||
|
static void cell_set(gran_t *gran, uint32_t cell, uint32_t mask, bool val)
|
||||||
|
{
|
||||||
|
if (val)
|
||||||
|
{
|
||||||
|
gran->gat[cell] |= mask;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gran->gat[cell] &= ~mask;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set or clear a range of GAT bits */
|
||||||
|
|
||||||
|
static void gran_set_(gran_t *gran, gatr_t *rang, bool val)
|
||||||
|
{
|
||||||
|
uint32_t c;
|
||||||
|
|
||||||
|
cell_set(gran, rang->sidx, rang->smask, val);
|
||||||
|
if (rang->sidx != rang->eidx)
|
||||||
|
{
|
||||||
|
cell_set(gran, rang->eidx, rang->emask, val);
|
||||||
|
c = rang->sidx + 1;
|
||||||
|
for (; c < rang->eidx; c++)
|
||||||
|
{
|
||||||
|
cell_set(gran, c, GATCFULL, val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/* prepare given GAT range instance for later use. */
|
||||||
|
|
||||||
|
int gran_range(const gran_t *gran, size_t posi, size_t size,
|
||||||
|
gatr_t *rang)
|
||||||
|
{
|
||||||
|
if (!gran || gran->ngranules < posi + size)
|
||||||
|
{
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rang == NULL)
|
||||||
|
{
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
rang->width = GATC_BITS(gran);
|
||||||
|
|
||||||
|
rang->sidx = posi / rang->width;
|
||||||
|
rang->soff = posi % rang->width;
|
||||||
|
|
||||||
|
posi += size - 1;
|
||||||
|
rang->eidx = posi / GATC_BITS(gran);
|
||||||
|
rang->eoff = posi % GATC_BITS(gran);
|
||||||
|
|
||||||
|
rang->smask = ~(BIT(rang->soff) - 1);
|
||||||
|
rang->emask = (BIT(rang->eoff) - 1) | BIT(rang->eoff);
|
||||||
|
|
||||||
|
if (rang->sidx == rang->eidx)
|
||||||
|
{
|
||||||
|
rang->smask &= rang->emask; /* combine the masks */
|
||||||
|
rang->emask = rang->smask;
|
||||||
|
}
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* checks if a range of granule matches the expected status */
|
||||||
|
|
||||||
|
bool gran_match(const gran_t *gran, size_t posi, size_t size, bool used,
|
||||||
|
size_t *mpos)
|
||||||
|
{
|
||||||
|
uint32_t c; /* cell index */
|
||||||
|
uint32_t v; /* masked cell value */
|
||||||
|
uint32_t e; /* expected cell value */
|
||||||
|
gatr_t r; /* range helper */
|
||||||
|
|
||||||
|
gran_range(gran, posi, size, &r);
|
||||||
|
|
||||||
|
/* check the ending cell */
|
||||||
|
|
||||||
|
c = r.eidx;
|
||||||
|
e = used ? r.emask : 0 ;
|
||||||
|
v = gran->gat[c] & r.emask;
|
||||||
|
if (v != e)
|
||||||
|
{
|
||||||
|
goto failure;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r.sidx == r.eidx)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check cells in between */
|
||||||
|
|
||||||
|
c = r.eidx - 1;
|
||||||
|
e = used ? GATCFULL : 0;
|
||||||
|
for (; c > r.sidx; c--)
|
||||||
|
{
|
||||||
|
v = gran->gat[c];
|
||||||
|
if (v != e)
|
||||||
|
{
|
||||||
|
goto failure;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check the starting cell */
|
||||||
|
|
||||||
|
c = r.sidx;
|
||||||
|
e = used ? r.smask : 0 ;
|
||||||
|
v = gran->gat[c] & r.smask;
|
||||||
|
if (v != e)
|
||||||
|
{
|
||||||
|
goto failure;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
failure:
|
||||||
|
|
||||||
|
if (mpos && !used)
|
||||||
|
{
|
||||||
|
/* offset of last used when matching for free */
|
||||||
|
|
||||||
|
DEBUGASSERT(v);
|
||||||
|
#ifdef CONFIG_HAVE_BUILTIN_CLZ
|
||||||
|
*mpos = 31 - __builtin_clz(v);
|
||||||
|
#else
|
||||||
|
*mpos = (uint32_t)((msb_mask(v)) * DEBRUJIN_NUM) >> 27;
|
||||||
|
DEBUGASSERT(*mpos < sizeof(DEBRUJIN_LUT));
|
||||||
|
*mpos = DEBRUJIN_LUT[*mpos];
|
||||||
|
#endif
|
||||||
|
*mpos += c * GATC_BITS(gran);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* returns granule number of free range or negative error */
|
||||||
|
|
||||||
|
int gran_search(const gran_t *gran, size_t size)
|
||||||
|
{
|
||||||
|
int ret = -EINVAL;
|
||||||
|
|
||||||
|
if (gran == NULL || gran->ngranules < size)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = -ENOMEM;
|
||||||
|
for (size_t i = 0; i <= gran->ngranules - size; i++)
|
||||||
|
{
|
||||||
|
if (gran_match(gran, i, size, 0, &i))
|
||||||
|
{
|
||||||
|
ret = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set a range of granules */
|
||||||
|
|
||||||
|
int gran_set(gran_t *gran, size_t posi, size_t size)
|
||||||
|
{
|
||||||
|
gatr_t rang;
|
||||||
|
int ret = gran_range(gran, posi, size, &rang);
|
||||||
|
|
||||||
|
if (ret == OK)
|
||||||
|
{
|
||||||
|
gran_set_(gran, &rang, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* clear a range of granules */
|
||||||
|
|
||||||
|
int gran_clear(gran_t *gran, size_t posi, size_t size)
|
||||||
|
{
|
||||||
|
gatr_t rang;
|
||||||
|
int ret = gran_range(gran, posi, size, &rang);
|
||||||
|
|
||||||
|
if (ret == OK)
|
||||||
|
{
|
||||||
|
gran_set_(gran, &rang, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* CONFIG_GRAN */
|
||||||
@@ -0,0 +1,159 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* mm/mm_gran/mm_grantable.h
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __MM_MM_GRAN_MM_GRANTABLE_H
|
||||||
|
#define __MM_MM_GRAN_MM_GRANTABLE_H
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Pre-processor Definitions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/* Granule arithmetics */
|
||||||
|
|
||||||
|
#define GRANSIZE(g) (1 << g->log2gran)
|
||||||
|
#define GRANMASK(g) (GRANSIZE(g) - 1)
|
||||||
|
#define NGRANULE(g, s) ((s + GRANMASK(g)) >> g->log2gran)
|
||||||
|
|
||||||
|
#define GRANBYTE(g) ((size_t)g->ngranules << g->log2gran)
|
||||||
|
#define GRANENDA(g) (GRANBYTE(g) + g->heapstart)
|
||||||
|
#define MEM2GRAN(g, m) ((((uintptr_t)m) - g->heapstart) >> g->log2gran)
|
||||||
|
#define GRAN2MEM(g, x) ((((uintptr_t)x) << g->log2gran) + g->heapstart)
|
||||||
|
|
||||||
|
#define GRAN_ALIGNED(g, m) ((((uintptr_t)(m)) & GRANMASK(g)) == 0)
|
||||||
|
#define GRAN_INRANGE(g, m) (g->heapstart <= (uintptr_t)(m) && \
|
||||||
|
(uintptr_t)(m) < GRANENDA(g))
|
||||||
|
#define GRAN_PRODUCT(g, m) (GRAN_ALIGNED(g, m) && GRAN_INRANGE(g, m))
|
||||||
|
|
||||||
|
#define ALIGNDN(g, m) (((size_t)m) & ~GRANMASK(g))
|
||||||
|
#define ALIGNUP(g, m) ((((size_t)m) + GRANMASK(g)) & ~GRANMASK(g))
|
||||||
|
|
||||||
|
/* gran_reserve related */
|
||||||
|
|
||||||
|
#define MEM_RSRV(g, m) ALIGNDN(g, m)
|
||||||
|
#define END_RSRV(g, m, s) ALIGNUP(g, (((size_t)m) + s - 1))
|
||||||
|
#define NUM_RSRV(g, m, s) (((END_RSRV(g, m, s) - MEM_RSRV(g, m)) \
|
||||||
|
>> g->log2gran) + 1)
|
||||||
|
#define LEN_RSRV(g, m, s) ((size_t)(NUM_RSRV(g, m, s) << g->log2gran))
|
||||||
|
|
||||||
|
/* GAT table related */
|
||||||
|
|
||||||
|
#define GATC_BITS(g) (sizeof(g->gat[0]) << 3)
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Types
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/* Structure for a range of granules in GAT */
|
||||||
|
|
||||||
|
struct gran_range_s
|
||||||
|
{
|
||||||
|
uint16_t sidx; /* index of the starting GAT cell */
|
||||||
|
uint16_t eidx; /* index of the ending GAT cell */
|
||||||
|
uint8_t soff; /* offset of bit in starting cell */
|
||||||
|
uint8_t eoff; /* offset of bit in ending cell */
|
||||||
|
uint16_t width; /* width of cell in bits */
|
||||||
|
uint32_t smask; /* mask of the starting GAT cell */
|
||||||
|
uint32_t emask; /* mask of the ending GAT cell */
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct gran_range_s gatr_t;
|
||||||
|
typedef struct gran_s gran_t;
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Function Prototypes
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: gran_range
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* populate a gran_range_s instance for later use
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* gran - Pointer to the gran state
|
||||||
|
* posi - Position of starting granule
|
||||||
|
* size - Length of range
|
||||||
|
*
|
||||||
|
* Output Parameters:
|
||||||
|
* rang - The range instance to be prepared
|
||||||
|
*
|
||||||
|
* Return value:
|
||||||
|
* OK or negative errno
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int gran_range(const gran_t *gran, size_t posi, size_t size, gatr_t *rang);
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: gran_match
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* check if a continuous range of granules all have expected status
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* gran - Pointer to the gran state
|
||||||
|
* posi - Position of starting granule
|
||||||
|
* size - Length of range
|
||||||
|
* used - Expected state, true for used, false for empty.
|
||||||
|
*
|
||||||
|
* Output Parameters:
|
||||||
|
* mism - Optional last failed position upon free range matching.
|
||||||
|
*
|
||||||
|
* Return value:
|
||||||
|
* true for match, false otherwise.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
bool gran_match(const gran_t *gran, size_t posi, size_t size, bool used,
|
||||||
|
size_t *mism);
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: gran_search
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* search for continuous range of free granules
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* gran - Pointer to the gran state
|
||||||
|
* size - Length of range
|
||||||
|
*
|
||||||
|
* Return value:
|
||||||
|
* position of negative error number.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int gran_search(const gran_t *gran, size_t size);
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: gran_set, gran_clear
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Set or clear a range of granule in the GAT
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* gran - Pointer to the gran state
|
||||||
|
* posi - Range starting bit index
|
||||||
|
* size - Range size
|
||||||
|
*
|
||||||
|
* Return value:
|
||||||
|
* OK on success or negative value on error
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int gran_set(gran_t *gran, size_t posi, size_t size);
|
||||||
|
int gran_clear(gran_t *gran, size_t posi, size_t size);
|
||||||
|
|
||||||
|
#endif /* __MM_MM_GRAN_MM_GRANTABLE_H */
|
||||||
Reference in New Issue
Block a user