Add logic to initialize the per-process user heap when each user process is started

This commit is contained in:
Gregory Nutt
2014-09-10 15:55:36 -06:00
parent 0ee23991fd
commit 205c23b9d6
15 changed files with 326 additions and 132 deletions
+25 -15
View File
@@ -48,6 +48,7 @@
#include <nuttx/arch.h>
#include <nuttx/kmalloc.h>
#include <nuttx/mm.h>
#include <nuttx/binfmt/binfmt.h>
#include "sched/sched.h"
@@ -164,9 +165,9 @@ int exec_module(FAR const struct binary_s *binp)
goto errout;
}
/* Instantiate the address environment containing the destructors */
#ifdef CONFIG_ARCH_ADDRENV
/* Instantiate the address environment containing the user heap */
ret = up_addrenv_select(&binp->addrenv, &oldenv);
if (ret < 0)
{
@@ -174,9 +175,18 @@ int exec_module(FAR const struct binary_s *binp)
err = -ret;
goto errout_with_tcb;
}
/* Initialize the user heap */
umm_initialize((FAR void *)CONFIG_ARCH_HEAP_VBASE,
up_addrenv_heapsize(&binp->addrenv));
#endif
/* Allocate the stack for the new task (always from the user heap) */
/* Allocate the stack for the new task.
*
* REVISIT: This allocation is currently always from the user heap. That
* will need to change if/when we want to support dynamic stack allocation.
*/
stack = (FAR uint32_t*)kumm_malloc(binp->stacksize);
if (!stack)
@@ -185,18 +195,6 @@ int exec_module(FAR const struct binary_s *binp)
goto errout_with_addrenv;
}
/* Restore the address environment */
#ifdef CONFIG_ARCH_ADDRENV
ret = up_addrenv_restore(&oldenv);
if (ret < 0)
{
bdbg("ERROR: up_addrenv_select() failed: %d\n", ret);
err = -ret;
goto errout_with_stack;
}
#endif
/* Initialize the task */
ret = task_init((FAR struct tcb_s *)tcb, binp->filename, binp->priority,
@@ -262,6 +260,18 @@ int exec_module(FAR const struct binary_s *binp)
goto errout_with_stack;
}
#ifdef CONFIG_ARCH_ADDRENV
/* Restore the address environment of the caller */
ret = up_addrenv_restore(&oldenv);
if (ret < 0)
{
bdbg("ERROR: up_addrenv_select() failed: %d\n", ret);
err = -ret;
goto errout_with_stack;
}
#endif
return (int)pid;
errout_with_stack:
+4 -2
View File
@@ -283,6 +283,8 @@ int elf_loaddtors(FAR struct elf_loadinfo_s *loadinfo);
* for the ELF image (read/execute).
* datasize - The size (in bytes) of the .bss/.data address environment
* needed for the ELF image (read/write).
* heapsize - The initial size (in bytes) of the heap address environment
* needed by the task. This region may be read/write only.
*
* Returned Value:
* Zero (OK) on success; a negated errno value on failure.
@@ -290,13 +292,13 @@ int elf_loaddtors(FAR struct elf_loadinfo_s *loadinfo);
****************************************************************************/
int elf_addrenv_alloc(FAR struct elf_loadinfo_s *loadinfo, size_t textsize,
size_t datasize);
size_t datasize, size_t heapsize);
/****************************************************************************
* Name: elf_addrenv_select
*
* Description:
* Temporarity select the task's address environemnt.
* Temporarily select the task's address environemnt.
*
* Input Parameters:
* loadinfo - Load state information
+5 -3
View File
@@ -80,6 +80,8 @@
* for the ELF image (read/execute).
* datasize - The size (in bytes) of the .bss/.data address environment
* needed for the ELF image (read/write).
* heapsize - The initial size (in bytes) of the heap address environment
* needed by the task. This region may be read/write only.
*
* Returned Value:
* Zero (OK) on success; a negated errno value on failure.
@@ -87,7 +89,7 @@
****************************************************************************/
int elf_addrenv_alloc(FAR struct elf_loadinfo_s *loadinfo, size_t textsize,
size_t datasize)
size_t datasize, size_t heapsize)
{
#ifdef CONFIG_ARCH_ADDRENV
FAR void *vtext;
@@ -96,7 +98,7 @@ int elf_addrenv_alloc(FAR struct elf_loadinfo_s *loadinfo, size_t textsize,
/* Create an address environment for the new ELF task */
ret = up_addrenv_create(textsize, datasize, &loadinfo->addrenv);
ret = up_addrenv_create(textsize, datasize, heapsize, &loadinfo->addrenv);
if (ret < 0)
{
bdbg("ERROR: up_addrenv_create failed: %d\n", ret);
@@ -145,7 +147,7 @@ int elf_addrenv_alloc(FAR struct elf_loadinfo_s *loadinfo, size_t textsize,
*
* Description:
* Release the address environment previously created by
* elf_addrenv_create(). This function is called only under certain error
* elf_addrenv_alloc(). This function is called only under certain error
* conditions after the module has been loaded but not yet started.
* After the module has been started, the address environment will
* automatically be freed when the module exits.
+16 -2
View File
@@ -49,6 +49,7 @@
#include <errno.h>
#include <debug.h>
#include <nuttx/addrenv.h>
#include <nuttx/binfmt/elf.h>
#include "libelf.h"
@@ -62,7 +63,11 @@
#define ELF_ALIGNDOWN(a) ((unsigned long)(a) & ~ELF_ALIGN_MASK)
#ifndef MAX
#define MAX(x,y) ((x) > (y) ? (x) : (y))
# define MAX(x,y) ((x) > (y) ? (x) : (y))
#endif
#ifndef MIN
# define MIN(x,y) ((x) < (y) ? (x) : (y))
#endif
/****************************************************************************
@@ -229,6 +234,7 @@ static inline int elf_loadfile(FAR struct elf_loadinfo_s *loadinfo)
int elf_load(FAR struct elf_loadinfo_s *loadinfo)
{
size_t heapsize;
int ret;
bvdbg("loadinfo: %p\n", loadinfo);
@@ -247,9 +253,17 @@ int elf_load(FAR struct elf_loadinfo_s *loadinfo)
elf_elfsize(loadinfo);
/* Determine the heapsize to allocate */
#ifdef CONFIG_ARCH_STACK_DYNAMIC
heapsize = ARCH_HEAP_SIZE;
#else
heapsize = MIN(ARCH_HEAP_SIZE, CONFIG_ELF_STACKSIZE);
#endif
/* Allocate (and zero) memory for the ELF file. */
ret = elf_addrenv_alloc(loadinfo, loadinfo->textsize, loadinfo->datasize);
ret = elf_addrenv_alloc(loadinfo, loadinfo->textsize, loadinfo->datasize, heapsize);
if (ret < 0)
{
bdbg("ERROR: elf_addrenv_alloc() failed: %d\n", ret);
+1 -1
View File
@@ -116,7 +116,7 @@ int nxflat_addrenv_alloc(FAR struct nxflat_loadinfo_s *loadinfo, size_t envsize)
*
* Description:
* Release the address environment previously created by
* nxflat_addrenv_create(). This function is called only under certain
* nxflat_addrenv_alloc(). This function is called only under certain
* error conditions after the module has been loaded but not yet
* started. After the module has been started, the address environment
* will automatically be freed when the module exits.
+14 -1
View File
@@ -52,6 +52,10 @@
* Pre-Processor Definitions
****************************************************************************/
#ifndef MIN
# define MIN(x,y) ((x) < (y) ? (x) : (y))
#endif
/****************************************************************************
* Private Constant Data
****************************************************************************/
@@ -88,6 +92,7 @@ int nxflat_addrenv_alloc(FAR struct nxflat_loadinfo_s *loadinfo, size_t envsize)
#ifdef CONFIG_ARCH_ADDRENV
FAR void *vdata;
save_addrenv_t oldenv;
size_t heapsize;
int ret;
#endif
@@ -103,9 +108,17 @@ int nxflat_addrenv_alloc(FAR struct nxflat_loadinfo_s *loadinfo, size_t envsize)
}
#ifdef CONFIG_ARCH_ADDRENV
/* Determine the heapsize to allocate */
#ifdef CONFIG_ARCH_STACK_DYNAMIC
heapsize = ARCH_HEAP_SIZE;
#else
heapsize = MIN(loadinfo->stacksize, ARCH_HEAP_SIZE);
#endif
/* Create a D-Space address environment for the new NXFLAT task */
ret = up_addrenv_create(envsize, &loadinfo->addrenv);
ret = up_addrenv_create(0, envsize, heapsize, &loadinfo->addrenv);
if (ret < 0)
{
bdbg("ERROR: up_addrenv_create failed: %d\n", ret);