mm/gran: Allow run-time execution of gran_reserve
User can ask for specific granules to be allocated. This is useful for one thing only: when mmap() is called for a specific vaddr. The parameter itself is non-sensical, this is just to satisfy the POSIX standard.
This commit is contained in:
parent
5c1b518314
commit
458ff380e5
@ -170,11 +170,12 @@ void gran_release(GRAN_HANDLE handle);
|
||||
* size - The size of the region to be reserved
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
* On success, a non-NULL pointer to the allocated memory is returned;
|
||||
* NULL is returned on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
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);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: gran_alloc
|
||||
|
@ -109,11 +109,12 @@ void gran_leave_critical(FAR struct gran_s *priv);
|
||||
* ngranules - The number of granules allocated
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
* On success, a non-NULL pointer to the allocated memory is returned;
|
||||
* NULL is returned on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void gran_mark_allocated(FAR struct gran_s *priv, uintptr_t alloc,
|
||||
unsigned int ngranules);
|
||||
FAR void *gran_mark_allocated(FAR struct gran_s *priv, uintptr_t alloc,
|
||||
unsigned int ngranules);
|
||||
|
||||
#endif /* __MM_MM_GRAN_MM_GRAN_H */
|
||||
|
@ -48,12 +48,13 @@
|
||||
* ngranules - The number of granules allocated
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
* On success, a non-NULL pointer to the allocated memory is returned;
|
||||
* NULL is returned on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void gran_mark_allocated(FAR struct gran_s *priv, uintptr_t alloc,
|
||||
unsigned int ngranules)
|
||||
FAR void *gran_mark_allocated(FAR struct gran_s *priv, uintptr_t alloc,
|
||||
unsigned int ngranules)
|
||||
{
|
||||
unsigned int granno;
|
||||
unsigned int gatidx;
|
||||
@ -75,35 +76,46 @@ void gran_mark_allocated(FAR struct gran_s *priv, uintptr_t alloc,
|
||||
avail = 32 - gatbit;
|
||||
if (ngranules > avail)
|
||||
{
|
||||
/* Mark bits in the first GAT entry */
|
||||
uint32_t gatmask2;
|
||||
|
||||
gatmask = 0xffffffff << gatbit;
|
||||
DEBUGASSERT((priv->gat[gatidx] & gatmask) == 0);
|
||||
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;
|
||||
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;
|
||||
priv->gat[gatidx + 1] |= gatmask2;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
return (FAR void *)alloc;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_GRAN */
|
||||
|
@ -54,13 +54,15 @@
|
||||
* size - The size of the region to be reserved
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
* On success, a non-NULL pointer to the allocated memory is returned;
|
||||
* NULL is returned on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
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 void *ret = NULL;
|
||||
|
||||
DEBUGASSERT(priv != NULL);
|
||||
|
||||
@ -81,10 +83,20 @@ void gran_reserve(GRAN_HANDLE handle, uintptr_t start, size_t size)
|
||||
|
||||
ngranules = ((end - start) >> priv->log2gran) + 1;
|
||||
|
||||
/* Must lock the granule allocator */
|
||||
|
||||
if (gran_enter_critical(priv) < 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* And reserve the granules */
|
||||
|
||||
gran_mark_allocated(priv, start, ngranules);
|
||||
ret = gran_mark_allocated(priv, start, ngranules);
|
||||
gran_leave_critical(priv);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_GRAN */
|
||||
|
@ -123,7 +123,8 @@ void mm_pginitialize(FAR void *heap_start, size_t heap_size)
|
||||
|
||||
void mm_pgreserve(uintptr_t start, size_t size)
|
||||
{
|
||||
gran_reserve(g_pgalloc, start, size);
|
||||
FAR void * ret = gran_reserve(g_pgalloc, start, size);
|
||||
DEBUGASSERT(ret != NULL);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
Loading…
x
Reference in New Issue
Block a user