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:
parent
26841d617e
commit
b75545f120
|
@ -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);
|
||||
|
|
|
@ -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))
|
||||
|
|
20
mm/mm_gran.h
20
mm/mm_gran.h
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue