mirror of
https://github.com/apache/nuttx.git
synced 2026-05-28 03:45:50 +08:00
Add logic to initialize the per-process user heap when each user process is started
This commit is contained in:
+25
-15
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user