summaryrefslogtreecommitdiff
path: root/nuttx/mm
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2014-09-02 08:05:11 -0600
committerGregory Nutt <gnutt@nuttx.org>2014-09-02 08:05:11 -0600
commitf86563aa4b8766959e7b2d1bee1829c431ac1acb (patch)
treebd5c7d6952b26442ad084727e82cc54e3e37a335 /nuttx/mm
parent9691af43e7843bfe632262822ac8521a2193fba3 (diff)
downloadnuttx-f86563aa4b8766959e7b2d1bee1829c431ac1acb.tar.gz
nuttx-f86563aa4b8766959e7b2d1bee1829c431ac1acb.tar.bz2
nuttx-f86563aa4b8766959e7b2d1bee1829c431ac1acb.zip
sbrk() need to initialized the memory manager on the first call
Diffstat (limited to 'nuttx/mm')
-rw-r--r--nuttx/mm/mm_sbrk.c36
1 files changed, 28 insertions, 8 deletions
diff --git a/nuttx/mm/mm_sbrk.c b/nuttx/mm/mm_sbrk.c
index c0c640735..f8c22b33a 100644
--- a/nuttx/mm/mm_sbrk.c
+++ b/nuttx/mm/mm_sbrk.c
@@ -93,9 +93,10 @@ FAR void *mm_sbrk(FAR struct mm_heap_s *heap, intptr_t incr,
uintptr_t maxbreak)
{
uintptr_t brkaddr;
+ uintptr_t allocbase;
unsigned int pgincr;
+ size_t bytesize;
int err;
- int ret;
DEBUGASSERT(incr >= 0);
if (incr < 0)
@@ -104,7 +105,10 @@ FAR void *mm_sbrk(FAR struct mm_heap_s *heap, intptr_t incr,
goto errout;
}
- /* Get the current break address (NOTE: assumes region 0) */
+ /* Get the current break address (NOTE: assumes region 0). If
+ * the memory manager is uninitialized, mm_brkaddr() will return
+ * zero.
+ */
brkaddr = (uintptr_t)mm_brkaddr(heap, 0);
if (incr > 0)
@@ -122,19 +126,35 @@ FAR void *mm_sbrk(FAR struct mm_heap_s *heap, intptr_t incr,
}
/* Allocate the requested number of pages and map them to the
- * break address.
+ * break address. If we provide a zero brkaddr to pgalloc(), it
+ * will create the first block in the correct virtual address
+ * space and return the start address of that block.
*/
- ret = pgalloc(brkaddr, pgincr);
- if (ret < 0)
+ allocbase = pgalloc(brkaddr, pgincr);
+ if (allocbase == 0)
{
- err = -ret;
+ err = EAGAIN;
goto errout;
}
- /* Extend the heap (region 0) */
+ /* Has the been been initialized? brkaddr will be zero if the
+ * memory manager has not yet been initialized.
+ */
+
+ bytesize = pgincr << MM_PGSHIFT;
+ if (brkaddr != 0)
+ {
+ /* No... then initialize it now */
- mm_extend(heap, (FAR void *)brkaddr, pgincr << MM_PGSHIFT, 0);
+ mm_initialize(heap, (FAR void *)allocbase, bytesize);
+ }
+ else
+ {
+ /* Extend the heap (region 0) */
+
+ mm_extend(heap, (FAR void *)allocbase, bytesize, 0);
+ }
}
return (FAR void *)brkaddr;