Fixes for granule allocator

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5131 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo 2012-09-11 21:39:39 +00:00
parent 26841d617e
commit b75545f120
6 changed files with 80 additions and 11 deletions

View File

@ -106,8 +106,8 @@ extern "C" {
****************************************************************************/
#ifdef CONFIG_GRAN_SINGLE
EXTERN void gran_initialize(FAR void *heapstart, size_t heapsize,
uint8_t log2gran);
EXTERN int gran_initialize(FAR void *heapstart, size_t heapsize,
uint8_t log2gran);
#else
EXTERN GRAN_HANDLE gran_initialize(FAR void *heapstart, size_t heapsize,
uint8_t log2gran);

View File

@ -41,7 +41,7 @@ CSRCS = mm_initialize.c mm_sem.c mm_addfreechunk.c mm_size2ndx.c mm_shrinkchunk
mm_memalign.c mm_free.c mm_mallinfo.c
ifeq ($(CONFIG_GRAN),y)
CSRCS = mm_graninit.c mm_granalloc.c mm_granfree.c
CSRCS += mm_graninit.c mm_granalloc.c mm_granfree.c
endif
AOBJS = $(ASRCS:.S=$(OBJEXT))

View File

@ -43,6 +43,7 @@
#include <nuttx/config.h>
#include <stdint.h>
#include <semaphore.h>
#include <nuttx/gran.h>
@ -87,6 +88,7 @@ struct gran_s
{
uint8_t log2gran; /* Log base 2 of the size of one granule */
uint16_t ngranules; /* The total number of (aligned) granules in the heap */
sem_t exclsem; /* For exclusive access to the GAT */
uintptr_t heapstart; /* The aligned start of the granule heap */
uint32_t gat[1]; /* Start of the granule allocation table */
};
@ -105,4 +107,22 @@ extern FAR struct gran_s *g_graninfo;
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: gran_semtake and gran_semgive
*
* Description:
* Managed semaphore for the granule allocator. gran_semgive is
* implemented as a macro.
*
* Input Parameters:
* priv - Pointer to the gran state
*
* Returned Value:
* None
*
****************************************************************************/
void gran_semtake(FAR struct gran_s *priv);
#define gran_semgive(p) sem_post(&(p)->exclsem);
#endif /* __MM_MM_GRAN_H */

View File

@ -93,7 +93,7 @@ static inline void gran_mark_allocated(FAR struct gran_s *priv, uintptr_t alloc,
ngranules -= avail;
}
/* Handle the cae where where all of the granules come from one entry */
/* Handle the case where where all of the granules come from one entry */
else
{
@ -135,8 +135,13 @@ static inline FAR void *gran_common_alloc(FAR struct gran_s *priv, size_t size)
int j;
DEBUGASSERT(priv && size <= 32 * (1 << priv->log2gran));
if (priv && size > 0)
{
/* Get exclusive access to the GAT */
gran_semtake(priv);
/* How many contiguous granules we we need to find? */
tmpmask = (1 << priv->log2gran) - 1;
@ -186,6 +191,7 @@ static inline FAR void *gran_common_alloc(FAR struct gran_s *priv, size_t size)
/* And return the allocation address */
gran_semgive(priv);
return (FAR void *)alloc;
}
@ -207,6 +213,7 @@ static inline FAR void *gran_common_alloc(FAR struct gran_s *priv, size_t size)
}
}
gran_semgive(priv);
return NULL;
}

View File

@ -79,6 +79,10 @@ static inline void gran_common_free(FAR struct gran_s *priv,
DEBUGASSERT(priv && memory && size <= 32 * (1 << priv->log2gran));
/* Get exclusive access to the GAT */
gran_semtake(priv);
/* Determine the granule number of the first granule in the allocation */
granno = ((uintptr_t)memory - priv->heapstart) >> priv->log2gran;
@ -102,21 +106,22 @@ static inline void gran_common_free(FAR struct gran_s *priv,
{
priv->gat[gatidx] &= ~(0xffffffff << gatbit);
ngranules -= avail;
/* Clear bits in the second GAT entry */
gatmask = 0xffffffff >> (32 - ngranules);
priv->gat[gatidx+1] &= ~(gatmask << gatbit);
}
/* Handle the cae where where all of the granules came from one entry */
/* Handle the case where where all of the granules came from one entry */
else
{
gatmask = 0xffffffff >> (32 - ngranules);
priv->gat[gatidx] &= ~(gatmask << gatbit);
return;
}
/* Clear bits in the second GAT entry */
gatmask = 0xffffffff >> (32 - ngranules);
priv->gat[gatidx+1] &= ~(gatmask << gatbit);
gran_semgive(priv);
}
/****************************************************************************

View File

@ -40,6 +40,8 @@
#include <nuttx/config.h>
#include <stdlib.h>
#include <assert.h>
#include <errno.h>
#include <nuttx/gran.h>
@ -95,6 +97,8 @@ static inline FAR struct gran_s *gran_common_initialize(FAR void *heapstart,
unsigned int alignedsize;
unsigned int ngranules;
DEBUGASSERT(heapstart && heapsize > 0 && log2gran > 0 && log2gran < 32);
/* Determine the number of granules */
mask = (1 << log2gran) - 1;
@ -115,6 +119,7 @@ static inline FAR struct gran_s *gran_common_initialize(FAR void *heapstart,
priv->log2gran = log2gran;
priv->ngranules = ngranules;
priv->heapstart = alignedstart;
sem_init(&priv->exclsem, 0, 1);
}
return priv;
@ -153,7 +158,7 @@ static inline FAR struct gran_s *gran_common_initialize(FAR void *heapstart,
int gran_initialize(FAR void *heapstart, size_t heapsize, uint8_t log2gran)
{
g_graninfo = gran_common_initialize(heapstart, heapsize, log2gran);
if (!g_granifo)
if (!g_graninfo)
{
return -ENOMEM;
}
@ -167,6 +172,38 @@ GRAN_HANDLE gran_initialize(FAR void *heapstart, size_t heapsize, uint8_t log2gr
}
#endif
/****************************************************************************
* Name: gran_semtake and gran_semgive
*
* Description:
* Managed semaphore for the granule allocator. gran_semgive is
* implemented as a macro.
*
* Input Parameters:
* priv - Pointer to the gran state
*
* Returned Value:
* None
*
****************************************************************************/
void gran_semtake(FAR struct gran_s *priv)
{
int ret;
/* Continue waiting if we are awakened by a signal */
do
{
ret = sem_wait(&priv->exclsem);
if (ret < 0)
{
DEBUGASSERT(errno == EINTR);
}
}
while (ret < 0);
}
#endif /* CONFIG_GRAN */