group/group_addrenv: Move address environment from group -> tcb
Detach the address environment handling from the group structure to the tcb. This is preparation to fix rare cases where the system (MMU) is left without a valid page directory, e.g. when a process exits.
This commit is contained in:
parent
ca95d592d3
commit
5713d85df0
@ -33,7 +33,6 @@
|
||||
#ifndef __ASSEMBLY__
|
||||
# include <stdint.h>
|
||||
# include <nuttx/pgalloc.h>
|
||||
# include <nuttx/addrenv.h>
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -98,8 +98,6 @@
|
||||
#include <assert.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/addrenv.h>
|
||||
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/pgalloc.h>
|
||||
#include <nuttx/irq.h>
|
||||
@ -778,22 +776,18 @@ int up_addrenv_clone(const arch_addrenv_t *src,
|
||||
* is created that needs to share the address environment of its task
|
||||
* group.
|
||||
*
|
||||
* NOTE: In some platforms, nothing will need to be done in this case.
|
||||
* Simply being a member of the group that has the address environment
|
||||
* may be sufficient.
|
||||
*
|
||||
* Input Parameters:
|
||||
* group - The task group to which the new thread belongs.
|
||||
* tcb - The TCB of the thread needing the address environment.
|
||||
* ptcb - The tcb of the parent task.
|
||||
* tcb - The tcb of the thread needing the address environment.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success; a negated errno value on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int up_addrenv_attach(struct task_group_s *group, struct tcb_s *tcb)
|
||||
int up_addrenv_attach(struct tcb_s *ptcb, struct tcb_s *tcb)
|
||||
{
|
||||
binfo("group=%p tcb=%p\n", group, tcb);
|
||||
binfo("parent=%p tcb=%p\n", ptcb, tcb);
|
||||
|
||||
/* Nothing needs to be done in this implementation */
|
||||
|
||||
@ -810,12 +804,7 @@ int up_addrenv_attach(struct task_group_s *group, struct tcb_s *tcb)
|
||||
* task group is itself destroyed. Any resources unique to this thread
|
||||
* may be destroyed now.
|
||||
*
|
||||
* NOTE: In some platforms, nothing will need to be done in this case.
|
||||
* Simply being a member of the group that has the address environment
|
||||
* may be sufficient.
|
||||
*
|
||||
* Input Parameters:
|
||||
* group - The group to which the thread belonged.
|
||||
* tcb - The TCB of the task or thread whose the address environment will
|
||||
* be released.
|
||||
*
|
||||
@ -824,9 +813,9 @@ int up_addrenv_attach(struct task_group_s *group, struct tcb_s *tcb)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int up_addrenv_detach(struct task_group_s *group, struct tcb_s *tcb)
|
||||
int up_addrenv_detach(struct tcb_s *tcb)
|
||||
{
|
||||
binfo("group=%p tcb=%p\n", group, tcb);
|
||||
binfo("tcb=%p\n", tcb);
|
||||
|
||||
/* Nothing needs to be done in this implementation */
|
||||
|
||||
|
@ -66,7 +66,7 @@
|
||||
int up_shmat(uintptr_t *pages, unsigned int npages, uintptr_t vaddr)
|
||||
{
|
||||
struct tcb_s *tcb = nxsched_self();
|
||||
struct task_group_s *group;
|
||||
struct arch_addrenv_s *addrenv;
|
||||
uintptr_t *l1entry;
|
||||
uint32_t *l2table;
|
||||
irqstate_t flags;
|
||||
@ -79,11 +79,11 @@ int up_shmat(uintptr_t *pages, unsigned int npages, uintptr_t vaddr)
|
||||
|
||||
/* Sanity checks */
|
||||
|
||||
DEBUGASSERT(pages && npages > 0 && tcb && tcb->group);
|
||||
DEBUGASSERT(pages && npages > 0 && tcb && tcb->addrenv_own);
|
||||
DEBUGASSERT(vaddr >= CONFIG_ARCH_SHM_VBASE && vaddr < ARCH_SHM_VEND);
|
||||
DEBUGASSERT(MM_ISALIGNED(vaddr));
|
||||
|
||||
group = tcb->group;
|
||||
addrenv = &tcb->addrenv_own->addrenv;
|
||||
|
||||
/* Loop until all pages have been mapped into the caller's address space. */
|
||||
|
||||
@ -97,7 +97,7 @@ int up_shmat(uintptr_t *pages, unsigned int npages, uintptr_t vaddr)
|
||||
* address.
|
||||
*/
|
||||
|
||||
l1entry = group->tg_addrenv.shm[shmndx];
|
||||
l1entry = addrenv->shm[shmndx];
|
||||
if (l1entry == NULL)
|
||||
{
|
||||
/* No.. Allocate one physical page for the L2 page table */
|
||||
@ -115,7 +115,7 @@ int up_shmat(uintptr_t *pages, unsigned int npages, uintptr_t vaddr)
|
||||
*/
|
||||
|
||||
flags = enter_critical_section();
|
||||
group->tg_addrenv.shm[shmndx] = (uintptr_t *)paddr;
|
||||
addrenv->shm[shmndx] = (uintptr_t *)paddr;
|
||||
|
||||
/* Get the virtual address corresponding to the physical page
|
||||
* address.
|
||||
@ -189,7 +189,7 @@ int up_shmat(uintptr_t *pages, unsigned int npages, uintptr_t vaddr)
|
||||
int up_shmdt(uintptr_t vaddr, unsigned int npages)
|
||||
{
|
||||
struct tcb_s *tcb = nxsched_self();
|
||||
struct task_group_s *group;
|
||||
struct arch_addrenv_s *addrenv;
|
||||
uintptr_t *l1entry;
|
||||
uint32_t *l2table;
|
||||
irqstate_t flags;
|
||||
@ -201,11 +201,11 @@ int up_shmdt(uintptr_t vaddr, unsigned int npages)
|
||||
|
||||
/* Sanity checks */
|
||||
|
||||
DEBUGASSERT(npages > 0 && tcb && tcb->group);
|
||||
DEBUGASSERT(npages > 0 && tcb && tcb->addrenv_own);
|
||||
DEBUGASSERT(vaddr >= CONFIG_ARCH_SHM_VBASE && vaddr < ARCH_SHM_VEND);
|
||||
DEBUGASSERT(MM_ISALIGNED(vaddr));
|
||||
|
||||
group = tcb->group;
|
||||
addrenv = &tcb->addrenv_own->addrenv;
|
||||
|
||||
/* Loop until all pages have been unmapped from the caller's address
|
||||
* space.
|
||||
@ -219,7 +219,7 @@ int up_shmdt(uintptr_t vaddr, unsigned int npages)
|
||||
|
||||
/* Get the level 1 page table entry for this virtual address */
|
||||
|
||||
l1entry = group->tg_addrenv.shm[shmndx];
|
||||
l1entry = addrenv->shm[shmndx];
|
||||
DEBUGASSERT(l1entry != NULL);
|
||||
|
||||
/* Get the physical address of the L2 page table from the L1 page
|
||||
|
@ -28,13 +28,13 @@
|
||||
#include <assert.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/addrenv.h>
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/board.h>
|
||||
#include <arch/board/board.h>
|
||||
|
||||
#include "arm_internal.h"
|
||||
#include "group/group.h"
|
||||
#include "gic.h"
|
||||
|
||||
/****************************************************************************
|
||||
@ -85,7 +85,7 @@ uint32_t *arm_doirq(int irq, uint32_t *regs)
|
||||
* thread at the head of the ready-to-run list.
|
||||
*/
|
||||
|
||||
group_addrenv(NULL);
|
||||
addrenv_switch(NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -183,16 +183,16 @@ static int get_pgtable(arch_addrenv_t *addrenv, uintptr_t vaddr)
|
||||
uintptr_t pgalloc(uintptr_t brkaddr, unsigned int npages)
|
||||
{
|
||||
struct tcb_s *tcb = nxsched_self();
|
||||
struct task_group_s *group;
|
||||
struct arch_addrenv_s *addrenv;
|
||||
uint32_t *l2table;
|
||||
irqstate_t flags;
|
||||
uintptr_t paddr;
|
||||
unsigned int index;
|
||||
|
||||
binfo("tcb->pid=%d tcb->group=%p\n", tcb->pid, tcb->group);
|
||||
binfo("tcb->pid=%d tcb->group=%p\n", tcb->pid, tcb->addrenv_own);
|
||||
binfo("brkaddr=%x npages=%d\n", brkaddr, npages);
|
||||
DEBUGASSERT(tcb && tcb->group);
|
||||
group = tcb->group;
|
||||
DEBUGASSERT(tcb && tcb->addrenv_own);
|
||||
addrenv = &tcb->addrenv_own->addrenv;
|
||||
|
||||
/* The current implementation only supports extending the user heap
|
||||
* region as part of the implementation of user sbrk(). This function
|
||||
@ -200,8 +200,6 @@ uintptr_t pgalloc(uintptr_t brkaddr, unsigned int npages)
|
||||
* space and (2) extending the kernel memory regions as well.
|
||||
*/
|
||||
|
||||
DEBUGASSERT((group->tg_flags & GROUP_FLAG_ADDRENV) != 0);
|
||||
|
||||
/* brkaddr = 0 means that no heap has yet been allocated */
|
||||
|
||||
if (brkaddr == 0)
|
||||
@ -216,7 +214,7 @@ uintptr_t pgalloc(uintptr_t brkaddr, unsigned int npages)
|
||||
{
|
||||
/* Get the physical address of the level 2 page table */
|
||||
|
||||
paddr = get_pgtable(&group->tg_addrenv, brkaddr);
|
||||
paddr = get_pgtable(addrenv, brkaddr);
|
||||
binfo("l2 page table (paddr=%x)\n", paddr);
|
||||
binfo("brkaddr=%x\n", brkaddr);
|
||||
if (paddr == 0)
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include <debug.h>
|
||||
#include <syscall.h>
|
||||
|
||||
#include <nuttx/addrenv.h>
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/sched.h>
|
||||
#include <nuttx/addrenv.h>
|
||||
@ -38,7 +39,6 @@
|
||||
#include "addrenv.h"
|
||||
#include "arm.h"
|
||||
#include "arm_internal.h"
|
||||
#include "group/group.h"
|
||||
#include "signal/signal.h"
|
||||
|
||||
/****************************************************************************
|
||||
@ -596,7 +596,7 @@ uint32_t *arm_syscall(uint32_t *regs)
|
||||
* thread at the head of the ready-to-run list.
|
||||
*/
|
||||
|
||||
group_addrenv(NULL);
|
||||
addrenv_switch(NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -33,7 +33,6 @@
|
||||
#include <arch/board/board.h>
|
||||
|
||||
#include "arm_internal.h"
|
||||
#include "group/group.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
|
@ -207,7 +207,7 @@ size_t up_check_tcbstack(struct tcb_s *tcb)
|
||||
|
||||
if ((tcb->flags & TCB_FLAG_TTYPE_MASK) != TCB_FLAG_TTYPE_KERNEL)
|
||||
{
|
||||
up_addrenv_select(&tcb->group->tg_addrenv, &oldenv);
|
||||
up_addrenv_select(&tcb->addrenv_own->addrenv, &oldenv);
|
||||
saved = true;
|
||||
}
|
||||
#endif
|
||||
|
@ -824,7 +824,7 @@ int up_addrenv_clone(const arch_addrenv_t *src,
|
||||
* group.
|
||||
*
|
||||
* Input Parameters:
|
||||
* group - The task group to which the new thread belongs.
|
||||
* ptcb - The tcb of the parent task.
|
||||
* tcb - The tcb of the thread needing the address environment.
|
||||
*
|
||||
* Returned Value:
|
||||
@ -832,7 +832,7 @@ int up_addrenv_clone(const arch_addrenv_t *src,
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int up_addrenv_attach(struct task_group_s *group, struct tcb_s *tcb)
|
||||
int up_addrenv_attach(struct tcb_s *ptcb, struct tcb_s *tcb)
|
||||
{
|
||||
/* There is nothing that needs to be done */
|
||||
|
||||
@ -849,12 +849,7 @@ int up_addrenv_attach(struct task_group_s *group, struct tcb_s *tcb)
|
||||
* task group is itself destroyed. Any resources unique to this thread
|
||||
* may be destroyed now.
|
||||
*
|
||||
* NOTE: In some platforms, nothing will need to be done in this case.
|
||||
* Simply being a member of the group that has the address environment
|
||||
* may be sufficient.
|
||||
*
|
||||
* Input Parameters:
|
||||
* group - The group to which the thread belonged.
|
||||
* tcb - The TCB of the task or thread whose the address environment will
|
||||
* be released.
|
||||
*
|
||||
@ -863,7 +858,7 @@ int up_addrenv_attach(struct task_group_s *group, struct tcb_s *tcb)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int up_addrenv_detach(struct task_group_s *group, struct tcb_s *tcb)
|
||||
int up_addrenv_detach(struct tcb_s *tcb)
|
||||
{
|
||||
/* There is nothing that needs to be done */
|
||||
|
||||
|
@ -66,21 +66,21 @@
|
||||
|
||||
int up_shmat(uintptr_t *pages, unsigned int npages, uintptr_t vaddr)
|
||||
{
|
||||
struct tcb_s *tcb = nxsched_self();
|
||||
struct task_group_s *group;
|
||||
uintptr_t ptlast;
|
||||
uintptr_t ptlevel;
|
||||
uintptr_t paddr;
|
||||
struct tcb_s *tcb = nxsched_self();
|
||||
struct arch_addrenv_s *addrenv;
|
||||
uintptr_t ptlast;
|
||||
uintptr_t ptlevel;
|
||||
uintptr_t paddr;
|
||||
|
||||
/* Sanity checks */
|
||||
|
||||
DEBUGASSERT(tcb && tcb->group);
|
||||
DEBUGASSERT(tcb && tcb->addrenv_own);
|
||||
DEBUGASSERT(pages != NULL && npages > 0);
|
||||
DEBUGASSERT(vaddr >= CONFIG_ARCH_SHM_VBASE && vaddr < ARCH_SHM_VEND);
|
||||
DEBUGASSERT(MM_ISALIGNED(vaddr));
|
||||
|
||||
group = tcb->group;
|
||||
ptlevel = RV_MMU_PT_LEVELS;
|
||||
addrenv = &tcb->addrenv_own->addrenv;
|
||||
ptlevel = RV_MMU_PT_LEVELS;
|
||||
|
||||
/* Add the references to pages[] into the caller's address environment */
|
||||
|
||||
@ -88,7 +88,7 @@ int up_shmat(uintptr_t *pages, unsigned int npages, uintptr_t vaddr)
|
||||
{
|
||||
/* Get the address of the last level page table */
|
||||
|
||||
ptlast = riscv_pgvaddr(riscv_get_pgtable(&group->tg_addrenv, vaddr));
|
||||
ptlast = riscv_pgvaddr(riscv_get_pgtable(addrenv, vaddr));
|
||||
if (!ptlast)
|
||||
{
|
||||
return -ENOMEM;
|
||||
@ -127,23 +127,23 @@ int up_shmat(uintptr_t *pages, unsigned int npages, uintptr_t vaddr)
|
||||
|
||||
int up_shmdt(uintptr_t vaddr, unsigned int npages)
|
||||
{
|
||||
struct tcb_s *tcb = nxsched_self();
|
||||
struct task_group_s *group;
|
||||
uintptr_t ptlast;
|
||||
uintptr_t ptprev;
|
||||
uintptr_t ptlevel;
|
||||
uintptr_t paddr;
|
||||
struct tcb_s *tcb = nxsched_self();
|
||||
struct arch_addrenv_s *addrenv;
|
||||
uintptr_t ptlast;
|
||||
uintptr_t ptprev;
|
||||
uintptr_t ptlevel;
|
||||
uintptr_t paddr;
|
||||
|
||||
/* Sanity checks */
|
||||
|
||||
DEBUGASSERT(tcb && tcb->group);
|
||||
DEBUGASSERT(tcb && tcb->addrenv_own);
|
||||
DEBUGASSERT(npages > 0);
|
||||
DEBUGASSERT(vaddr >= CONFIG_ARCH_SHM_VBASE && vaddr < ARCH_SHM_VEND);
|
||||
DEBUGASSERT(MM_ISALIGNED(vaddr));
|
||||
|
||||
group = tcb->group;
|
||||
ptlevel = ARCH_SPGTS;
|
||||
ptprev = riscv_pgvaddr(group->tg_addrenv.spgtables[ARCH_SPGTS - 1]);
|
||||
addrenv = &tcb->addrenv_own->addrenv;
|
||||
ptlevel = ARCH_SPGTS;
|
||||
ptprev = riscv_pgvaddr(addrenv->spgtables[ARCH_SPGTS - 1]);
|
||||
if (!ptprev)
|
||||
{
|
||||
/* Something is very wrong */
|
||||
|
@ -163,7 +163,7 @@ size_t up_check_tcbstack(struct tcb_s *tcb)
|
||||
|
||||
if ((tcb->flags & TCB_FLAG_TTYPE_MASK) != TCB_FLAG_TTYPE_KERNEL)
|
||||
{
|
||||
up_addrenv_select(&tcb->group->tg_addrenv, &oldenv);
|
||||
up_addrenv_select(&tcb->addrenv_own->addrenv, &oldenv);
|
||||
saved = true;
|
||||
}
|
||||
#endif
|
||||
|
@ -28,12 +28,12 @@
|
||||
#include <assert.h>
|
||||
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/addrenv.h>
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/board.h>
|
||||
#include <arch/board/board.h>
|
||||
|
||||
#include "riscv_internal.h"
|
||||
#include "group/group.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
@ -98,7 +98,7 @@ uintptr_t *riscv_doirq(int irq, uintptr_t *regs)
|
||||
* thread at the head of the ready-to-run list.
|
||||
*/
|
||||
|
||||
group_addrenv(NULL);
|
||||
addrenv_switch(NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -94,14 +94,14 @@
|
||||
|
||||
uintptr_t pgalloc(uintptr_t brkaddr, unsigned int npages)
|
||||
{
|
||||
struct tcb_s *tcb = nxsched_self();
|
||||
struct task_group_s *group;
|
||||
uintptr_t ptlast;
|
||||
uintptr_t paddr;
|
||||
uintptr_t vaddr;
|
||||
struct tcb_s *tcb = nxsched_self();
|
||||
struct arch_addrenv_s *addrenv;
|
||||
uintptr_t ptlast;
|
||||
uintptr_t paddr;
|
||||
uintptr_t vaddr;
|
||||
|
||||
DEBUGASSERT(tcb && tcb->group);
|
||||
group = tcb->group;
|
||||
DEBUGASSERT(tcb && tcb->addrenv_own);
|
||||
addrenv = &tcb->addrenv_own->addrenv;
|
||||
|
||||
/* The current implementation only supports extending the user heap
|
||||
* region as part of the implementation of user sbrk(). This function
|
||||
@ -109,13 +109,11 @@ uintptr_t pgalloc(uintptr_t brkaddr, unsigned int npages)
|
||||
* space and (2) extending the kernel memory regions as well.
|
||||
*/
|
||||
|
||||
DEBUGASSERT((group->tg_flags & GROUP_FLAG_ADDRENV) != 0);
|
||||
|
||||
/* brkaddr = 0 means that no heap has yet been allocated */
|
||||
|
||||
if (!brkaddr)
|
||||
{
|
||||
brkaddr = group->tg_addrenv.heapvbase;
|
||||
brkaddr = addrenv->heapvbase;
|
||||
}
|
||||
|
||||
/* Start mapping from the old heap break address */
|
||||
@ -124,14 +122,14 @@ uintptr_t pgalloc(uintptr_t brkaddr, unsigned int npages)
|
||||
|
||||
/* Sanity checks */
|
||||
|
||||
DEBUGASSERT(brkaddr >= group->tg_addrenv.heapvbase);
|
||||
DEBUGASSERT(brkaddr >= addrenv->heapvbase);
|
||||
DEBUGASSERT(MM_ISALIGNED(brkaddr));
|
||||
|
||||
for (; npages > 0; npages--)
|
||||
{
|
||||
/* Get the address of the last level page table */
|
||||
|
||||
ptlast = riscv_pgvaddr(riscv_get_pgtable(&group->tg_addrenv, vaddr));
|
||||
ptlast = riscv_pgvaddr(riscv_get_pgtable(addrenv, vaddr));
|
||||
if (!ptlast)
|
||||
{
|
||||
return 0;
|
||||
|
@ -26,8 +26,9 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <nuttx/addrenv.h>
|
||||
|
||||
#include "riscv_internal.h"
|
||||
#include "group/group.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
@ -52,7 +53,7 @@ void *riscv_perform_syscall(uintptr_t *regs)
|
||||
* thread at the head of the ready-to-run list.
|
||||
*/
|
||||
|
||||
group_addrenv(NULL);
|
||||
addrenv_switch(NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <nuttx/addrenv.h>
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/board.h>
|
||||
@ -35,7 +36,6 @@
|
||||
|
||||
#include "chip/switch.h"
|
||||
#include "z80_internal.h"
|
||||
#include "group/group.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
@ -82,7 +82,7 @@ FAR chipreg_t *z80_doirq(uint8_t irq, FAR chipreg_t *regs)
|
||||
* ready-to-run list.
|
||||
*/
|
||||
|
||||
group_addrenv(NULL);
|
||||
addrenv_switch(NULL);
|
||||
}
|
||||
|
||||
regs = newregs;
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include <sched.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/addrenv.h>
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/irq.h>
|
||||
#ifdef CONFIG_DUMP_ON_EXIT
|
||||
@ -143,7 +144,7 @@ void up_exit(int status)
|
||||
* the ready-to-run list.
|
||||
*/
|
||||
|
||||
group_addrenv(tcb);
|
||||
addrenv_switch(tcb);
|
||||
#endif
|
||||
|
||||
/* Then switch contexts */
|
||||
|
@ -28,13 +28,13 @@
|
||||
#include <assert.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/addrenv.h>
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/sched.h>
|
||||
|
||||
#include "chip.h"
|
||||
#include "chip/switch.h"
|
||||
#include "sched/sched.h"
|
||||
#include "group/group.h"
|
||||
#include "clock/clock.h"
|
||||
#include "z80_internal.h"
|
||||
|
||||
@ -99,7 +99,7 @@ void up_switch_context(FAR struct tcb_s *tcb, FAR struct tcb_s *rtcb)
|
||||
* thread at the head of the ready-to-run list.
|
||||
*/
|
||||
|
||||
group_addrenv(tcb);
|
||||
addrenv_switch(tcb);
|
||||
#endif
|
||||
/* Update scheduler parameters */
|
||||
|
||||
|
@ -560,7 +560,7 @@ int up_addrenv_clone(FAR const arch_addrenv_t *src,
|
||||
* group.
|
||||
*
|
||||
* Input Parameters:
|
||||
* group - The task group to which the new thread belongs.
|
||||
* ptcb - The tcb of the parent task.
|
||||
* tcb - The tcb of the thread needing the address environment.
|
||||
*
|
||||
* Returned Value:
|
||||
@ -568,7 +568,7 @@ int up_addrenv_clone(FAR const arch_addrenv_t *src,
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int up_addrenv_attach(FAR struct task_group_s *group, FAR struct tcb_s *tcb)
|
||||
int up_addrenv_attach(FAR struct tcb_s *ptcb, FAR struct tcb_s *tcb)
|
||||
{
|
||||
/* There is nothing that needs to be done */
|
||||
|
||||
@ -590,7 +590,6 @@ int up_addrenv_attach(FAR struct task_group_s *group, FAR struct tcb_s *tcb)
|
||||
* may be sufficient.
|
||||
*
|
||||
* Input Parameters:
|
||||
* group - The group to which the thread belonged.
|
||||
* tcb - The TCB of the task or thread whose the address environment will
|
||||
* be released.
|
||||
*
|
||||
@ -599,7 +598,7 @@ int up_addrenv_attach(FAR struct task_group_s *group, FAR struct tcb_s *tcb)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int up_addrenv_detach(FAR struct task_group_s *group, FAR struct tcb_s *tcb)
|
||||
int up_addrenv_detach(FAR struct tcb_s *tcb)
|
||||
{
|
||||
/* There is nothing that needs to be done */
|
||||
|
||||
|
@ -239,18 +239,14 @@ int exec_module(FAR const struct binary_s *binp,
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_ADDRENV
|
||||
/* Assign the address environment to the new task group */
|
||||
/* Attach the address environment to the new task */
|
||||
|
||||
ret = up_addrenv_clone(&binp->addrenv, &tcb->cmn.group->tg_addrenv);
|
||||
ret = addrenv_attach((FAR struct tcb_s *)tcb, &binp->addrenv);
|
||||
if (ret < 0)
|
||||
{
|
||||
berr("ERROR: up_addrenv_clone() failed: %d\n", ret);
|
||||
berr("ERROR: addrenv_attach() failed: %d\n", ret);
|
||||
goto errout_with_tcbinit;
|
||||
}
|
||||
|
||||
/* Mark that this group has an address environment */
|
||||
|
||||
tcb->cmn.group->tg_flags |= GROUP_FLAG_ADDRENV;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BINFMT_CONSTRUCTORS
|
||||
|
@ -32,6 +32,8 @@
|
||||
# include <nuttx/mm/mm.h>
|
||||
#endif
|
||||
|
||||
#include <arch/arch.h>
|
||||
|
||||
#ifdef CONFIG_ARCH_ADDRENV
|
||||
|
||||
/****************************************************************************
|
||||
@ -218,6 +220,11 @@
|
||||
(CONFIG_ARCH_PGPOOL_VBASE + CONFIG_ARCH_PGPOOL_SIZE)
|
||||
|
||||
#endif
|
||||
/****************************************************************************
|
||||
* Public Type Definitions
|
||||
****************************************************************************/
|
||||
|
||||
struct tcb_s; /* Forward reference to TCB */
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
@ -225,6 +232,13 @@
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
struct addrenv_s
|
||||
{
|
||||
struct arch_addrenv_s addrenv; /* The address environment page directory */
|
||||
};
|
||||
|
||||
typedef struct addrenv_s addrenv_t;
|
||||
|
||||
/* Reserved .bss/.data region. In the kernel build (CONFIG_BUILD_KERNEL),
|
||||
* the region at the beginning of the .bss/.data region is reserved for use
|
||||
* by the OS. This reserved region contains support for:
|
||||
@ -269,6 +283,83 @@ struct addrenv_reserve_s
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: addrenv_allocate
|
||||
*
|
||||
* Description:
|
||||
* Allocate an address environment for a new process.
|
||||
*
|
||||
* Input Parameters:
|
||||
* tcb - The tcb of the newly created task.
|
||||
* ttype - The type of the task.
|
||||
*
|
||||
* Returned Value:
|
||||
* This is a NuttX internal function so it follows the convention that
|
||||
* 0 (OK) is returned on success and a negated errno is returned on
|
||||
* failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int addrenv_allocate(FAR struct tcb_s *tcb, uint8_t ttype);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: addrenv_free
|
||||
*
|
||||
* Description:
|
||||
* Free an address environment for a process.
|
||||
*
|
||||
* Input Parameters:
|
||||
* tcb - The tcb of the task.
|
||||
*
|
||||
* Returned Value:
|
||||
* This is a NuttX internal function so it follows the convention that
|
||||
* 0 (OK) is returned on success and a negated errno is returned on
|
||||
* failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int addrenv_free(FAR struct tcb_s *tcb);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: addrenv_switch
|
||||
*
|
||||
* Description:
|
||||
* Switch to an address environment.
|
||||
*
|
||||
* Input Parameters:
|
||||
* tcb - The tcb of the task to switch to, or NULL to use the task at the
|
||||
* head of the ready-to-run list.
|
||||
*
|
||||
* Returned Value:
|
||||
* This is a NuttX internal function so it follows the convention that
|
||||
* 0 (OK) is returned on success and a negated errno is returned on
|
||||
* failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int addrenv_switch(FAR struct tcb_s *tcb);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: addrenv_attach
|
||||
*
|
||||
* Description:
|
||||
* Attach address environment to a newly process. Called by exec() right
|
||||
* before injecting the new process into the system.
|
||||
*
|
||||
* Input Parameters:
|
||||
* tcb - The tcb of the newly loaded task.
|
||||
* addrenv - The address environment that is attached.
|
||||
*
|
||||
* Returned Value:
|
||||
* This is a NuttX internal function so it follows the convention that
|
||||
* 0 (OK) is returned on success and a negated errno is returned on
|
||||
* failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int addrenv_attach(FAR struct tcb_s *tcb,
|
||||
FAR const struct arch_addrenv_s *addrenv);
|
||||
|
||||
/****************************************************************************
|
||||
* Address Environment Interfaces
|
||||
*
|
||||
|
@ -1094,13 +1094,9 @@ int up_addrenv_clone(FAR const arch_addrenv_t *src,
|
||||
* is created that needs to share the address environment of its task
|
||||
* group.
|
||||
*
|
||||
* NOTE: In some platforms, nothing will need to be done in this case.
|
||||
* Simply being a member of the group that has the address environment
|
||||
* may be sufficient.
|
||||
*
|
||||
* Input Parameters:
|
||||
* group - The task group to which the new thread belongs.
|
||||
* tcb - The TCB of the thread needing the address environment.
|
||||
* ptcb - The tcb of the parent task.
|
||||
* tcb - The tcb of the thread needing the address environment.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success; a negated errno value on failure.
|
||||
@ -1108,7 +1104,7 @@ int up_addrenv_clone(FAR const arch_addrenv_t *src,
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ARCH_ADDRENV
|
||||
int up_addrenv_attach(FAR struct task_group_s *group, FAR struct tcb_s *tcb);
|
||||
int up_addrenv_attach(FAR struct tcb_s *ptcb, FAR struct tcb_s *tcb);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
@ -1121,12 +1117,7 @@ int up_addrenv_attach(FAR struct task_group_s *group, FAR struct tcb_s *tcb);
|
||||
* task group is itself destroyed. Any resources unique to this thread
|
||||
* may be destroyed now.
|
||||
*
|
||||
* NOTE: In some platforms, nothing will need to be done in this case.
|
||||
* Simply being a member of the group that has the address environment
|
||||
* may be sufficient.
|
||||
*
|
||||
* Input Parameters:
|
||||
* group - The group to which the thread belonged.
|
||||
* tcb - The TCB of the task or thread whose the address environment will
|
||||
* be released.
|
||||
*
|
||||
@ -1136,7 +1127,7 @@ int up_addrenv_attach(FAR struct task_group_s *group, FAR struct tcb_s *tcb);
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ARCH_ADDRENV
|
||||
int up_addrenv_detach(FAR struct task_group_s *group, FAR struct tcb_s *tcb);
|
||||
int up_addrenv_detach(FAR struct tcb_s *tcb);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include <pthread.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <nuttx/addrenv.h>
|
||||
#include <nuttx/clock.h>
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/mutex.h>
|
||||
@ -107,10 +108,9 @@
|
||||
/* Values for struct task_group tg_flags */
|
||||
|
||||
#define GROUP_FLAG_NOCLDWAIT (1 << 0) /* Bit 0: Do not retain child exit status */
|
||||
#define GROUP_FLAG_ADDRENV (1 << 1) /* Bit 1: Group has an address environment */
|
||||
#define GROUP_FLAG_PRIVILEGED (1 << 2) /* Bit 2: Group is privileged */
|
||||
#define GROUP_FLAG_DELETED (1 << 3) /* Bit 3: Group has been deleted but not yet freed */
|
||||
/* Bits 4-7: Available */
|
||||
#define GROUP_FLAG_PRIVILEGED (1 << 1) /* Bit 1: Group is privileged */
|
||||
#define GROUP_FLAG_DELETED (1 << 2) /* Bit 2: Group has been deleted but not yet freed */
|
||||
/* Bits 3-7: Available */
|
||||
|
||||
/* Values for struct child_status_s ch_flags */
|
||||
|
||||
@ -418,7 +418,7 @@ struct binary_s; /* Forward reference
|
||||
|
||||
struct task_group_s
|
||||
{
|
||||
#if defined(HAVE_GROUP_MEMBERS) || defined(CONFIG_ARCH_ADDRENV)
|
||||
#if defined(HAVE_GROUP_MEMBERS)
|
||||
struct task_group_s *flink; /* Supports a singly linked list */
|
||||
#endif
|
||||
pid_t tg_pid; /* The ID of the task within the group */
|
||||
@ -512,12 +512,6 @@ struct task_group_s
|
||||
|
||||
struct filelist tg_filelist; /* Maps file descriptor to file */
|
||||
|
||||
#ifdef CONFIG_ARCH_ADDRENV
|
||||
/* Address Environment ****************************************************/
|
||||
|
||||
arch_addrenv_t tg_addrenv; /* Task group address environment */
|
||||
#endif
|
||||
|
||||
/* Virtual memory mapping info ********************************************/
|
||||
|
||||
struct mm_map_s tg_mm_map; /* Task mmappings */
|
||||
@ -542,6 +536,12 @@ struct tcb_s
|
||||
|
||||
FAR struct task_group_s *group; /* Pointer to shared task group data */
|
||||
|
||||
/* Address Environment ****************************************************/
|
||||
|
||||
#ifdef CONFIG_ARCH_ADDRENV
|
||||
FAR struct addrenv_s *addrenv_own; /* Task (group) own memory mappings */
|
||||
#endif
|
||||
|
||||
/* Task Management Fields *************************************************/
|
||||
|
||||
pid_t pid; /* This is the ID of the thread */
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
include $(TOPDIR)/Make.defs
|
||||
|
||||
include addrenv/Make.defs
|
||||
include clock/Make.defs
|
||||
include environ/Make.defs
|
||||
include group/Make.defs
|
||||
|
28
sched/addrenv/Make.defs
Normal file
28
sched/addrenv/Make.defs
Normal file
@ -0,0 +1,28 @@
|
||||
############################################################################
|
||||
# sched/addrenv/Make.defs
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership. The
|
||||
# ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance with the
|
||||
# License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
############################################################################
|
||||
|
||||
ifeq ($(CONFIG_ARCH_ADDRENV),y)
|
||||
CSRCS += addrenv.c
|
||||
endif
|
||||
|
||||
# Include addrenv build support
|
||||
|
||||
DEPPATH += --dep-path addrenv
|
||||
VPATH += :addrenv
|
@ -1,5 +1,5 @@
|
||||
/****************************************************************************
|
||||
* sched/group/group_addrenv.c
|
||||
* sched/addrenv/addrenv.c
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
@ -27,33 +27,37 @@
|
||||
#include <assert.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/addrenv.h>
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/sched.h>
|
||||
|
||||
#include "sched/sched.h"
|
||||
#include "group/group.h"
|
||||
|
||||
#ifdef CONFIG_ARCH_ADDRENV
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* This variable holds the current task group. This pointer is NULL
|
||||
* if the current task is a kernel thread that has no address environment
|
||||
* (other than the kernel context).
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/* This variable holds the current address environment. These contents are
|
||||
* _never_ NULL, besides when the system is started and there are only the
|
||||
* initial kernel mappings available.
|
||||
*
|
||||
* This must only be accessed with interrupts disabled.
|
||||
*
|
||||
* REVISIT: Try to get rid of this, global bookkeeping for this is dangerous.
|
||||
*/
|
||||
|
||||
FAR struct task_group_s *g_group_current[CONFIG_SMP_NCPUS];
|
||||
static FAR struct addrenv_s *g_addrenv[CONFIG_SMP_NCPUS];
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: group_addrenv
|
||||
* Name: addrenv_switch
|
||||
*
|
||||
* Description:
|
||||
* Instantiate the group address environment for the current thread at the
|
||||
@ -80,10 +84,10 @@ FAR struct task_group_s *g_group_current[CONFIG_SMP_NCPUS];
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int group_addrenv(FAR struct tcb_s *tcb)
|
||||
int addrenv_switch(FAR struct tcb_s *tcb)
|
||||
{
|
||||
FAR struct task_group_s *group;
|
||||
FAR struct task_group_s *oldgroup;
|
||||
FAR struct addrenv_s *curr;
|
||||
FAR struct addrenv_s *next;
|
||||
irqstate_t flags;
|
||||
int cpu;
|
||||
int ret;
|
||||
@ -97,12 +101,12 @@ int group_addrenv(FAR struct tcb_s *tcb)
|
||||
tcb = this_task();
|
||||
}
|
||||
|
||||
DEBUGASSERT(tcb && tcb->group);
|
||||
group = tcb->group;
|
||||
DEBUGASSERT(tcb);
|
||||
next = tcb->mm_curr;
|
||||
|
||||
/* Does the group have an address environment? */
|
||||
|
||||
if ((group->tg_flags & GROUP_FLAG_ADDRENV) == 0)
|
||||
if (!next)
|
||||
{
|
||||
/* No... just return perhaps leaving a different address environment
|
||||
* intact.
|
||||
@ -111,24 +115,24 @@ int group_addrenv(FAR struct tcb_s *tcb)
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* Are we going to change address environments? */
|
||||
|
||||
flags = enter_critical_section();
|
||||
|
||||
cpu = this_cpu();
|
||||
oldgroup = g_group_current[cpu];
|
||||
if (group != oldgroup)
|
||||
curr = g_addrenv[cpu];
|
||||
|
||||
/* Are we going to change address environments? */
|
||||
|
||||
if (curr != next)
|
||||
{
|
||||
/* Yes.. Is there a current address environment in place? */
|
||||
|
||||
if (oldgroup)
|
||||
if (curr)
|
||||
{
|
||||
/* We need to flush the D-Cache and Invalidate the I-Cache for
|
||||
* the group whose environment is disappearing.
|
||||
*/
|
||||
|
||||
DEBUGASSERT((oldgroup->tg_flags & GROUP_FLAG_ADDRENV) != 0);
|
||||
up_addrenv_coherent(&oldgroup->tg_addrenv);
|
||||
up_addrenv_coherent(&curr->addrenv);
|
||||
}
|
||||
|
||||
/* Instantiate the new address environment (removing the old
|
||||
@ -137,19 +141,115 @@ int group_addrenv(FAR struct tcb_s *tcb)
|
||||
* instantiated.
|
||||
*/
|
||||
|
||||
ret = up_addrenv_select(&group->tg_addrenv, NULL);
|
||||
ret = up_addrenv_select(&next->addrenv, NULL);
|
||||
if (ret < 0)
|
||||
{
|
||||
berr("ERROR: up_addrenv_select failed: %d\n", ret);
|
||||
}
|
||||
|
||||
/* Save the new, current group */
|
||||
/* Save the new, current address environment group */
|
||||
|
||||
g_group_current[cpu] = group;
|
||||
g_addrenv[cpu] = next;
|
||||
}
|
||||
|
||||
leave_critical_section(flags);
|
||||
return OK;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_ARCH_ADDRENV */
|
||||
/****************************************************************************
|
||||
* Name: addrenv_allocate
|
||||
*
|
||||
* Description:
|
||||
* Allocate an address environment for a new process.
|
||||
*
|
||||
* Input Parameters:
|
||||
* tcb - The tcb of the newly created task.
|
||||
* ttype - The type of the task.
|
||||
*
|
||||
* Returned Value:
|
||||
* This is a NuttX internal function so it follows the convention that
|
||||
* 0 (OK) is returned on success and a negated errno is returned on
|
||||
* failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int addrenv_allocate(FAR struct tcb_s *tcb, uint8_t ttype)
|
||||
{
|
||||
int ret = OK;
|
||||
|
||||
if ((ttype & TCB_FLAG_TTYPE_MASK) == TCB_FLAG_TTYPE_KERNEL)
|
||||
{
|
||||
tcb->addrenv_own = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
tcb->addrenv_own = (FAR struct addrenv_s *)
|
||||
kmm_zalloc(sizeof(struct addrenv_s));
|
||||
if (tcb->addrenv_own == NULL)
|
||||
{
|
||||
ret = -ENOMEM;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: addrenv_free
|
||||
*
|
||||
* Description:
|
||||
* Free an address environment for a process.
|
||||
*
|
||||
* Input Parameters:
|
||||
* tcb - The tcb of the task.
|
||||
*
|
||||
* Returned Value:
|
||||
* This is a NuttX internal function so it follows the convention that
|
||||
* 0 (OK) is returned on success and a negated errno is returned on
|
||||
* failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int addrenv_free(FAR struct tcb_s *tcb)
|
||||
{
|
||||
if (tcb->addrenv_own != NULL)
|
||||
{
|
||||
kmm_free(tcb->addrenv_own);
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: addrenv_attach
|
||||
*
|
||||
* Description:
|
||||
* Attach address environment to a newly created group. Called by exec()
|
||||
* right before injecting the new process into the system.
|
||||
*
|
||||
* Input Parameters:
|
||||
* tcb - The tcb of the newly loaded task.
|
||||
* addrenv - The address environment that is attached.
|
||||
*
|
||||
* Returned Value:
|
||||
* This is a NuttX internal function so it follows the convention that
|
||||
* 0 (OK) is returned on success and a negated errno is returned on
|
||||
* failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int addrenv_attach(FAR struct tcb_s *tcb,
|
||||
FAR const struct arch_addrenv_s *addrenv)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Clone the address environment for us */
|
||||
|
||||
ret = up_addrenv_clone(addrenv, &tcb->addrenv_own->addrenv);
|
||||
if (ret < 0)
|
||||
{
|
||||
berr("ERROR: up_addrenv_clone failed: %d\n", ret);
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
@ -36,10 +36,6 @@ ifeq ($(CONFIG_SCHED_USER_IDENTITY),y)
|
||||
CSRCS += group_setuid.c group_setgid.c group_getuid.c group_getgid.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_ARCH_ADDRENV),y)
|
||||
CSRCS += group_addrenv.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_SIG_SIGSTOP_ACTION),y)
|
||||
CSRCS += group_suspendchildren.c group_continue.c
|
||||
endif
|
||||
|
@ -44,23 +44,12 @@ typedef int (*foreachchild_t)(pid_t pid, FAR void *arg);
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(HAVE_GROUP_MEMBERS) || defined(CONFIG_ARCH_ADDRENV)
|
||||
#if defined(HAVE_GROUP_MEMBERS)
|
||||
/* This is the head of a list of all group members */
|
||||
|
||||
extern FAR struct task_group_s *g_grouphead;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_ADDRENV
|
||||
/* This variable holds the current task group. This pointer is NULL
|
||||
* if the current task is a kernel thread that has no address environment
|
||||
* (other than the kernel context).
|
||||
*
|
||||
* This must only be accessed with interrupts disabled.
|
||||
*/
|
||||
|
||||
extern FAR struct task_group_s *g_group_current[CONFIG_SMP_NCPUS];
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
@ -86,7 +75,7 @@ void group_add_waiter(FAR struct task_group_s *group);
|
||||
void group_del_waiter(FAR struct task_group_s *group);
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_GROUP_MEMBERS) || defined(CONFIG_ARCH_ADDRENV)
|
||||
#if defined(HAVE_GROUP_MEMBERS)
|
||||
FAR struct task_group_s *group_findbypid(pid_t pid);
|
||||
#endif
|
||||
|
||||
@ -100,12 +89,6 @@ int group_continue(FAR struct tcb_s *tcb);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_ADDRENV
|
||||
/* Group address environment management */
|
||||
|
||||
int group_addrenv(FAR struct tcb_s *tcb);
|
||||
#endif
|
||||
|
||||
/* Convenience functions */
|
||||
|
||||
FAR struct task_group_s *task_getgroup(pid_t pid);
|
||||
|
@ -51,7 +51,7 @@
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(HAVE_GROUP_MEMBERS) || defined(CONFIG_ARCH_ADDRENV)
|
||||
#if defined(HAVE_GROUP_MEMBERS)
|
||||
/* This is the head of a list of all group members */
|
||||
|
||||
FAR struct task_group_s *g_grouphead;
|
||||
@ -231,7 +231,7 @@ errout_with_group:
|
||||
void group_initialize(FAR struct task_tcb_s *tcb)
|
||||
{
|
||||
FAR struct task_group_s *group;
|
||||
#if defined(HAVE_GROUP_MEMBERS) || defined(CONFIG_ARCH_ADDRENV)
|
||||
#if defined(HAVE_GROUP_MEMBERS)
|
||||
irqstate_t flags;
|
||||
#endif
|
||||
|
||||
@ -261,7 +261,7 @@ void group_initialize(FAR struct task_tcb_s *tcb)
|
||||
|
||||
group->tg_nmembers = 1;
|
||||
|
||||
#if defined(HAVE_GROUP_MEMBERS) || defined(CONFIG_ARCH_ADDRENV)
|
||||
#if defined(HAVE_GROUP_MEMBERS)
|
||||
/* Add the initialized entry to the list of groups */
|
||||
|
||||
flags = enter_critical_section();
|
||||
|
@ -63,7 +63,7 @@
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(HAVE_GROUP_MEMBERS) || defined(CONFIG_ARCH_ADDRENV)
|
||||
#if defined(HAVE_GROUP_MEMBERS)
|
||||
FAR struct task_group_s *group_findbypid(pid_t pid)
|
||||
{
|
||||
FAR struct task_group_s *group;
|
||||
|
@ -67,7 +67,7 @@
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(HAVE_GROUP_MEMBERS) || defined(CONFIG_ARCH_ADDRENV)
|
||||
#if defined(HAVE_GROUP_MEMBERS)
|
||||
static void group_remove(FAR struct task_group_s *group)
|
||||
{
|
||||
FAR struct task_group_s *curr;
|
||||
@ -128,10 +128,6 @@ static void group_remove(FAR struct task_group_s *group)
|
||||
|
||||
static inline void group_release(FAR struct task_group_s *group)
|
||||
{
|
||||
#ifdef CONFIG_ARCH_ADDRENV
|
||||
int i;
|
||||
#endif
|
||||
|
||||
#if CONFIG_TLS_TASK_NELEM > 0
|
||||
task_tls_destruct();
|
||||
#endif
|
||||
@ -172,7 +168,7 @@ static inline void group_release(FAR struct task_group_s *group)
|
||||
|
||||
mm_map_destroy(&group->tg_mm_map);
|
||||
|
||||
#if defined(HAVE_GROUP_MEMBERS) || defined(CONFIG_ARCH_ADDRENV)
|
||||
#if defined(HAVE_GROUP_MEMBERS)
|
||||
/* Remove the group from the list of groups */
|
||||
|
||||
group_remove(group);
|
||||
@ -201,22 +197,6 @@ static inline void group_release(FAR struct task_group_s *group)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_ADDRENV
|
||||
/* Destroy the group address environment */
|
||||
|
||||
up_addrenv_destroy(&group->tg_addrenv);
|
||||
|
||||
/* Mark no address environment */
|
||||
|
||||
for (i = 0; i < CONFIG_SMP_NCPUS; i++)
|
||||
{
|
||||
if (group == g_group_current[i])
|
||||
{
|
||||
g_group_current[i] = NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Mark the group as deleted now */
|
||||
|
||||
group->tg_flags |= GROUP_FLAG_DELETED;
|
||||
|
@ -242,7 +242,7 @@ static void get_argv_str(FAR struct tcb_s *tcb, FAR char *args, size_t size)
|
||||
#ifdef CONFIG_ARCH_ADDRENV
|
||||
if ((tcb->flags & TCB_FLAG_TTYPE_MASK) != TCB_FLAG_TTYPE_KERNEL)
|
||||
{
|
||||
if ((tcb->group->tg_flags & GROUP_FLAG_ADDRENV) == 0)
|
||||
if (tcb->addrenv_own == NULL)
|
||||
{
|
||||
/* Process should have address environment, but doesn't */
|
||||
|
||||
@ -250,7 +250,7 @@ static void get_argv_str(FAR struct tcb_s *tcb, FAR char *args, size_t size)
|
||||
return;
|
||||
}
|
||||
|
||||
up_addrenv_select(&tcb->group->tg_addrenv, &oldenv);
|
||||
up_addrenv_select(&tcb->addrenv_own->addrenv, &oldenv);
|
||||
saved = true;
|
||||
}
|
||||
#endif
|
||||
|
@ -220,7 +220,7 @@ int nx_pthread_create(pthread_trampoline_t trampoline, FAR pthread_t *thread,
|
||||
#ifdef CONFIG_ARCH_ADDRENV
|
||||
/* Share the address environment of the parent task group. */
|
||||
|
||||
ret = up_addrenv_attach(ptcb->cmn.group, this_task());
|
||||
ret = up_addrenv_attach(this_task(), (FAR struct tcb_s *)ptcb);
|
||||
if (ret < 0)
|
||||
{
|
||||
errcode = -ret;
|
||||
|
@ -154,7 +154,11 @@ int nxsched_release_tcb(FAR struct tcb_s *tcb, uint8_t ttype)
|
||||
#ifdef CONFIG_ARCH_ADDRENV
|
||||
/* Release this thread's reference to the address environment */
|
||||
|
||||
ret = up_addrenv_detach(tcb->group, tcb);
|
||||
ret = up_addrenv_detach(tcb);
|
||||
if (ttype == TCB_FLAG_TTYPE_TASK)
|
||||
{
|
||||
addrenv_free(tcb);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Leave the group (if we did not already leave in task_exithook.c) */
|
||||
|
@ -96,12 +96,22 @@ int nxtask_init(FAR struct task_tcb_s *tcb, const char *name, int priority,
|
||||
DEBUGASSERT(tcb && ttype != TCB_FLAG_TTYPE_PTHREAD);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_ADDRENV
|
||||
/* Allocate address environment for the task */
|
||||
|
||||
ret = addrenv_allocate(&tcb->cmn, tcb->cmn.flags);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Create a new task group */
|
||||
|
||||
ret = group_allocate(tcb, tcb->cmn.flags);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
goto errout_with_addrenv;
|
||||
}
|
||||
|
||||
/* Duplicate the parent tasks environment */
|
||||
@ -190,6 +200,11 @@ errout_with_group:
|
||||
}
|
||||
|
||||
group_leave(&tcb->cmn);
|
||||
|
||||
errout_with_addrenv:
|
||||
#ifdef CONFIG_ARCH_ADDRENV
|
||||
addrenv_free(&tcb->cmn);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user