diff --git a/Documentation/guides/kernel_threads_with_custom_stacks.rst b/Documentation/guides/kernel_threads_with_custom_stacks.rst index 09be91c51800c..c180e0200d70c 100644 --- a/Documentation/guides/kernel_threads_with_custom_stacks.rst +++ b/Documentation/guides/kernel_threads_with_custom_stacks.rst @@ -31,7 +31,7 @@ Here is the body of some function. It expects to have the following inputs: * used to that all fields of the new TCB will be zeroed. */ - tcb = (FAR struct task_tcb_s *)kmm_zalloc(sizeof(struct task_tcb_s)); + tcb = kmm_zalloc(sizeof(struct tcb_s) + sizeof(struct task_group_s)); if (tcb == NULL) { return -ENOMEM; @@ -131,4 +131,4 @@ option is to include it in all cases where you do not expect the custom stack to be de-allocated. You must not free the custom stack after ``nxtask_activate()`` returns -successfully and until the kernel thread is terminated. \ No newline at end of file +successfully and until the kernel thread is terminated. diff --git a/arch/arm/src/common/arm_fork.c b/arch/arm/src/common/arm_fork.c index 7a5a73e3668d2..114c580921dad 100644 --- a/arch/arm/src/common/arm_fork.c +++ b/arch/arm/src/common/arm_fork.c @@ -92,7 +92,7 @@ pid_t arm_fork(const struct fork_s *context) { struct tcb_s *parent = this_task(); - struct task_tcb_s *child; + struct tcb_s *child; uint32_t newsp; uint32_t newfp; uint32_t newtop; @@ -144,17 +144,17 @@ pid_t arm_fork(const struct fork_s *context) * effort is overkill. */ - newtop = (uint32_t)child->cmn.stack_base_ptr + - child->cmn.adj_stack_size; + newtop = (uint32_t)child->stack_base_ptr + + child->adj_stack_size; newsp = newtop - stackutil; /* Move the register context to newtop. */ memcpy((void *)(newsp - XCPTCONTEXT_SIZE), - child->cmn.xcp.regs, XCPTCONTEXT_SIZE); + child->xcp.regs, XCPTCONTEXT_SIZE); - child->cmn.xcp.regs = (void *)(newsp - XCPTCONTEXT_SIZE); + child->xcp.regs = (void *)(newsp - XCPTCONTEXT_SIZE); memcpy((void *)newsp, (const void *)oldsp, stackutil); @@ -182,16 +182,16 @@ pid_t arm_fork(const struct fork_s *context) * child thread. */ - child->cmn.xcp.regs[REG_R4] = context->r4; /* Volatile register r4 */ - child->cmn.xcp.regs[REG_R5] = context->r5; /* Volatile register r5 */ - child->cmn.xcp.regs[REG_R6] = context->r6; /* Volatile register r6 */ - child->cmn.xcp.regs[REG_R7] = context->r7; /* Volatile register r7 */ - child->cmn.xcp.regs[REG_R8] = context->r8; /* Volatile register r8 */ - child->cmn.xcp.regs[REG_R9] = context->r9; /* Volatile register r9 */ - child->cmn.xcp.regs[REG_R10] = context->r10; /* Volatile register r10 */ - child->cmn.xcp.regs[REG_R11] = context->r11; /* Volatile register r11 */ - child->cmn.xcp.regs[REG_FP] = newfp; /* Frame pointer */ - child->cmn.xcp.regs[REG_SP] = newsp; /* Stack pointer */ + child->xcp.regs[REG_R4] = context->r4; /* Volatile register r4 */ + child->xcp.regs[REG_R5] = context->r5; /* Volatile register r5 */ + child->xcp.regs[REG_R6] = context->r6; /* Volatile register r6 */ + child->xcp.regs[REG_R7] = context->r7; /* Volatile register r7 */ + child->xcp.regs[REG_R8] = context->r8; /* Volatile register r8 */ + child->xcp.regs[REG_R9] = context->r9; /* Volatile register r9 */ + child->xcp.regs[REG_R10] = context->r10; /* Volatile register r10 */ + child->xcp.regs[REG_R11] = context->r11; /* Volatile register r11 */ + child->xcp.regs[REG_FP] = newfp; /* Frame pointer */ + child->xcp.regs[REG_SP] = newsp; /* Stack pointer */ #ifdef CONFIG_LIB_SYSCALL /* If we got here via a syscall, then we are going to have to setup some @@ -203,7 +203,7 @@ pid_t arm_fork(const struct fork_s *context) int index; for (index = 0; index < parent->xcp.nsyscalls; index++) { - child->cmn.xcp.syscall[index].sysreturn = + child->xcp.syscall[index].sysreturn = parent->xcp.syscall[index].sysreturn; /* REVISIT: This logic is *not* common. */ @@ -211,7 +211,7 @@ pid_t arm_fork(const struct fork_s *context) #if defined(CONFIG_ARCH_ARMV7A) # ifdef CONFIG_BUILD_KERNEL - child->cmn.xcp.syscall[index].cpsr = + child->xcp.syscall[index].cpsr = parent->xcp.syscall[index].cpsr; # endif @@ -219,21 +219,21 @@ pid_t arm_fork(const struct fork_s *context) #elif defined(CONFIG_ARCH_ARMV7R) # ifdef CONFIG_BUILD_PROTECTED - child->cmn.xcp.syscall[index].cpsr = + child->xcp.syscall[index].cpsr = parent->xcp.syscall[index].cpsr; # endif #elif defined(CONFIG_ARCH_ARMV6M) || defined(CONFIG_ARCH_ARMV7M) || \ defined(CONFIG_ARCH_ARMV8M) - child->cmn.xcp.syscall[index].excreturn = + child->xcp.syscall[index].excreturn = parent->xcp.syscall[index].excreturn; #else # error Missing logic #endif } - child->cmn.xcp.nsyscalls = parent->xcp.nsyscalls; + child->xcp.nsyscalls = parent->xcp.nsyscalls; } #endif diff --git a/arch/arm64/src/common/arm64_fork.c b/arch/arm64/src/common/arm64_fork.c index 9cd23b5554a81..ec20e02a088e3 100644 --- a/arch/arm64/src/common/arm64_fork.c +++ b/arch/arm64/src/common/arm64_fork.c @@ -122,7 +122,7 @@ void arm64_fork_fpureg_save(struct fork_s *context) pid_t arm64_fork(const struct fork_s *context) { struct tcb_s *parent = this_task(); - struct task_tcb_s *child; + struct tcb_s *child; uint64_t newsp; uint64_t newfp; uint64_t newtop; @@ -156,8 +156,8 @@ pid_t arm64_fork(const struct fork_s *context) * effort is overkill. */ - newtop = (uint64_t)child->cmn.stack_base_ptr + - child->cmn.adj_stack_size; + newtop = (uint64_t)child->stack_base_ptr + + child->adj_stack_size; newsp = newtop - stackutil; memcpy((void *)newsp, (const void *)context->sp, stackutil); @@ -183,59 +183,59 @@ pid_t arm64_fork(const struct fork_s *context) /* make the fork stack frame */ #ifdef CONFIG_ARCH_FPU - child->cmn.xcp.fpu_regs = (void *)(newsp - FPU_CONTEXT_SIZE); - memcpy(child->cmn.xcp.fpu_regs, context->fpu, FPU_CONTEXT_SIZE); + child->xcp.fpu_regs = (void *)(newsp - FPU_CONTEXT_SIZE); + memcpy(child->xcp.fpu_regs, context->fpu, FPU_CONTEXT_SIZE); #endif - child->cmn.xcp.regs = (void *)(newsp - XCPTCONTEXT_SIZE); - - child->cmn.xcp.regs[REG_X0] = 0; - child->cmn.xcp.regs[REG_X8] = context->regs[FORK_REG_X8]; - child->cmn.xcp.regs[REG_X9] = context->regs[FORK_REG_X9]; - child->cmn.xcp.regs[REG_X10] = context->regs[FORK_REG_X10]; - child->cmn.xcp.regs[REG_X11] = context->regs[FORK_REG_X11]; - child->cmn.xcp.regs[REG_X12] = context->regs[FORK_REG_X12]; - child->cmn.xcp.regs[REG_X13] = context->regs[FORK_REG_X13]; - child->cmn.xcp.regs[REG_X14] = context->regs[FORK_REG_X14]; - child->cmn.xcp.regs[REG_X15] = context->regs[FORK_REG_X15]; - child->cmn.xcp.regs[REG_X16] = context->regs[FORK_REG_X16]; - child->cmn.xcp.regs[REG_X17] = context->regs[FORK_REG_X17]; - child->cmn.xcp.regs[REG_X18] = context->regs[FORK_REG_X18]; - child->cmn.xcp.regs[REG_X19] = context->regs[FORK_REG_X19]; - child->cmn.xcp.regs[REG_X20] = context->regs[FORK_REG_X20]; - child->cmn.xcp.regs[REG_X21] = context->regs[FORK_REG_X21]; - child->cmn.xcp.regs[REG_X22] = context->regs[FORK_REG_X22]; - child->cmn.xcp.regs[REG_X23] = context->regs[FORK_REG_X23]; - child->cmn.xcp.regs[REG_X24] = context->regs[FORK_REG_X24]; - child->cmn.xcp.regs[REG_X25] = context->regs[FORK_REG_X25]; - child->cmn.xcp.regs[REG_X26] = context->regs[FORK_REG_X26]; - child->cmn.xcp.regs[REG_X27] = context->regs[FORK_REG_X27]; - child->cmn.xcp.regs[REG_X28] = context->regs[FORK_REG_X28]; - child->cmn.xcp.regs[REG_FP] = newfp; + child->xcp.regs = (void *)(newsp - XCPTCONTEXT_SIZE); + + child->xcp.regs[REG_X0] = 0; + child->xcp.regs[REG_X8] = context->regs[FORK_REG_X8]; + child->xcp.regs[REG_X9] = context->regs[FORK_REG_X9]; + child->xcp.regs[REG_X10] = context->regs[FORK_REG_X10]; + child->xcp.regs[REG_X11] = context->regs[FORK_REG_X11]; + child->xcp.regs[REG_X12] = context->regs[FORK_REG_X12]; + child->xcp.regs[REG_X13] = context->regs[FORK_REG_X13]; + child->xcp.regs[REG_X14] = context->regs[FORK_REG_X14]; + child->xcp.regs[REG_X15] = context->regs[FORK_REG_X15]; + child->xcp.regs[REG_X16] = context->regs[FORK_REG_X16]; + child->xcp.regs[REG_X17] = context->regs[FORK_REG_X17]; + child->xcp.regs[REG_X18] = context->regs[FORK_REG_X18]; + child->xcp.regs[REG_X19] = context->regs[FORK_REG_X19]; + child->xcp.regs[REG_X20] = context->regs[FORK_REG_X20]; + child->xcp.regs[REG_X21] = context->regs[FORK_REG_X21]; + child->xcp.regs[REG_X22] = context->regs[FORK_REG_X22]; + child->xcp.regs[REG_X23] = context->regs[FORK_REG_X23]; + child->xcp.regs[REG_X24] = context->regs[FORK_REG_X24]; + child->xcp.regs[REG_X25] = context->regs[FORK_REG_X25]; + child->xcp.regs[REG_X26] = context->regs[FORK_REG_X26]; + child->xcp.regs[REG_X27] = context->regs[FORK_REG_X27]; + child->xcp.regs[REG_X28] = context->regs[FORK_REG_X28]; + child->xcp.regs[REG_FP] = newfp; #if CONFIG_ARCH_ARM64_EXCEPTION_LEVEL == 3 - child->cmn.xcp.regs[REG_SPSR] = SPSR_MODE_EL3H; + child->xcp.regs[REG_SPSR] = SPSR_MODE_EL3H; #else - child->cmn.xcp.regs[REG_SPSR] = SPSR_MODE_EL1H; + child->xcp.regs[REG_SPSR] = SPSR_MODE_EL1H; #endif #ifdef CONFIG_SUPPRESS_INTERRUPTS - child->cmn.xcp.regs[REG_SPSR] |= (DAIF_IRQ_BIT | DAIF_FIQ_BIT); + child->xcp.regs[REG_SPSR] |= (DAIF_IRQ_BIT | DAIF_FIQ_BIT); #endif /* CONFIG_SUPPRESS_INTERRUPTS */ - child->cmn.xcp.regs[REG_ELR] = (uint64_t)context->lr; + child->xcp.regs[REG_ELR] = (uint64_t)context->lr; - child->cmn.xcp.regs[REG_SCTLR_EL1] = read_sysreg(sctlr_el1); + child->xcp.regs[REG_SCTLR_EL1] = read_sysreg(sctlr_el1); #ifdef CONFIG_ARM64_MTE - child->cmn.xcp.regs[REG_SCTLR_EL1] |= SCTLR_TCF1_BIT; + child->xcp.regs[REG_SCTLR_EL1] |= SCTLR_TCF1_BIT; #endif - child->cmn.xcp.regs[REG_EXE_DEPTH] = 0; - child->cmn.xcp.regs[REG_SP_ELX] = newsp - XCPTCONTEXT_SIZE; + child->xcp.regs[REG_EXE_DEPTH] = 0; + child->xcp.regs[REG_SP_ELX] = newsp - XCPTCONTEXT_SIZE; #ifdef CONFIG_ARCH_KERNEL_STACK - child->cmn.xcp.regs[REG_SP_EL0] = (uint64_t)child->cmn.xcp.ustkptr; + child->xcp.regs[REG_SP_EL0] = (uint64_t)child->xcp.ustkptr; #else - child->cmn.xcp.regs[REG_SP_EL0] = newsp - XCPTCONTEXT_SIZE; + child->xcp.regs[REG_SP_EL0] = newsp - XCPTCONTEXT_SIZE; #endif /* And, finally, start the child task. On a failure, nxtask_start_fork() diff --git a/arch/ceva/src/common/ceva_fork.c b/arch/ceva/src/common/ceva_fork.c index 78fc191566011..4e4c98c6a7593 100644 --- a/arch/ceva/src/common/ceva_fork.c +++ b/arch/ceva/src/common/ceva_fork.c @@ -87,7 +87,7 @@ pid_t ceva_fork(const uint32_t *regs) { #ifdef CONFIG_SCHED_WAITPID struct tcb_s *parent = this_task(); - struct task_tcb_s *child; + struct tcb_s *child; size_t stacksize; const void *sp = regs + XCPTCONTEXT_REGS; void *newsp; @@ -114,7 +114,7 @@ pid_t ceva_fork(const uint32_t *regs) /* Allocate the stack for the TCB */ - ret = up_create_stack((struct tcb_s *)child, stacksize + argsize, + ret = up_create_stack(child, stacksize + argsize, parent->flags & TCB_FLAG_TTYPE_MASK); if (ret != OK) { @@ -125,7 +125,7 @@ pid_t ceva_fork(const uint32_t *regs) /* Allocate the memory and copy argument from parent task */ - argv = up_stack_frame((struct tcb_s *)child, argsize); + argv = up_stack_frame(child, argsize); memcpy(argv, parent->stack_base_ptr, argsize); /* How much of the parent's stack was utilized? The CEVA uses @@ -146,14 +146,14 @@ pid_t ceva_fork(const uint32_t *regs) * effort is overkill. */ - newsp = child->cmn.stack_base_ptr - stackutil; + newsp = child->stack_base_ptr - stackutil; memcpy(newsp, sp, stackutil); /* Allocate the context and copy the parent snapshot */ newsp -= XCPTCONTEXT_SIZE; memcpy(newsp, regs, XCPTCONTEXT_SIZE); - child->cmn.xcp.regs = newsp; + child->xcp.regs = newsp; /* Was there a frame pointer in place before? */ @@ -161,7 +161,7 @@ pid_t ceva_fork(const uint32_t *regs) regs[REG_FP] >= (uint32_t)parent->stack_base_ptr - stacksize) { uint32_t frameutil = (uint32_t)parent->stack_base_ptr - regs[REG_FP]; - newfp = (uint32_t)child->cmn.stack_base_ptr - frameutil; + newfp = (uint32_t)child->stack_base_ptr - frameutil; } else { @@ -171,17 +171,17 @@ pid_t ceva_fork(const uint32_t *regs) sinfo("Parent: stack base:%08x SP:%08x FP:%08x\n", parent->stack_base_ptr, sp, regs[REG_FP]); sinfo("Child: stack base:%08x SP:%08x FP:%08x\n", - child->cmn.stack_base_ptr, newsp, newfp); + child->stack_base_ptr, newsp, newfp); /* Update the stack pointer, frame pointer, and the return value in A0 * should be cleared to zero, providing the indication to the newly started * child thread. */ - child->cmn.xcp.regs[REG_A0] = 0; /* Return value */ - child->cmn.xcp.regs[REG_FP] = newfp; /* Frame pointer */ - child->cmn.xcp.regs[REG_PC] = regs[REG_LR]; /* Program counter */ - child->cmn.xcp.regs[REG_SP] = (uint32_t)newsp; /* Stack pointer */ + child->xcp.regs[REG_A0] = 0; /* Return value */ + child->xcp.regs[REG_FP] = newfp; /* Frame pointer */ + child->xcp.regs[REG_PC] = regs[REG_LR]; /* Program counter */ + child->xcp.regs[REG_SP] = (uint32_t)newsp; /* Stack pointer */ #ifdef CONFIG_LIB_SYSCALL /* If we got here via a syscall, then we are going to have to setup some @@ -193,10 +193,10 @@ pid_t ceva_fork(const uint32_t *regs) int index; for (index = 0; index < parent->xcp.nsyscalls; index++) { - child->cmn.xcp.syscall[index] = parent->xcp.syscall[index]; + child->xcp.syscall[index] = parent->xcp.syscall[index]; } - child->cmn.xcp.nsyscalls = parent->xcp.nsyscalls; + child->xcp.nsyscalls = parent->xcp.nsyscalls; } #endif diff --git a/arch/mips/src/mips32/mips_fork.c b/arch/mips/src/mips32/mips_fork.c index 831757447f3e4..fa827f9d61ed9 100644 --- a/arch/mips/src/mips32/mips_fork.c +++ b/arch/mips/src/mips32/mips_fork.c @@ -92,7 +92,7 @@ pid_t mips_fork(const struct fork_s *context) { struct tcb_s *parent = this_task(); - struct task_tcb_s *child; + struct tcb_s *child; uint32_t newsp; #ifdef CONFIG_MIPS32_FRAMEPOINTER uint32_t newfp; @@ -159,8 +159,8 @@ pid_t mips_fork(const struct fork_s *context) * effort is overkill. */ - newtop = (uintptr_t)child->cmn.stack_base_ptr + - child->cmn.adj_stack_size; + newtop = (uintptr_t)child->stack_base_ptr + + child->adj_stack_size; newsp = newtop - stackutil; memcpy((void *)newsp, (const void *)context->sp, stackutil); @@ -195,22 +195,22 @@ pid_t mips_fork(const struct fork_s *context) * indication to the newly started child thread. */ - child->cmn.xcp.regs[REG_S0] = context->s0; /* Saved register s0 */ - child->cmn.xcp.regs[REG_S1] = context->s1; /* Saved register s1 */ - child->cmn.xcp.regs[REG_S2] = context->s2; /* Saved register s2 */ - child->cmn.xcp.regs[REG_S3] = context->s3; /* Volatile register s3 */ - child->cmn.xcp.regs[REG_S4] = context->s4; /* Volatile register s4 */ - child->cmn.xcp.regs[REG_S5] = context->s5; /* Volatile register s5 */ - child->cmn.xcp.regs[REG_S6] = context->s6; /* Volatile register s6 */ - child->cmn.xcp.regs[REG_S7] = context->s7; /* Volatile register s7 */ + child->xcp.regs[REG_S0] = context->s0; /* Saved register s0 */ + child->xcp.regs[REG_S1] = context->s1; /* Saved register s1 */ + child->xcp.regs[REG_S2] = context->s2; /* Saved register s2 */ + child->xcp.regs[REG_S3] = context->s3; /* Volatile register s3 */ + child->xcp.regs[REG_S4] = context->s4; /* Volatile register s4 */ + child->xcp.regs[REG_S5] = context->s5; /* Volatile register s5 */ + child->xcp.regs[REG_S6] = context->s6; /* Volatile register s6 */ + child->xcp.regs[REG_S7] = context->s7; /* Volatile register s7 */ #ifdef CONFIG_MIPS32_FRAMEPOINTER - child->cmn.xcp.regs[REG_FP] = newfp; /* Frame pointer */ + child->xcp.regs[REG_FP] = newfp; /* Frame pointer */ #else - child->cmn.xcp.regs[REG_S8] = context->s8; /* Volatile register s8 */ + child->xcp.regs[REG_S8] = context->s8; /* Volatile register s8 */ #endif - child->cmn.xcp.regs[REG_SP] = newsp; /* Stack pointer */ + child->xcp.regs[REG_SP] = newsp; /* Stack pointer */ #ifdef MIPS32_SAVE_GP - child->cmn.xcp.regs[REG_GP] = context->gp; /* Global pointer */ + child->xcp.regs[REG_GP] = context->gp; /* Global pointer */ #endif /* And, finally, start the child task. On a failure, nxtask_start_fork() diff --git a/arch/risc-v/src/common/riscv_fork.c b/arch/risc-v/src/common/riscv_fork.c index f77ce42f8edb3..d7ad9889a6135 100644 --- a/arch/risc-v/src/common/riscv_fork.c +++ b/arch/risc-v/src/common/riscv_fork.c @@ -105,7 +105,7 @@ pid_t riscv_fork(const struct fork_s *context) { struct tcb_s *parent = this_task(); - struct task_tcb_s *child; + struct tcb_s *child; uintptr_t newsp; uintptr_t newtop; uintptr_t stacktop; @@ -132,7 +132,7 @@ pid_t riscv_fork(const struct fork_s *context) /* Copy goes to child's user stack top */ - newtop = (uintptr_t)child->cmn.stack_base_ptr + child->cmn.adj_stack_size; + newtop = (uintptr_t)child->stack_base_ptr + child->adj_stack_size; newsp = newtop - stackutil; memcpy((void *)newsp, (const void *)parent->xcp.sregs[REG_SP], stackutil); @@ -140,17 +140,17 @@ pid_t riscv_fork(const struct fork_s *context) #ifdef CONFIG_SCHED_THREAD_LOCAL /* Save child's thread pointer */ - tp = child->cmn.xcp.regs[REG_TP]; + tp = child->xcp.regs[REG_TP]; #endif /* Determine the integer context save area */ #ifdef CONFIG_ARCH_KERNEL_STACK - if (child->cmn.xcp.kstack) + if (child->xcp.kstack) { /* Set context to kernel stack */ - stacktop = (uintptr_t)child->cmn.xcp.ktopstk; + stacktop = (uintptr_t)child->xcp.ktopstk; } else #endif @@ -162,22 +162,22 @@ pid_t riscv_fork(const struct fork_s *context) /* Set the new register restore area to the new stack top */ - child->cmn.xcp.regs = (void *)(stacktop - XCPTCONTEXT_SIZE); + child->xcp.regs = (void *)(stacktop - XCPTCONTEXT_SIZE); /* Copy the parent integer context (overwrites child's SP and TP) */ - memcpy(child->cmn.xcp.regs, parent->xcp.sregs, XCPTCONTEXT_SIZE); + memcpy(child->xcp.regs, parent->xcp.sregs, XCPTCONTEXT_SIZE); /* Save FPU */ - riscv_savefpu(child->cmn.xcp.regs, riscv_fpuregs(&child->cmn)); + riscv_savefpu(child->xcp.regs, riscv_fpuregs(child)); /* Return 0 to child */ - child->cmn.xcp.regs[REG_A0] = 0; - child->cmn.xcp.regs[REG_SP] = newsp; + child->xcp.regs[REG_A0] = 0; + child->xcp.regs[REG_SP] = newsp; #ifdef CONFIG_SCHED_THREAD_LOCAL - child->cmn.xcp.regs[REG_TP] = tp; + child->xcp.regs[REG_TP] = tp; #endif /* And, finally, start the child task. On a failure, nxtask_start_fork() @@ -192,7 +192,7 @@ pid_t riscv_fork(const struct fork_s *context) pid_t riscv_fork(const struct fork_s *context) { struct tcb_s *parent = this_task(); - struct task_tcb_s *child; + struct tcb_s *child; uintptr_t newsp; #ifdef CONFIG_RISCV_FRAMEPOINTER uintptr_t newfp; @@ -259,13 +259,13 @@ pid_t riscv_fork(const struct fork_s *context) * effort is overkill. */ - newtop = (uintptr_t)child->cmn.stack_base_ptr + child->cmn.adj_stack_size; + newtop = (uintptr_t)child->stack_base_ptr + child->adj_stack_size; newsp = newtop - stackutil; /* Set up frame for context and copy the initial context there */ memcpy((void *)(newsp - XCPTCONTEXT_SIZE), - child->cmn.xcp.regs, XCPTCONTEXT_SIZE); + child->xcp.regs, XCPTCONTEXT_SIZE); /* Copy the parent stack contents (overwrites child's SP and TP) */ @@ -273,7 +273,7 @@ pid_t riscv_fork(const struct fork_s *context) /* Set the new register restore area to the new stack top */ - child->cmn.xcp.regs = (void *)(newsp - XCPTCONTEXT_SIZE); + child->xcp.regs = (void *)(newsp - XCPTCONTEXT_SIZE); /* Was there a frame pointer in place before? */ @@ -306,40 +306,40 @@ pid_t riscv_fork(const struct fork_s *context) * indication to the newly started child thread. */ - child->cmn.xcp.regs[REG_S1] = context->s1; /* Saved register s1 */ - child->cmn.xcp.regs[REG_S2] = context->s2; /* Saved register s2 */ - child->cmn.xcp.regs[REG_S3] = context->s3; /* Saved register s3 */ - child->cmn.xcp.regs[REG_S4] = context->s4; /* Saved register s4 */ - child->cmn.xcp.regs[REG_S5] = context->s5; /* Saved register s5 */ - child->cmn.xcp.regs[REG_S6] = context->s6; /* Saved register s6 */ - child->cmn.xcp.regs[REG_S7] = context->s7; /* Saved register s7 */ - child->cmn.xcp.regs[REG_S8] = context->s8; /* Saved register s8 */ - child->cmn.xcp.regs[REG_S9] = context->s9; /* Saved register s9 */ - child->cmn.xcp.regs[REG_S10] = context->s10; /* Saved register s10 */ - child->cmn.xcp.regs[REG_S11] = context->s11; /* Saved register s11 */ + child->xcp.regs[REG_S1] = context->s1; /* Saved register s1 */ + child->xcp.regs[REG_S2] = context->s2; /* Saved register s2 */ + child->xcp.regs[REG_S3] = context->s3; /* Saved register s3 */ + child->xcp.regs[REG_S4] = context->s4; /* Saved register s4 */ + child->xcp.regs[REG_S5] = context->s5; /* Saved register s5 */ + child->xcp.regs[REG_S6] = context->s6; /* Saved register s6 */ + child->xcp.regs[REG_S7] = context->s7; /* Saved register s7 */ + child->xcp.regs[REG_S8] = context->s8; /* Saved register s8 */ + child->xcp.regs[REG_S9] = context->s9; /* Saved register s9 */ + child->xcp.regs[REG_S10] = context->s10; /* Saved register s10 */ + child->xcp.regs[REG_S11] = context->s11; /* Saved register s11 */ #ifdef CONFIG_RISCV_FRAMEPOINTER - child->cmn.xcp.regs[REG_FP] = newfp; /* Frame pointer */ + child->xcp.regs[REG_FP] = newfp; /* Frame pointer */ #else - child->cmn.xcp.regs[REG_S0] = context->s0; /* Saved register s0 */ + child->xcp.regs[REG_S0] = context->s0; /* Saved register s0 */ #endif - child->cmn.xcp.regs[REG_SP] = newsp; /* Stack pointer */ + child->xcp.regs[REG_SP] = newsp; /* Stack pointer */ #ifdef RISCV_SAVE_GP - child->cmn.xcp.regs[REG_GP] = context->gp; /* Global pointer */ + child->xcp.regs[REG_GP] = context->gp; /* Global pointer */ #endif #ifdef CONFIG_ARCH_FPU - fregs = riscv_fpuregs(&child->cmn); - fregs[REG_FS0] = context->fs0; /* Saved register fs1 */ - fregs[REG_FS1] = context->fs1; /* Saved register fs1 */ - fregs[REG_FS2] = context->fs2; /* Saved register fs2 */ - fregs[REG_FS3] = context->fs3; /* Saved register fs3 */ - fregs[REG_FS4] = context->fs4; /* Saved register fs4 */ - fregs[REG_FS5] = context->fs5; /* Saved register fs5 */ - fregs[REG_FS6] = context->fs6; /* Saved register fs6 */ - fregs[REG_FS7] = context->fs7; /* Saved register fs7 */ - fregs[REG_FS8] = context->fs8; /* Saved register fs8 */ - fregs[REG_FS9] = context->fs9; /* Saved register fs9 */ - fregs[REG_FS10] = context->fs10; /* Saved register fs10 */ - fregs[REG_FS11] = context->fs11; /* Saved register fs11 */ + fregs = riscv_fpuregs(child); + fregs[REG_FS0] = context->fs0; /* Saved register fs1 */ + fregs[REG_FS1] = context->fs1; /* Saved register fs1 */ + fregs[REG_FS2] = context->fs2; /* Saved register fs2 */ + fregs[REG_FS3] = context->fs3; /* Saved register fs3 */ + fregs[REG_FS4] = context->fs4; /* Saved register fs4 */ + fregs[REG_FS5] = context->fs5; /* Saved register fs5 */ + fregs[REG_FS6] = context->fs6; /* Saved register fs6 */ + fregs[REG_FS7] = context->fs7; /* Saved register fs7 */ + fregs[REG_FS8] = context->fs8; /* Saved register fs8 */ + fregs[REG_FS9] = context->fs9; /* Saved register fs9 */ + fregs[REG_FS10] = context->fs10; /* Saved register fs10 */ + fregs[REG_FS11] = context->fs11; /* Saved register fs11 */ #endif /* And, finally, start the child task. On a failure, nxtask_start_fork() diff --git a/arch/sim/src/sim/sim_fork.c b/arch/sim/src/sim/sim_fork.c index ad4ffd293c70c..2233ab5b5706f 100644 --- a/arch/sim/src/sim/sim_fork.c +++ b/arch/sim/src/sim/sim_fork.c @@ -91,7 +91,7 @@ nosanitize_address pid_t sim_fork(const xcpt_reg_t *context) { struct tcb_s *parent = this_task(); - struct task_tcb_s *child; + struct tcb_s *child; unsigned char *pout; unsigned char *pin; xcpt_reg_t newsp; @@ -135,8 +135,8 @@ pid_t sim_fork(const xcpt_reg_t *context) * effort is overkill. */ - newtop = (xcpt_reg_t)child->cmn.stack_base_ptr + - child->cmn.adj_stack_size; + newtop = (xcpt_reg_t)child->stack_base_ptr + + child->adj_stack_size; newsp = newtop - stackutil; pout = (unsigned char *)newsp; pin = (unsigned char *)context[JB_SP]; @@ -166,10 +166,10 @@ pid_t sim_fork(const xcpt_reg_t *context) * child thread. */ - memcpy(child->cmn.xcp.regs, context, + memcpy(child->xcp.regs, context, sizeof(xcpt_reg_t) * XCPTCONTEXT_REGS); - child->cmn.xcp.regs[JB_FP] = newfp; /* Frame pointer */ - child->cmn.xcp.regs[JB_SP] = newsp; /* Stack pointer */ + child->xcp.regs[JB_FP] = newfp; /* Frame pointer */ + child->xcp.regs[JB_SP] = newsp; /* Stack pointer */ /* And, finally, start the child task. On a failure, nxtask_start_fork() * will discard the TCB by calling nxtask_abort_fork(). diff --git a/arch/x86_64/src/common/x86_64_fork.c b/arch/x86_64/src/common/x86_64_fork.c index f52a313dfc322..a1e3b642d6b14 100644 --- a/arch/x86_64/src/common/x86_64_fork.c +++ b/arch/x86_64/src/common/x86_64_fork.c @@ -92,7 +92,7 @@ pid_t x86_64_fork(const struct fork_s *context) { struct tcb_s *parent = this_task(); - struct task_tcb_s *child; + struct tcb_s *child; uint64_t newsp; uint64_t newfp; uint64_t newtop; @@ -140,15 +140,15 @@ pid_t x86_64_fork(const struct fork_s *context) * effort is overkill. */ - newtop = (uint64_t)XCP_ALIGN_DOWN((uintptr_t)child->cmn.stack_base_ptr + - child->cmn.adj_stack_size - + newtop = (uint64_t)XCP_ALIGN_DOWN((uintptr_t)child->stack_base_ptr + + child->adj_stack_size - XCPTCONTEXT_SIZE); newsp = newtop - stackutil; /* Move the register context (from parent) to newtop. */ - memcpy(child->cmn.xcp.regs, parent->xcp.regs, XCPTCONTEXT_SIZE); + memcpy(child->xcp.regs, parent->xcp.regs, XCPTCONTEXT_SIZE); memcpy((void *)newsp, (const void *)context->rsp, stackutil); @@ -178,18 +178,18 @@ pid_t x86_64_fork(const struct fork_s *context) * child thread. */ - child->cmn.xcp.regs[REG_RAX] = 0; /* Parent proc return 0 */ - child->cmn.xcp.regs[REG_R12] = context->r12; /* Non-volatile register r12 */ - child->cmn.xcp.regs[REG_R13] = context->r13; /* Non-volatile register r13 */ - child->cmn.xcp.regs[REG_R14] = context->r14; /* Non-volatile register r14 */ - child->cmn.xcp.regs[REG_R15] = context->r15; /* Non-volatile register r15 */ - child->cmn.xcp.regs[REG_RBX] = context->rbx; /* Non-volatile register rbx */ - child->cmn.xcp.regs[REG_SS] = context->ss; /* SS */ - child->cmn.xcp.regs[REG_CS] = context->cs; /* CS */ - child->cmn.xcp.regs[REG_RFLAGS] = context->rflags; - child->cmn.xcp.regs[REG_RIP] = context->rip; - child->cmn.xcp.regs[REG_RSP] = newsp; /* Stack pointer */ - child->cmn.xcp.regs[REG_RBP] = newfp; /* Like registers */ + child->xcp.regs[REG_RAX] = 0; /* Parent proc return 0 */ + child->xcp.regs[REG_R12] = context->r12; /* Non-volatile register r12 */ + child->xcp.regs[REG_R13] = context->r13; /* Non-volatile register r13 */ + child->xcp.regs[REG_R14] = context->r14; /* Non-volatile register r14 */ + child->xcp.regs[REG_R15] = context->r15; /* Non-volatile register r15 */ + child->xcp.regs[REG_RBX] = context->rbx; /* Non-volatile register rbx */ + child->xcp.regs[REG_SS] = context->ss; /* SS */ + child->xcp.regs[REG_CS] = context->cs; /* CS */ + child->xcp.regs[REG_RFLAGS] = context->rflags; + child->xcp.regs[REG_RIP] = context->rip; + child->xcp.regs[REG_RSP] = newsp; /* Stack pointer */ + child->xcp.regs[REG_RBP] = newfp; /* Like registers */ /* And, finally, start the child task. On a failure, nxtask_start_fork() * will discard the TCB by calling nxtask_abort_fork(). diff --git a/binfmt/binfmt_execmodule.c b/binfmt/binfmt_execmodule.c index 979c9b5ce15ad..fbfa08a5dc266 100644 --- a/binfmt/binfmt_execmodule.c +++ b/binfmt/binfmt_execmodule.c @@ -156,7 +156,7 @@ int exec_module(FAR struct binary_s *binp, FAR const posix_spawnattr_t *attr, bool spawn) { - FAR struct task_tcb_s *tcb; + FAR struct tcb_s *tcb; #if defined(CONFIG_ARCH_ADDRENV) && defined(CONFIG_BUILD_KERNEL) FAR struct arch_addrenv_s *addrenv = &binp->addrenv->addrenv; FAR void *vheap; @@ -179,12 +179,14 @@ int exec_module(FAR struct binary_s *binp, /* Allocate a TCB for the new task. */ - tcb = kmm_zalloc(sizeof(struct task_tcb_s)); + tcb = kmm_zalloc(sizeof(struct tcb_s) + sizeof(struct task_group_s)); if (!tcb) { return -ENOMEM; } + tcb = (FAR void *)((uintptr_t)tcb + sizeof(struct task_group_s)); + ret = binfmt_copyargv(&argv, argv); if (ret < 0) { @@ -243,7 +245,7 @@ int exec_module(FAR struct binary_s *binp, #if defined(CONFIG_ARCH_ADDRENV) && defined(CONFIG_ARCH_KERNEL_STACK) /* Allocate the kernel stack */ - ret = up_addrenv_kstackalloc(&tcb->cmn); + ret = up_addrenv_kstackalloc(tcb); if (ret < 0) { berr("ERROR: up_addrenv_kstackalloc() failed: %d\n", ret); @@ -251,11 +253,11 @@ int exec_module(FAR struct binary_s *binp, } #endif - /* Note that tcb->cmn.flags are not modified. 0=normal task */ + /* Note that tcb->flags are not modified. 0=normal task */ - /* tcb->cmn.flags |= TCB_FLAG_TTYPE_TASK; */ + /* tcb->flags |= TCB_FLAG_TTYPE_TASK; */ - tcb->cmn.flags |= TCB_FLAG_FREE_TCB; + tcb->flags |= TCB_FLAG_FREE_TCB; /* Initialize the task */ @@ -293,17 +295,17 @@ int exec_module(FAR struct binary_s *binp, * must be the first allocated address space. */ - tcb->cmn.dspace = binp->picbase; + tcb->dspace = binp->picbase; /* Re-initialize the task's initial state to account for the new PIC base */ - up_initial_state(&tcb->cmn); + up_initial_state(tcb); #endif #ifdef CONFIG_ARCH_ADDRENV /* Attach the address environment to the new task */ - ret = addrenv_attach((FAR struct tcb_s *)tcb, binp->addrenv); + ret = addrenv_attach(tcb, binp->addrenv); if (ret < 0) { berr("ERROR: addrenv_attach() failed: %d\n", ret); @@ -314,23 +316,23 @@ int exec_module(FAR struct binary_s *binp, #ifdef CONFIG_SCHED_USER_IDENTITY if (binp->mode & S_ISUID) { - tcb->cmn.group->tg_euid = binp->uid; + tcb->group->tg_euid = binp->uid; } if (binp->mode & S_ISGID) { - tcb->cmn.group->tg_egid = binp->gid; + tcb->group->tg_egid = binp->gid; } #endif if (!spawn) { - exec_swap(this_task(), (FAR struct tcb_s *)tcb); + exec_swap(this_task(), tcb); } /* Get the assigned pid before we start the task */ - pid = tcb->cmn.pid; + pid = tcb->pid; #if defined(CONFIG_ARCH_ADDRENV) && defined(CONFIG_BUILD_KERNEL) /* Restore the address environment of the caller */ @@ -356,7 +358,7 @@ int exec_module(FAR struct binary_s *binp, /* Then activate the task at the provided priority */ - nxtask_activate((FAR struct tcb_s *)tcb); + nxtask_activate(tcb); return pid; @@ -364,7 +366,7 @@ int exec_module(FAR struct binary_s *binp, #ifndef CONFIG_BUILD_KERNEL if (binp->stackaddr != NULL) { - tcb->cmn.stack_alloc_ptr = NULL; + tcb->stack_alloc_ptr = NULL; } #endif diff --git a/include/nuttx/mm/map.h b/include/nuttx/mm/map.h index eff3bac8254b9..22df037e72c42 100644 --- a/include/nuttx/mm/map.h +++ b/include/nuttx/mm/map.h @@ -129,7 +129,7 @@ void mm_map_unlock(void); * Name: mm_map_initialize * * Description: - * Initialization function, called only by group_initialize + * Initialization function, called only by group_postinitialize * * Input Parameters: * mm - Pointer to the mm_map structure to be initialized diff --git a/include/nuttx/sched.h b/include/nuttx/sched.h index 1059bb9f004f9..b5f5e25ca0ef3 100644 --- a/include/nuttx/sched.h +++ b/include/nuttx/sched.h @@ -729,25 +729,6 @@ struct tcb_s #endif }; -/* struct task_tcb_s ********************************************************/ - -/* This is the particular form of the task control block (TCB) structure used - * by tasks (and kernel threads). There are two TCB forms: one for pthreads - * and one for tasks. - * Both share the common TCB fields (which must appear at the top of the - * structure) plus additional fields unique to tasks and threads. - * Having separate structures for tasks and pthreads adds some complexity, - * but saves memory in that it prevents pthreads from being burdened with the - * overhead required for tasks (and vice versa). - */ - -struct task_tcb_s -{ - /* Common TCB fields ******************************************************/ - - struct tcb_s cmn; /* Common TCB fields */ -}; - /* struct pthread_tcb_s *****************************************************/ /* This is the particular form of the task control block (TCB) structure used @@ -1009,7 +990,7 @@ FAR struct fdlist *nxsched_get_fdlist(void); * ****************************************************************************/ -int nxtask_init(FAR struct task_tcb_s *tcb, const char *name, int priority, +int nxtask_init(FAR struct tcb_s *tcb, const char *name, int priority, FAR void *stack, uint32_t stack_size, main_t entry, FAR char * const argv[], FAR char * const envp[], FAR const posix_spawn_file_actions_t *actions); @@ -1033,7 +1014,7 @@ int nxtask_init(FAR struct task_tcb_s *tcb, const char *name, int priority, * ****************************************************************************/ -void nxtask_uninit(FAR struct task_tcb_s *tcb); +void nxtask_uninit(FAR struct tcb_s *tcb); /**************************************************************************** * Name: nxtask_create @@ -1169,9 +1150,9 @@ void nxtask_startup(main_t entrypt, int argc, FAR char *argv[]); * ****************************************************************************/ -FAR struct task_tcb_s *nxtask_setup_fork(start_t retaddr); -pid_t nxtask_start_fork(FAR struct task_tcb_s *child); -void nxtask_abort_fork(FAR struct task_tcb_s *child, int errcode); +FAR struct tcb_s *nxtask_setup_fork(start_t retaddr); +pid_t nxtask_start_fork(FAR struct tcb_s *child); +void nxtask_abort_fork(FAR struct tcb_s *child, int errcode); /**************************************************************************** * Name: nxtask_argvstr diff --git a/sched/group/group.h b/sched/group/group.h index a8c4f908c2ce8..909e7f12ce8ef 100644 --- a/sched/group/group.h +++ b/sched/group/group.h @@ -58,8 +58,8 @@ void task_initialize(void); /* Task group data structure management */ -int group_allocate(FAR struct task_tcb_s *tcb, uint8_t ttype); -void group_initialize(FAR struct task_tcb_s *tcb); +int group_initialize(FAR struct tcb_s *tcb, uint8_t ttype); +void group_postinitialize(FAR struct tcb_s *tcb); #ifndef CONFIG_DISABLE_PTHREAD void group_bind(FAR struct pthread_tcb_s *tcb); void group_join(FAR struct pthread_tcb_s *tcb); @@ -112,7 +112,7 @@ void group_remove_children(FAR struct task_group_s *group); /* Group data resource configuration */ int group_setupidlefiles(void); -int group_setuptaskfiles(FAR struct task_tcb_s *tcb, +int group_setuptaskfiles(FAR struct tcb_s *tcb, FAR const posix_spawn_file_actions_t *actions, bool cloexec); diff --git a/sched/group/group_create.c b/sched/group/group_create.c index 1c5f5f81e417e..19b93ded7b9ba 100644 --- a/sched/group/group_create.c +++ b/sched/group/group_create.c @@ -92,7 +92,7 @@ static inline void group_inherit_identity(FAR struct task_group_s *group) ****************************************************************************/ /**************************************************************************** - * Name: group_allocate + * Name: group_initialize * * Description: * Create and a new task group structure for the specified TCB. This @@ -100,8 +100,8 @@ static inline void group_inherit_identity(FAR struct task_group_s *group) * allocated and zeroed, but otherwise uninitialized. The full creation * of the group of a two step process: (1) First, this function allocates * group structure early in the task creation sequence in order to provide - * a group container, then (2) group_initialize() is called to set up the - * group membership. + * a group container, then (2) group_postinitialize() is called to set up + * the group membership. * * Input Parameters: * tcb - The tcb in need of the task group. @@ -116,12 +116,12 @@ static inline void group_inherit_identity(FAR struct task_group_s *group) * ****************************************************************************/ -int group_allocate(FAR struct task_tcb_s *tcb, uint8_t ttype) +int group_initialize(FAR struct tcb_s *tcb, uint8_t ttype) { FAR struct task_group_s *group; int ret; - DEBUGASSERT(tcb && !tcb->cmn.group); + DEBUGASSERT(tcb && !tcb->group); ttype &= TCB_FLAG_TTYPE_MASK; @@ -130,20 +130,21 @@ int group_allocate(FAR struct task_tcb_s *tcb, uint8_t ttype) if (ttype == TCB_FLAG_TTYPE_KERNEL) { group = &g_kthread_group; - tcb->cmn.group = group; + tcb->group = group; if (group->tg_info) { return OK; } } - else + else if (ttype == TCB_FLAG_TTYPE_TASK) { - group = kmm_zalloc(sizeof(struct task_group_s)); + tcb->group = (FAR void *)((uintptr_t)tcb - + sizeof(struct task_group_s)); + group = tcb->group; } - - if (!group) + else { - return -ENOMEM; + group = tcb->group; } #if defined(CONFIG_MM_KERNEL_HEAP) @@ -165,7 +166,7 @@ int group_allocate(FAR struct task_tcb_s *tcb, uint8_t ttype) /* Attach the group to the TCB */ - tcb->cmn.group = group; + tcb->group = group; /* Inherit the user identity from the parent task group */ @@ -180,7 +181,7 @@ int group_allocate(FAR struct task_tcb_s *tcb, uint8_t ttype) ret = task_init_info(group); if (ret < 0) { - goto errout_with_group; + return ret; } nxrmutex_init(&group->tg_mutex); @@ -198,20 +199,17 @@ int group_allocate(FAR struct task_tcb_s *tcb, uint8_t ttype) #endif return OK; - -errout_with_group: - kmm_free(group); - return ret; } /**************************************************************************** - * Name: group_initialize + * Name: group_postinitialize * * Description: * Add the task as the initial member of the group. The full creation of * the group of a two step process: (1) First, this group structure is - * allocated by group_allocate() early in the task creation sequence, then - * (2) this function is called to set up the initial group membership. + * allocated by group_initialize() early in the task creation sequence, + * then (2) this function is called to set up the initial group + * membership. * * Input Parameters: * tcb - The tcb in need of the task group. @@ -225,23 +223,23 @@ int group_allocate(FAR struct task_tcb_s *tcb, uint8_t ttype) * ****************************************************************************/ -void group_initialize(FAR struct task_tcb_s *tcb) +void group_postinitialize(FAR struct tcb_s *tcb) { FAR struct task_group_s *group; - DEBUGASSERT(tcb && tcb->cmn.group); - group = tcb->cmn.group; + DEBUGASSERT(tcb && tcb->group); + group = tcb->group; spin_lock_init(&group->tg_lock); /* Allocate mm_map list if required */ mm_map_initialize(&group->tg_mm_map, - (tcb->cmn.flags & TCB_FLAG_TTYPE_KERNEL) != 0); + (tcb->flags & TCB_FLAG_TTYPE_KERNEL) != 0); #ifdef HAVE_GROUP_MEMBERS /* Assign the PID of this new task as a member of the group. */ - sq_addlast(&tcb->cmn.member, &group->tg_members); + sq_addlast(&tcb->member, &group->tg_members); #endif /* Save the ID of the main task within the group of threads. This needed @@ -252,6 +250,6 @@ void group_initialize(FAR struct task_tcb_s *tcb) if (group != &g_kthread_group) { - group->tg_pid = tcb->cmn.pid; + group->tg_pid = tcb->pid; } } diff --git a/sched/group/group_foreachchild.c b/sched/group/group_foreachchild.c index 8b830837833c6..a0cf1f25458a8 100644 --- a/sched/group/group_foreachchild.c +++ b/sched/group/group_foreachchild.c @@ -64,7 +64,7 @@ int group_foreachchild(FAR struct task_group_s *group, { FAR sq_entry_t *curr; FAR sq_entry_t *next; - int ret; + int ret = OK; DEBUGASSERT(group); diff --git a/sched/group/group_leave.c b/sched/group/group_leave.c index 5e69dc2d3499a..0f2d203e8a085 100644 --- a/sched/group/group_leave.c +++ b/sched/group/group_leave.c @@ -31,6 +31,7 @@ #include #include +#include #include #include #include @@ -70,7 +71,8 @@ * ****************************************************************************/ -static inline void group_release(FAR struct task_group_s *group) +static inline void +group_release(FAR struct task_group_s *group) { /* Destroy the mutex */ @@ -171,6 +173,12 @@ void group_leave(FAR struct tcb_s *tcb) group = tcb->group; if (group) { + /* In any event, we can detach the group from the TCB so that we won't + * do this again. + */ + + tcb->group = NULL; + /* Remove the member from group. */ #ifdef HAVE_GROUP_MEMBERS @@ -187,12 +195,6 @@ void group_leave(FAR struct tcb_s *tcb) group_release(group); } - - /* In any event, we can detach the group from the TCB so that we won't - * do this again. - */ - - tcb->group = NULL; } } @@ -233,7 +235,6 @@ void group_drop(FAR struct task_group_s *group) } else #endif - /* Finally, if no one needs the group and it has been deleted, remove it */ if (group->tg_flags & GROUP_FLAG_DELETED) diff --git a/sched/group/group_setuptaskfiles.c b/sched/group/group_setuptaskfiles.c index cab58e82458aa..18f69f49365eb 100644 --- a/sched/group/group_setuptaskfiles.c +++ b/sched/group/group_setuptaskfiles.c @@ -59,11 +59,11 @@ * ****************************************************************************/ -int group_setuptaskfiles(FAR struct task_tcb_s *tcb, +int group_setuptaskfiles(FAR struct tcb_s *tcb, FAR const posix_spawn_file_actions_t *actions, bool cloexec) { - FAR struct task_group_s *group = tcb->cmn.group; + FAR struct task_group_s *group = tcb->group; int ret = OK; #ifndef CONFIG_FDCLONE_DISABLE FAR struct tcb_s *rtcb = this_task(); @@ -72,7 +72,7 @@ int group_setuptaskfiles(FAR struct task_tcb_s *tcb, sched_trace_begin(); DEBUGASSERT(group); #ifndef CONFIG_DISABLE_PTHREAD - DEBUGASSERT((tcb->cmn.flags & TCB_FLAG_TTYPE_MASK) != + DEBUGASSERT((tcb->flags & TCB_FLAG_TTYPE_MASK) != TCB_FLAG_TTYPE_PTHREAD); #endif @@ -84,16 +84,16 @@ int group_setuptaskfiles(FAR struct task_tcb_s *tcb, */ if (group != rtcb->group && - (tcb->cmn.flags & TCB_FLAG_TTYPE_MASK) != TCB_FLAG_TTYPE_KERNEL) + (tcb->flags & TCB_FLAG_TTYPE_MASK) != TCB_FLAG_TTYPE_KERNEL) { ret = fdlist_copy(&rtcb->group->tg_fdlist, &group->tg_fdlist, actions, cloexec); } if (ret >= 0 && actions != NULL && - (tcb->cmn.flags & TCB_FLAG_TTYPE_MASK) != TCB_FLAG_TTYPE_KERNEL) + (tcb->flags & TCB_FLAG_TTYPE_MASK) != TCB_FLAG_TTYPE_KERNEL) { - ret = spawn_file_actions(&tcb->cmn, actions); + ret = spawn_file_actions(tcb, actions); } #endif diff --git a/sched/init/nx_start.c b/sched/init/nx_start.c index 79f57e4029e48..791bd2e74715d 100644 --- a/sched/init/nx_start.c +++ b/sched/init/nx_start.c @@ -445,7 +445,7 @@ static void idle_group_initialize(void) /* Allocate the IDLE group */ DEBUGVERIFY( - group_allocate((FAR struct task_tcb_s *)tcb, tcb->flags)); + group_initialize(tcb, tcb->flags)); /* Initialize the task join */ @@ -478,7 +478,7 @@ static void idle_group_initialize(void) * of child status in the IDLE group. */ - group_initialize((FAR struct task_tcb_s *)tcb); + group_postinitialize(tcb); tcb->group->tg_flags = GROUP_FLAG_NOCLDWAIT | GROUP_FLAG_PRIVILEGED; } } @@ -705,8 +705,7 @@ void nx_start(void) { /* Clone stdout, stderr, stdin from the CPU0 IDLE task. */ - DEBUGVERIFY(group_setuptaskfiles( - (FAR struct task_tcb_s *)&g_idletcb[i], NULL, true)); + DEBUGVERIFY(group_setuptaskfiles(&g_idletcb[i], NULL, true)); } else { diff --git a/sched/pthread/pthread_create.c b/sched/pthread/pthread_create.c index 023e15eeea01f..108e165102887 100644 --- a/sched/pthread/pthread_create.c +++ b/sched/pthread/pthread_create.c @@ -209,8 +209,7 @@ int nx_pthread_create(pthread_trampoline_t trampoline, FAR pthread_t *thread, /* Allocate a TCB for the new task. */ - ptcb = (FAR struct pthread_tcb_s *) - kmm_zalloc(sizeof(struct pthread_tcb_s)); + ptcb = kmm_zalloc(sizeof(struct pthread_tcb_s)); if (!ptcb) { serr("ERROR: Failed to allocate TCB\n"); diff --git a/sched/sched/sched_releasetcb.c b/sched/sched/sched_releasetcb.c index 96b3e736e79cd..c8ec8a268281c 100644 --- a/sched/sched/sched_releasetcb.c +++ b/sched/sched/sched_releasetcb.c @@ -178,7 +178,10 @@ int nxsched_release_tcb(FAR struct tcb_s *tcb, uint8_t ttype) if (tcb->flags & TCB_FLAG_FREE_TCB) { - kmm_free(tcb); + if (ttype != TCB_FLAG_TTYPE_TASK) + { + kmm_free(tcb); + } } } diff --git a/sched/task/task.h b/sched/task/task.h index 6ce8a3afcddde..efdaf519ad5bb 100644 --- a/sched/task/task.h +++ b/sched/task/task.h @@ -44,13 +44,13 @@ struct tcb_s; /* Forward reference */ /* Task start-up */ void nxtask_start(void); -int nxtask_setup_stackargs(FAR struct task_tcb_s *tcb, +int nxtask_setup_stackargs(FAR struct tcb_s *tcb, FAR const char *name, FAR char * const argv[]); -int nxtask_setup_scheduler(FAR struct task_tcb_s *tcb, int priority, +int nxtask_setup_scheduler(FAR struct tcb_s *tcb, int priority, start_t start, main_t main, uint8_t ttype); #if CONFIG_TASK_NAME_SIZE > 0 -void nxtask_setup_name(FAR struct task_tcb_s *tcb, FAR const char *name); +void nxtask_setup_name(FAR struct tcb_s *tcb, FAR const char *name); #else # define nxtask_setup_name(tcb, name) #endif diff --git a/sched/task/task_create.c b/sched/task/task_create.c index 3ad6130873f61..e99d8fbc3f576 100644 --- a/sched/task/task_create.c +++ b/sched/task/task_create.c @@ -85,20 +85,23 @@ int nxthread_create(FAR const char *name, uint8_t ttype, int priority, /* Allocate a TCB for the new task. */ tcb = kmm_zalloc(ttype == TCB_FLAG_TTYPE_KERNEL ? - sizeof(struct tcb_s) : sizeof(struct task_tcb_s)); + sizeof(struct tcb_s) : + sizeof(struct tcb_s) + sizeof(struct task_group_s)); if (!tcb) { serr("ERROR: Failed to allocate TCB\n"); return -ENOMEM; } + tcb = (FAR void *)((uintptr_t)tcb + sizeof(struct task_group_s)); + /* Setup the task type */ tcb->flags = ttype | TCB_FLAG_FREE_TCB; /* Initialize the task */ - ret = nxtask_init((FAR struct task_tcb_s *)tcb, name, priority, + ret = nxtask_init(tcb, name, priority, stack_addr, stack_size, entry, argv, envp, NULL); if (ret < OK) { diff --git a/sched/task/task_exithook.c b/sched/task/task_exithook.c index 268931b247df1..9ce9424ff5121 100644 --- a/sched/task/task_exithook.c +++ b/sched/task/task_exithook.c @@ -447,16 +447,16 @@ void nxtask_exithook(FAR struct tcb_s *tcb, int status) sched_unlock(); + /* Deallocate anything left in the TCB's queues */ + + nxsig_cleanup(tcb); /* Deallocate Signal lists */ + /* Leave the task group. Perhaps discarding any un-reaped child * status (no zombies here!) */ group_leave(tcb); - /* Deallocate anything left in the TCB's queues */ - - nxsig_cleanup(tcb); /* Deallocate Signal lists */ - #ifdef CONFIG_SCHED_DUMP_LEAK if ((tcb->flags & TCB_FLAG_TTYPE_MASK) == TCB_FLAG_TTYPE_KERNEL) { diff --git a/sched/task/task_fork.c b/sched/task/task_fork.c index a9b7f071b8407..08d4d276755bf 100644 --- a/sched/task/task_fork.c +++ b/sched/task/task_fork.c @@ -93,11 +93,11 @@ * ****************************************************************************/ -FAR struct task_tcb_s *nxtask_setup_fork(start_t retaddr) +FAR struct tcb_s *nxtask_setup_fork(start_t retaddr) { FAR struct tcb_s *ptcb = this_task(); FAR struct tcb_s *parent; - FAR struct task_tcb_s *child; + FAR struct tcb_s *child; FAR char **argv; size_t stack_size; uint8_t ttype; @@ -137,7 +137,7 @@ FAR struct task_tcb_s *nxtask_setup_fork(start_t retaddr) /* Allocate a TCB for the child task. */ - child = kmm_zalloc(sizeof(struct task_tcb_s)); + child = kmm_zalloc(sizeof(struct tcb_s) + sizeof(struct task_group_s)); if (!child) { serr("ERROR: Failed to allocate TCB\n"); @@ -145,14 +145,16 @@ FAR struct task_tcb_s *nxtask_setup_fork(start_t retaddr) goto errout; } - child->cmn.flags |= TCB_FLAG_FREE_TCB; + child = (FAR void *)((uintptr_t)child + sizeof(struct task_group_s)); + + child->flags |= TCB_FLAG_FREE_TCB; #if defined(CONFIG_ARCH_ADDRENV) /* Join the parent address environment (REVISIT: vfork() only) */ if (ttype != TCB_FLAG_TTYPE_KERNEL) { - ret = addrenv_join(parent, &child->cmn); + ret = addrenv_join(parent, child); if (ret < 0) { goto errout_with_tcb; @@ -162,15 +164,15 @@ FAR struct task_tcb_s *nxtask_setup_fork(start_t retaddr) /* Initialize the task join */ - nxtask_joininit(&child->cmn); + nxtask_joininit(child); #if !defined(CONFIG_DISABLE_PTHREAD) && !defined(CONFIG_PTHREAD_MUTEX_UNSAFE) - spin_lock_init(&child->cmn.mhead_lock); + spin_lock_init(&child->mhead_lock); #endif /* Allocate a new task group with the same privileges as the parent */ - ret = group_allocate(child, ttype); + ret = group_initialize(child, ttype); if (ret < 0) { goto errout_with_tcb; @@ -178,7 +180,7 @@ FAR struct task_tcb_s *nxtask_setup_fork(start_t retaddr) /* Duplicate the parent tasks environment */ - ret = env_dup(child->cmn.group, environ); + ret = env_dup(child->group, environ); if (ret < 0) { goto errout_with_tcb; @@ -202,7 +204,7 @@ FAR struct task_tcb_s *nxtask_setup_fork(start_t retaddr) stack_size = (uintptr_t)ptcb->stack_base_ptr - (uintptr_t)ptcb->stack_alloc_ptr + ptcb->adj_stack_size; - ret = up_create_stack(&child->cmn, stack_size, ttype); + ret = up_create_stack(child, stack_size, ttype); if (ret < OK) { goto errout_with_tcb; @@ -213,7 +215,7 @@ FAR struct task_tcb_s *nxtask_setup_fork(start_t retaddr) if (ttype != TCB_FLAG_TTYPE_KERNEL) { - ret = up_addrenv_kstackalloc(&child->cmn); + ret = up_addrenv_kstackalloc(child); if (ret < 0) { goto errout_with_tcb; @@ -223,7 +225,7 @@ FAR struct task_tcb_s *nxtask_setup_fork(start_t retaddr) /* Setup thread local storage */ - ret = tls_dup_info(&child->cmn, parent); + ret = tls_dup_info(child, parent); if (ret < OK) { goto errout_with_tcb; @@ -257,7 +259,7 @@ FAR struct task_tcb_s *nxtask_setup_fork(start_t retaddr) /* Now we have enough in place that we can join the group */ - group_initialize(child); + group_postinitialize(child); sinfo("parent=%p, returning child=%p\n", parent, child); return child; @@ -301,7 +303,7 @@ FAR struct task_tcb_s *nxtask_setup_fork(start_t retaddr) * 6) nxtask_start_fork() then executes the child thread. * * Input Parameters: - * child - The task_tcb_s struct instance that created by + * child - The tcb_s struct instance that created by * nxtask_setup_fork() method * wait_child - whether need to wait until the child is running finished * @@ -313,7 +315,7 @@ FAR struct task_tcb_s *nxtask_setup_fork(start_t retaddr) * ****************************************************************************/ -pid_t nxtask_start_fork(FAR struct task_tcb_s *child) +pid_t nxtask_start_fork(FAR struct tcb_s *child) { pid_t pid; @@ -322,11 +324,11 @@ pid_t nxtask_start_fork(FAR struct task_tcb_s *child) /* Get the assigned pid before we start the task */ - pid = child->cmn.pid; + pid = child->pid; /* Activate the task */ - nxtask_activate((FAR struct tcb_s *)child); + nxtask_activate(child); return pid; } @@ -342,7 +344,7 @@ pid_t nxtask_start_fork(FAR struct task_tcb_s *child) * ****************************************************************************/ -void nxtask_abort_fork(FAR struct task_tcb_s *child, int errcode) +void nxtask_abort_fork(FAR struct tcb_s *child, int errcode) { /* The TCB was added to the active task list by nxtask_setup_scheduler() */ @@ -350,8 +352,7 @@ void nxtask_abort_fork(FAR struct task_tcb_s *child, int errcode) /* Release the TCB */ - nxsched_release_tcb((FAR struct tcb_s *)child, - child->cmn.flags & TCB_FLAG_TTYPE_MASK); + nxsched_release_tcb(child, child->flags & TCB_FLAG_TTYPE_MASK); set_errno(errcode); } diff --git a/sched/task/task_init.c b/sched/task/task_init.c index a3f8d9c78abf1..84c1757a4b964 100644 --- a/sched/task/task_init.c +++ b/sched/task/task_init.c @@ -85,13 +85,13 @@ * ****************************************************************************/ -int nxtask_init(FAR struct task_tcb_s *tcb, const char *name, int priority, +int nxtask_init(FAR struct tcb_s *tcb, const char *name, int priority, FAR void *stack, uint32_t stack_size, main_t entry, FAR char * const argv[], FAR char * const envp[], FAR const posix_spawn_file_actions_t *actions) { - uint8_t ttype = tcb->cmn.flags & TCB_FLAG_TTYPE_MASK; + uint8_t ttype = tcb->flags & TCB_FLAG_TTYPE_MASK; int ret; sched_trace_begin(); @@ -107,13 +107,13 @@ int nxtask_init(FAR struct task_tcb_s *tcb, const char *name, int priority, if (ttype == TCB_FLAG_TTYPE_KERNEL) { - tcb->cmn.addrenv_own = NULL; + tcb->addrenv_own = NULL; } #endif /* Create a new task group */ - ret = group_allocate(tcb, tcb->cmn.flags); + ret = group_initialize(tcb, tcb->flags); if (ret < 0) { sched_trace_end(); @@ -123,16 +123,16 @@ int nxtask_init(FAR struct task_tcb_s *tcb, const char *name, int priority, #ifndef CONFIG_DISABLE_PTHREAD /* Initialize the task join */ - nxtask_joininit(&tcb->cmn); + nxtask_joininit(tcb); #endif #if !defined(CONFIG_DISABLE_PTHREAD) && !defined(CONFIG_PTHREAD_MUTEX_UNSAFE) - spin_lock_init(&tcb->cmn.mhead_lock); + spin_lock_init(&tcb->mhead_lock); #endif /* Duplicate the parent tasks environment */ - ret = env_dup(tcb->cmn.group, envp); + ret = env_dup(tcb->group, envp); if (ret < 0) { goto errout_with_group; @@ -154,13 +154,13 @@ int nxtask_init(FAR struct task_tcb_s *tcb, const char *name, int priority, { /* Use pre-allocated stack */ - ret = up_use_stack(&tcb->cmn, stack, stack_size); + ret = up_use_stack(tcb, stack, stack_size); } else { /* Allocate the stack for the TCB */ - ret = up_create_stack(&tcb->cmn, stack_size, ttype); + ret = up_create_stack(tcb, stack_size, ttype); } if (ret < OK) @@ -179,7 +179,7 @@ int nxtask_init(FAR struct task_tcb_s *tcb, const char *name, int priority, /* Initialize thread local storage */ - ret = tls_init_info(&tcb->cmn); + ret = tls_init_info(tcb); if (ret < OK) { goto errout_with_group; @@ -195,12 +195,12 @@ int nxtask_init(FAR struct task_tcb_s *tcb, const char *name, int priority, /* Now we have enough in place that we can join the group */ - group_initialize(tcb); + group_postinitialize(tcb); sched_trace_end(); return ret; errout_with_group: - if (!stack && tcb->cmn.stack_alloc_ptr) + if (!stack && tcb->stack_alloc_ptr) { #ifdef CONFIG_BUILD_KERNEL /* If the exiting thread is not a kernel thread, then it has an @@ -216,13 +216,13 @@ int nxtask_init(FAR struct task_tcb_s *tcb, const char *name, int priority, if (ttype == TCB_FLAG_TTYPE_KERNEL) #endif { - up_release_stack(&tcb->cmn, ttype); + up_release_stack(tcb, ttype); } } - nxtask_joindestroy(&tcb->cmn); + nxtask_joindestroy(tcb); - group_leave(&tcb->cmn); + group_leave(tcb); sched_trace_end(); return ret; @@ -247,7 +247,7 @@ int nxtask_init(FAR struct task_tcb_s *tcb, const char *name, int priority, * ****************************************************************************/ -void nxtask_uninit(FAR struct task_tcb_s *tcb) +void nxtask_uninit(FAR struct tcb_s *tcb) { /* The TCB was added to the inactive task list by * nxtask_setup_scheduler(). @@ -259,6 +259,5 @@ void nxtask_uninit(FAR struct task_tcb_s *tcb) * itself. */ - nxsched_release_tcb((FAR struct tcb_s *)tcb, - tcb->cmn.flags & TCB_FLAG_TTYPE_MASK); + nxsched_release_tcb(tcb, tcb->flags & TCB_FLAG_TTYPE_MASK); } diff --git a/sched/task/task_setup.c b/sched/task/task_setup.c index 7b893b4b3b8f5..8523ae725a940 100644 --- a/sched/task/task_setup.c +++ b/sched/task/task_setup.c @@ -516,7 +516,7 @@ static int nxthread_setup_scheduler(FAR struct tcb_s *tcb, int priority, * ****************************************************************************/ -int nxtask_setup_stackargs(FAR struct task_tcb_s *tcb, +int nxtask_setup_stackargs(FAR struct tcb_s *tcb, FAR const char *name, FAR char * const argv[]) { @@ -557,8 +557,8 @@ int nxtask_setup_stackargs(FAR struct task_tcb_s *tcb, */ strtablen += (strlen(argv[argc]) + 1); - DEBUGASSERT(strtablen < tcb->cmn.adj_stack_size); - if (strtablen >= tcb->cmn.adj_stack_size) + DEBUGASSERT(strtablen < tcb->adj_stack_size); + if (strtablen >= tcb->adj_stack_size) { return -ENAMETOOLONG; } @@ -583,7 +583,7 @@ int nxtask_setup_stackargs(FAR struct task_tcb_s *tcb, */ argvlen = (argc + 2) * sizeof(FAR char *); - stackargv = (FAR char **)up_stack_frame(&tcb->cmn, argvlen + strtablen); + stackargv = (FAR char **)up_stack_frame(tcb, argvlen + strtablen); DEBUGASSERT(stackargv != NULL); if (stackargv == NULL) @@ -658,7 +658,7 @@ int nxtask_setup_stackargs(FAR struct task_tcb_s *tcb, * ****************************************************************************/ -int nxtask_setup_scheduler(FAR struct task_tcb_s *tcb, int priority, +int nxtask_setup_scheduler(FAR struct tcb_s *tcb, int priority, start_t start, main_t main, uint8_t ttype) { /* Perform common thread setup */ @@ -719,9 +719,9 @@ int pthread_setup_scheduler(FAR struct pthread_tcb_s *tcb, int priority, ****************************************************************************/ #if CONFIG_TASK_NAME_SIZE > 0 -void nxtask_setup_name(FAR struct task_tcb_s *tcb, FAR const char *name) +void nxtask_setup_name(FAR struct tcb_s *tcb, FAR const char *name) { - FAR char *dst = tcb->cmn.name; + FAR char *dst = tcb->name; int i; /* Give a name to the unnamed tasks */ diff --git a/sched/task/task_spawn.c b/sched/task/task_spawn.c index dd2bbf5c7b870..67c6f061066a6 100644 --- a/sched/task/task_spawn.c +++ b/sched/task/task_spawn.c @@ -86,22 +86,24 @@ static int nxtask_spawn_create(FAR const char *name, int priority, FAR const posix_spawn_file_actions_t *actions, FAR const posix_spawnattr_t *attr) { - FAR struct task_tcb_s *tcb; + FAR struct tcb_s *tcb; pid_t pid; int ret; /* Allocate a TCB for the new task. */ - tcb = kmm_zalloc(sizeof(struct task_tcb_s)); + tcb = kmm_zalloc(sizeof(struct tcb_s) + sizeof(struct task_group_s)); if (tcb == NULL) { serr("ERROR: Failed to allocate TCB\n"); return -ENOMEM; } + tcb = (FAR void *)((uintptr_t)tcb + sizeof(struct task_group_s)); + /* Setup the task type */ - tcb->cmn.flags = TCB_FLAG_TTYPE_TASK | TCB_FLAG_FREE_TCB; + tcb->flags = TCB_FLAG_TTYPE_TASK | TCB_FLAG_FREE_TCB; /* Initialize the task */ @@ -115,7 +117,7 @@ static int nxtask_spawn_create(FAR const char *name, int priority, /* Get the assigned pid before we start the task */ - pid = tcb->cmn.pid; + pid = tcb->pid; /* Set the attributes */ @@ -130,7 +132,7 @@ static int nxtask_spawn_create(FAR const char *name, int priority, /* Activate the task */ - nxtask_activate(&tcb->cmn); + nxtask_activate(tcb); return pid; diff --git a/tools/pynuttx/nxgdb/utils.py b/tools/pynuttx/nxgdb/utils.py index e3a12ab24363b..3aa8e6416cf92 100644 --- a/tools/pynuttx/nxgdb/utils.py +++ b/tools/pynuttx/nxgdb/utils.py @@ -889,8 +889,7 @@ def get_task_argvstr(tcb: Tcb) -> List[str]: if tcb.flags & TCB_FLAG_TTYPE_MASK == TCB_FLAG_TTYPE_PTHREAD: if tcb.type.code != gdb.TYPE_CODE_PTR: tcb = tcb.address - tcb = tcb.cast(lookup_type("struct pthread_tcb_s").pointer()) - return ["", f"{tcb['cmn']['entry']['main']}", f'{tcb["arg"]}'] + return ["", f"{tcb['entry']['main']}", f'{tcb["arg"]}'] tls_info_s = lookup_type("struct tls_info_s").pointer() tls = tcb.stack_alloc_ptr.cast(tls_info_s)