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 2da0392ae2
commit 006cf7d745
4 changed files with 124 additions and 46 deletions

View File

@ -133,9 +133,19 @@ do { \
struct group_addrenv_s
{
/* Level 1 page table entries for each group section */
FAR uintptr_t *text[ARCH_TEXT_NSECTS];
FAR uintptr_t *data[ARCH_DATA_NSECTS];
FAR uintptr_t *heap[ARCH_HEAP_NSECTS];
/* Initial heap allocation (in bytes). This exists only provide an
* indirect path for passing the size of the initial heap to the heap
* initialization logic. These operations are separated in time and
* architecture. REVISIT: I would like a better way to do this.
*/
size_t heapsize;
};
typedef struct group_addrenv_s group_addrenv_t;
@ -153,9 +163,7 @@ struct save_addrenv_s
{
FAR uint32_t text[ARCH_TEXT_NSECTS];
FAR uint32_t data[ARCH_DATA_NSECTS];
#if 0 /* Not yet implemented */
FAR uint32_t heap[ARCH_HEAP_NSECTS];
#endif
};
typedef struct save_addrenv_s save_addrenv_t;

View File

@ -274,17 +274,15 @@ struct xcptcontext
struct xcpt_syscall_s syscall[CONFIG_SYS_NNEST];
#endif
#ifdef CONFIG_ARCH_ADDRENV
#if defined(CONFIG_ARCH_ADDRENV) && defined(CONFIG_ARCH_STACK_DYNAMIC)
/* This table holds the physical address of the level 2 page table used
* to map the thread's stack memory. This array will be initially of
* zeroed and would be back-up up with pages during page fault exception
* handling to support dynamically sized stacks for each thread.
*/
#if 0 /* Not yet implemented */
FAR uintptr_t *stack[ARCH_STACK_NSECTS];
#endif
#endif
};
#endif

View File

@ -40,27 +40,28 @@
* is an abstract representation of a task group's address environment and
* must be defined in arch/arch.h if CONFIG_ARCH_ADDRENV is defined.
*
* up_addrenv_create - Create an address environment
* up_addrenv_destroy - Destroy an address environment.
* up_addrenv_vtext - Returns the virtual base address of the .text
* address environment
* up_addrenv_vdata - Returns the virtual base address of the .bss/.data
* address environment
* up_addrenv_select - Instantiate an address environment
* up_addrenv_restore - Restore an address environment
* up_addrenv_clone - Copy an address environment from one location to
* another.
* up_addrenv_create - Create an address environment
* up_addrenv_destroy - Destroy an address environment.
* up_addrenv_vtext - Returns the virtual base address of the .text
* address environment
* up_addrenv_vdata - Returns the virtual base address of the .bss/.data
* address environment
* up_addrenv_heapsize - Returns the size of the initial heap allocation.
* up_addrenv_select - Instantiate an address environment
* up_addrenv_restore - Restore an address environment
* up_addrenv_clone - Copy an address environment from one location to
* another.
*
* Higher-level interfaces used by the tasking logic. These interfaces are
* used by the functions in sched/ and all operate on the thread which whose
* group been assigned an address environment by up_addrenv_clone().
*
* up_addrenv_attach - Clone the address environment assigned to one TCB
* to another. This operation is done when a pthread
* is created that share's the same address
* environment.
* up_addrenv_detach - Release the threads reference to an address
* environment when a task/thread exits.
* up_addrenv_attach - Clone the address environment assigned to one TCB
* to another. This operation is done when a pthread
* is created that share's the same address
* environment.
* up_addrenv_detach - Release the threads reference to an address
* environment when a task/thread exits.
*
****************************************************************************/
@ -153,6 +154,10 @@ static void set_l2_entry(FAR uint32_t *l2table, uintptr_t paddr,
* Description:
* Create one memory region.
*
* Returned Value:
* On success, the number of pages allocated is returned. Otherwise, a
* negated errno value is returned.
*
****************************************************************************/
static int up_addrenv_create_region(FAR uintptr_t **list,
@ -264,7 +269,7 @@ static int up_addrenv_create_region(FAR uintptr_t **list,
irqrestore(flags);
}
return OK;
return npages;
}
/****************************************************************************
@ -437,6 +442,8 @@ static void up_addrenv_destroy_region(FAR uintptr_t **list,
* actual size of the data region that is allocated will include a
* OS private reserved region at the beginning. The size of the
* private, reserved region is give by ARCH_DATA_RESERVE_SIZE.
* heapsize - The initial size (in bytes) of the heap address environment
* needed by the task. This region may be read/write only.
* addrenv - The location to return the representation of the task address
* environment.
*
@ -445,7 +452,7 @@ static void up_addrenv_destroy_region(FAR uintptr_t **list,
*
****************************************************************************/
int up_addrenv_create(size_t textsize, size_t datasize,
int up_addrenv_create(size_t textsize, size_t datasize, size_t heapsize,
FAR group_addrenv_t *addrenv)
{
int ret;
@ -503,8 +510,22 @@ int up_addrenv_create(size_t textsize, size_t datasize,
}
#endif
/* Notice that no pages are yet allocated for the heap */
/* Allocate heap space pages */
ret = up_addrenv_create_region(addrenv->heap, ARCH_HEAP_NSECTS,
CONFIG_ARCH_HEAP_VBASE, heapsize,
MMU_L2_UDATAFLAGS);
if (ret < 0)
{
bdbg("ERROR: Failed to create heap region: %d\n", ret);
goto errout;
}
/* Save the initial heap size allocated. This will be needed when
* the heap data structures are initialized.
*/
addrenv->heapsize = (size_t)ret << MM_PGSHIFT;
return OK;
errout:
@ -543,12 +564,10 @@ int up_addrenv_destroy(FAR group_addrenv_t *addrenv)
up_addrenv_destroy_region(addrenv->data, ARCH_DATA_NSECTS,
CONFIG_ARCH_DATA_VBASE);
#if 0 /* Not yet implemented */
/* Destroy the heap region */
up_addrenv_destroy_region(addrenv->heap, ARCH_HEAP_NSECTS,
CONFIG_ARCH_HEAP_VBASE);
#endif
memset(addrenv, 0, sizeof(group_addrenv_t));
return OK;
@ -616,6 +635,31 @@ int up_addrenv_vdata(FAR group_addrenv_t *addrenv, uintptr_t textsize,
return OK;
}
/****************************************************************************
* Name: up_addrenv_heapsize
*
* Description:
* Return the initial heap allocation size. That is the amount of memory
* allocated by up_addrenv_create() when the heap memory region was first
* created. This may or may not differ from the heapsize parameter that
* was passed to up_addrenv_create()
*
* Input Parameters:
* addrenv - The representation of the task address environment previously
* returned by up_addrenv_create.
*
* Returned Value:
* The initial heap size allocated is returned on success; a negated
* errno value on failure.
*
****************************************************************************/
ssize_t up_addrenv_heapsize(FAR const group_addrenv_t *addrenv)
{
DEBUGASSERT(addrenv);
return (ssize_t)addrenv->heapsize;
}
/****************************************************************************
* Name: up_addrenv_select
*
@ -698,7 +742,6 @@ int up_addrenv_select(FAR const group_addrenv_t *addrenv,
}
}
#if 0 /* Not yet implemented */
for (vaddr = CONFIG_ARCH_HEAP_VBASE, i = 0;
i < ARCH_HEAP_NSECTS;
vaddr += SECTION_SIZE, i++)
@ -722,7 +765,6 @@ int up_addrenv_select(FAR const group_addrenv_t *addrenv,
mmu_l1_clrentry(vaddr);
}
}
#endif
return OK;
}
@ -770,7 +812,6 @@ int up_addrenv_restore(FAR const save_addrenv_t *oldenv)
mmu_l1_restore(vaddr, oldenv->data[i]);
}
#if 0 /* Not yet implemented */
for (vaddr = CONFIG_ARCH_HEAP_VBASE, i = 0;
i < ARCH_HEAP_NSECTS;
vaddr += SECTION_SIZE, i++)
@ -779,7 +820,6 @@ int up_addrenv_restore(FAR const save_addrenv_t *oldenv)
mmu_l1_restore(vaddr, oldenv->heap[i]);
}
#endif
return OK;
}

View File

@ -184,15 +184,16 @@ return g_physhandle ? OK : -ENOMEM;
* is an abstract representation of a task group's address environment and
* must be defined in arch/arch.h if CONFIG_ARCH_ADDRENV is defined.
*
* up_addrenv_create - Create an address environment
* up_addrenv_destroy - Destroy an address environment.
* up_addrenv_vtext - Returns the virtual base address of the .text
* address environment
* up_addrenv_vdata - Returns the virtual base address of the .bss/.data
* address environment
* up_addrenv_select - Instantiate an address environment
* up_addrenv_restore - Restore an address environment
* up_addrenv_clone - Copy an address environment from one location to
* up_addrenv_create - Create an address environment
* up_addrenv_destroy - Destroy an address environment.
* up_addrenv_vtext - Returns the virtual base address of the .text
* address environment
* up_addrenv_vdata - Returns the virtual base address of the .bss/.data
* address environment
* up_addrenv_heapsize - Returns the size of the initial heap allocation.
* up_addrenv_select - Instantiate an address environment
* up_addrenv_restore - Restore an address environment
* up_addrenv_clone - Copy an address environment from one location to
* another.
*
* Higher-level interfaces used by the tasking logic. These interfaces are
@ -200,11 +201,11 @@ return g_physhandle ? OK : -ENOMEM;
* group been assigned an address environment by up_addrenv_clone().
*
* up_addrenv_attach - Clone the address environment assigned to one TCB
* to another. This operation is done when a pthread
* is created that share's the same address
* environment.
* up_addrenv_detach - Release the threads reference to an address
* environment when a task/thread exits.
* to another. This operation is done when a pthread
* is created that share's the same address
* environment.
* up_addrenv_detach - Release the threads reference to an address
* environment when a task/thread exits.
*
****************************************************************************/
/****************************************************************************
@ -220,6 +221,11 @@ return g_physhandle ? OK : -ENOMEM;
* textsize - The size (in bytes) of the .text address environment needed
* by the task. This region may be read/execute only.
* datasize - The size (in bytes) of the .data/.bss address environment
* needed by the task. This region may be read/write only. NOTE: The
* actual size of the data region that is allocated will include a
* OS private reserved region at the beginning. The size of the
* private, reserved region is give by ARCH_DATA_RESERVE_SIZE.
* heapsize - The initial size (in bytes) of the heap address environment
* needed by the task. This region may be read/write only.
* addrenv - The location to return the representation of the task address
* environment.
@ -229,7 +235,7 @@ return g_physhandle ? OK : -ENOMEM;
*
****************************************************************************/
int up_addrenv_create(size_t textsize, size_t datasize,
int up_addrenv_create(size_t textsize, size_t datasize, size_t heapsize,
FAR group_addrenv_t *addrenv)
{
FAR struct z180_cbr_s *cbr;
@ -241,7 +247,7 @@ int up_addrenv_create(size_t textsize, size_t datasize,
/* Convert the size from bytes to numbers of pages */
envsize = textsize + datasize;
envsize = textsize + datasize + heapsize;
npages = PHYS_ALIGNUP(envsize);
if (npages < 1)
{
@ -389,6 +395,32 @@ int up_addrenv_vdata(FAR group_addrenv_t *addrenv, uintptr_t textsize,
return CONFIG_Z180_COMMON1AREA_VIRTBASE + textsize;
}
/****************************************************************************
* Name: up_addrenv_heapsize
*
* Description:
* Return the initial heap allocation size. That is the amount of memory
* allocated by up_addrenv_create() when the heap memory region was first
* created. This may or may not differ from the heapsize parameter that
* was passed to up_addrenv_create()
*
* Input Parameters:
* addrenv - The representation of the task address environment previously
* returned by up_addrenv_create.
*
* Returned Value:
* The initial heap size allocated is returned on success; a negated
* errno value on failure.
*
****************************************************************************/
ssize_t up_addrenv_heapsize(FAR const group_addrenv_t *addrenv)
{
/* Not implemented */
return (ssize_t)-ENOSYS;
}
/****************************************************************************
* Name: up_addrenv_select
*