diff --git a/sched/environ/env_dup.c b/sched/environ/env_dup.c index 8a41b393e98ce..389284b9a4229 100644 --- a/sched/environ/env_dup.c +++ b/sched/environ/env_dup.c @@ -72,7 +72,7 @@ int env_dup(FAR struct task_group_s *group, FAR char * const *envcp) /* Is there an environment ? */ - if (envcp != NULL) + if (envcp != NULL && group->tg_envp == NULL) { /* Pre-emption must be disabled throughout the following because the * environment may be shared. diff --git a/sched/group/group_create.c b/sched/group/group_create.c index 1648e286f79f1..a8018e7802253 100644 --- a/sched/group/group_create.c +++ b/sched/group/group_create.c @@ -40,9 +40,11 @@ #include "tls/tls.h" /**************************************************************************** - * Public Data + * Private Data ****************************************************************************/ +static struct task_group_s g_kthread_group; /* Shared among kthreads */ + /**************************************************************************** * Private Functions ****************************************************************************/ @@ -119,9 +121,23 @@ int group_initialize(FAR struct task_tcb_s *tcb, uint8_t ttype) DEBUGASSERT(tcb && !tcb->cmn.group); - /* Allocate the group structure and assign it to the TCB */ + ttype &= TCB_FLAG_TTYPE_MASK; + + /* Initialize group pointer and assign to TCB */ - group = &tcb->group; + if (ttype == TCB_FLAG_TTYPE_KERNEL) + { + group = &g_kthread_group; + tcb->cmn.group = group; + if (group->tg_info) + { + return OK; + } + } + else + { + group = &tcb->group; + } #if defined(CONFIG_MM_KERNEL_HEAP) /* If this group is being created for a privileged thread, then all @@ -222,5 +238,6 @@ void group_postinitialize(FAR struct task_tcb_s *tcb) * task has exited. */ - group->tg_pid = tcb->cmn.pid; + group->tg_pid = (group == &g_kthread_group) ? group->tg_pid : + tcb->cmn.pid; } diff --git a/sched/group/group_setuptaskfiles.c b/sched/group/group_setuptaskfiles.c index 4c074da887233..f5b31537e3518 100644 --- a/sched/group/group_setuptaskfiles.c +++ b/sched/group/group_setuptaskfiles.c @@ -79,7 +79,8 @@ int group_setuptaskfiles(FAR struct task_tcb_s *tcb, /* Duplicate the parent task's file descriptors */ - ret = files_duplist(&rtcb->group->tg_filelist, + ret = (group == rtcb->group) ? OK : + files_duplist(&rtcb->group->tg_filelist, &group->tg_filelist, actions, cloexec); if (ret >= 0 && actions != NULL) { diff --git a/sched/init/nx_start.c b/sched/init/nx_start.c index 26fd5400e063e..a38125229841c 100644 --- a/sched/init/nx_start.c +++ b/sched/init/nx_start.c @@ -205,7 +205,7 @@ uint8_t g_nx_initstate; /* See enum nx_initstate_e */ * bringing up the rest of the system. */ -static struct task_tcb_s g_idletcb[CONFIG_SMP_NCPUS]; +static struct tcb_s g_idletcb[CONFIG_SMP_NCPUS]; /* This is the name of the idle task */ @@ -350,10 +350,11 @@ static void tasklist_initialize(void) static void idle_task_initialize(void) { - FAR struct task_tcb_s *tcb; + FAR struct tcb_s *tcb; FAR dq_queue_t *tasklist; int i; + memset(g_idletcb, 0, sizeof(g_idletcb)); for (i = 0; i < CONFIG_SMP_NCPUS; i++) { tcb = &g_idletcb[i]; @@ -365,9 +366,8 @@ static void idle_task_initialize(void) * that has pid == 0 and sched_priority == 0. */ - memset(tcb, 0, sizeof(struct task_tcb_s)); - tcb->cmn.pid = i; - tcb->cmn.task_state = TSTATE_TASK_RUNNING; + tcb->pid = i; + tcb->task_state = TSTATE_TASK_RUNNING; /* Set the entry point. This is only for debug purposes. NOTE: that * the start_t entry point is not saved. That is acceptable, however, @@ -378,14 +378,14 @@ static void idle_task_initialize(void) #ifdef CONFIG_SMP if (i > 0) { - tcb->cmn.start = nx_idle_trampoline; - tcb->cmn.entry.main = (main_t)nx_idle_trampoline; + tcb->start = nx_idle_trampoline; + tcb->entry.main = (main_t)nx_idle_trampoline; } else #endif { - tcb->cmn.start = nx_start; - tcb->cmn.entry.main = (main_t)nx_start; + tcb->start = nx_start; + tcb->entry.main = (main_t)nx_start; } /* Set the task flags to indicate that this is a kernel thread and, if @@ -393,8 +393,8 @@ static void idle_task_initialize(void) */ #ifdef CONFIG_SMP - tcb->cmn.flags = (TCB_FLAG_TTYPE_KERNEL | TCB_FLAG_CPU_LOCKED); - tcb->cmn.cpu = i; + tcb->flags = (TCB_FLAG_TTYPE_KERNEL | TCB_FLAG_CPU_LOCKED); + tcb->cpu = i; /* Set the affinity mask to allow the thread to run on all CPUs. No, * this IDLE thread can only run on its assigned CPU. That is @@ -404,19 +404,19 @@ static void idle_task_initialize(void) * the IDLE task. */ - tcb->cmn.affinity = + tcb->affinity = (cpu_set_t)(CONFIG_SMP_DEFAULT_CPUSET & SCHED_ALL_CPUS); #else - tcb->cmn.flags = TCB_FLAG_TTYPE_KERNEL; + tcb->flags = TCB_FLAG_TTYPE_KERNEL; #endif #if CONFIG_TASK_NAME_SIZE > 0 /* Set the IDLE task name */ # ifdef CONFIG_SMP - snprintf(tcb->cmn.name, CONFIG_TASK_NAME_SIZE, "CPU%d IDLE", i); + snprintf(tcb->name, CONFIG_TASK_NAME_SIZE, "CPU%d IDLE", i); # else - strlcpy(tcb->cmn.name, g_idlename, CONFIG_TASK_NAME_SIZE); + strlcpy(tcb->name, g_idlename, CONFIG_TASK_NAME_SIZE); # endif /* Configure the task name in the argument list. The IDLE task does @@ -427,7 +427,7 @@ static void idle_task_initialize(void) * stack and there is no support that yet. */ - g_idleargv[i][0] = tcb->cmn.name; + g_idleargv[i][0] = tcb->name; #else g_idleargv[i][0] = (FAR char *)g_idlename; #endif /* CONFIG_TASK_NAME_SIZE */ @@ -437,15 +437,15 @@ static void idle_task_initialize(void) */ #ifdef CONFIG_SMP - tasklist = TLIST_HEAD(&tcb->cmn, i); + tasklist = TLIST_HEAD(tcb, i); #else - tasklist = TLIST_HEAD(&tcb->cmn); + tasklist = TLIST_HEAD(tcb); #endif dq_addfirst((FAR dq_entry_t *)tcb, tasklist); /* Mark the idle task as the running task */ - g_running_tasks[i] = &tcb->cmn; + g_running_tasks[i] = tcb; } } @@ -459,7 +459,7 @@ static void idle_task_initialize(void) static void idle_group_initialize(void) { - FAR struct task_tcb_s *tcb; + FAR struct tcb_s *tcb; int hashndx; int i; @@ -470,16 +470,17 @@ static void idle_group_initialize(void) tcb = &g_idletcb[i]; hashndx = PIDHASH(i); - nxsched_pidhash()[hashndx] = &tcb->cmn; + nxsched_pidhash()[hashndx] = tcb; /* Allocate the IDLE group */ - DEBUGVERIFY(group_initialize(tcb, tcb->cmn.flags)); - tcb->cmn.group->tg_info->ta_argv = &g_idleargv[i][0]; + DEBUGVERIFY( + group_initialize((FAR struct task_tcb_s *)tcb, tcb->flags)); + tcb->group->tg_info->ta_argv = &g_idleargv[i][0]; /* Initialize the task join */ - nxtask_joininit(&tcb->cmn); + nxtask_joininit(tcb); #ifdef CONFIG_SMP /* Create a stack for all CPU IDLE threads (except CPU0 which already @@ -488,26 +489,24 @@ static void idle_group_initialize(void) if (i > 0) { - DEBUGVERIFY(up_cpu_idlestack(i, &tcb->cmn, - CONFIG_IDLETHREAD_STACKSIZE)); + DEBUGVERIFY(up_cpu_idlestack(i, tcb, CONFIG_IDLETHREAD_STACKSIZE)); } #endif /* Initialize the processor-specific portion of the TCB */ - up_initial_state(&tcb->cmn); + up_initial_state(tcb); /* Initialize the thread local storage */ - tls_init_info(&tcb->cmn); + tls_init_info(tcb); /* Complete initialization of the IDLE group. Suppress retention * of child status in the IDLE group. */ - group_postinitialize(tcb); - tcb->cmn.group->tg_flags = GROUP_FLAG_NOCLDWAIT | - GROUP_FLAG_PRIVILEGED; + group_postinitialize((FAR struct task_tcb_s *)tcb); + tcb->group->tg_flags = GROUP_FLAG_NOCLDWAIT | GROUP_FLAG_PRIVILEGED; } } @@ -727,7 +726,7 @@ void nx_start(void) /* Announce that the CPU0 IDLE task has started */ - sched_note_start(&g_idletcb[0].cmn); + sched_note_start(&g_idletcb[0]); /* Initialize stdio for the IDLE task of each CPU */ @@ -737,7 +736,8 @@ void nx_start(void) { /* Clone stdout, stderr, stdin from the CPU0 IDLE task. */ - DEBUGVERIFY(group_setuptaskfiles(&g_idletcb[i], NULL, true)); + DEBUGVERIFY(group_setuptaskfiles( + (FAR struct task_tcb_s *)&g_idletcb[i], NULL, true)); } else { diff --git a/sched/task/task_create.c b/sched/task/task_create.c index f934078a374c9..f7b7073495102 100644 --- a/sched/task/task_create.c +++ b/sched/task/task_create.c @@ -76,13 +76,14 @@ int nxthread_create(FAR const char *name, uint8_t ttype, int priority, FAR void *stack_addr, int stack_size, main_t entry, FAR char * const argv[], FAR char * const envp[]) { - 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(ttype == TCB_FLAG_TTYPE_KERNEL ? sizeof(struct tcb_s) : + sizeof(struct task_tcb_s)); if (!tcb) { serr("ERROR: Failed to allocate TCB\n"); @@ -91,12 +92,12 @@ int nxthread_create(FAR const char *name, uint8_t ttype, int priority, /* Setup the task type */ - tcb->cmn.flags = ttype | TCB_FLAG_FREE_TCB; + tcb->flags = ttype | TCB_FLAG_FREE_TCB; /* Initialize the task */ - ret = nxtask_init(tcb, name, priority, stack_addr, stack_size, - entry, argv, envp, NULL); + ret = nxtask_init((FAR struct task_tcb_s *)tcb, name, priority, + stack_addr, stack_size, entry, argv, envp, NULL); if (ret < OK) { kmm_free(tcb); @@ -105,11 +106,11 @@ int nxthread_create(FAR const char *name, uint8_t ttype, int priority, /* Get the assigned pid before we start the task */ - pid = tcb->cmn.pid; + pid = tcb->pid; /* Activate the task */ - nxtask_activate(&tcb->cmn); + nxtask_activate(tcb); return pid; } diff --git a/sched/task/task_setup.c b/sched/task/task_setup.c index 61a8b615643b1..5255f216c9fb8 100644 --- a/sched/task/task_setup.c +++ b/sched/task/task_setup.c @@ -514,6 +514,7 @@ static void nxtask_setup_name(FAR struct task_tcb_s *tcb, * * Input Parameters: * tcb - Address of the new task's TCB + * name - Name of the new task * argv - A pointer to an array of input parameters. The array should be * terminated with a NULL argv[] value. If no parameters are * required, argv may be NULL. @@ -527,6 +528,7 @@ static int nxtask_setup_stackargs(FAR struct task_tcb_s *tcb, FAR const char *name, FAR char * const argv[]) { + const uint8_t ttype = tcb->cmn.flags & TCB_FLAG_TTYPE_MASK; FAR char **stackargv; FAR char *str; size_t strtablen; @@ -630,8 +632,11 @@ static int nxtask_setup_stackargs(FAR struct task_tcb_s *tcb, stackargv[argc + 1] = NULL; - tcb->cmn.group->tg_info->ta_argc = argc; - tcb->cmn.group->tg_info->ta_argv = stackargv; + if (ttype != TCB_FLAG_TTYPE_KERNEL) + { + tcb->cmn.group->tg_info->ta_argc = argc; + tcb->cmn.group->tg_info->ta_argv = stackargv; + } return OK; } diff --git a/sched/task/task_start.c b/sched/task/task_start.c index 8d6bf9e909a91..a3d6e2e66fa75 100644 --- a/sched/task/task_start.c +++ b/sched/task/task_start.c @@ -66,17 +66,18 @@ void nxtask_start(void) { FAR struct tcb_s *tcb = this_task(); + uint8_t ttype = tcb->flags & TCB_FLAG_TTYPE_MASK; #ifdef CONFIG_SCHED_STARTHOOK FAR struct task_tcb_s *ttcb = (FAR struct task_tcb_s *)tcb; #endif int exitcode = EXIT_FAILURE; + FAR char **argv; int argc; - DEBUGASSERT((tcb->flags & TCB_FLAG_TTYPE_MASK) != \ - TCB_FLAG_TTYPE_PTHREAD); + DEBUGASSERT(ttype != TCB_FLAG_TTYPE_PTHREAD); #ifdef CONFIG_SIG_DEFAULT - if ((tcb->flags & TCB_FLAG_TTYPE_MASK) != TCB_FLAG_TTYPE_KERNEL) + if (ttype != TCB_FLAG_TTYPE_KERNEL) { /* Set up default signal actions for NON-kernel thread */ @@ -87,33 +88,32 @@ void nxtask_start(void) /* Execute the start hook if one has been registered */ #ifdef CONFIG_SCHED_STARTHOOK - if (ttcb->starthook != NULL) + if (ttype != TCB_FLAG_TTYPE_KERNEL && ttcb->starthook != NULL) { ttcb->starthook(ttcb->starthookarg); } #endif - /* Add program name */ + /* Take args from stack, as group is shared for kthreads */ - argc = tcb->group->tg_info->ta_argc + 1; + argv = nxsched_get_stackargs(tcb); + for (argc = 0; argv && argv[argc]; argc++); /* Call the 'main' entry point passing argc and argv. In the kernel build * this has to be handled differently if we are starting a user-space task; * we have to switch to user-mode before calling the task. */ - if ((tcb->flags & TCB_FLAG_TTYPE_MASK) == TCB_FLAG_TTYPE_KERNEL) + if (ttype == TCB_FLAG_TTYPE_KERNEL) { - exitcode = tcb->entry.main(argc, tcb->group->tg_info->ta_argv); + exitcode = tcb->entry.main(argc, argv); } else { #ifdef CONFIG_BUILD_FLAT - nxtask_startup(tcb->entry.main, argc, - tcb->group->tg_info->ta_argv); + nxtask_startup(tcb->entry.main, argc, argv); #else - up_task_start(tcb->entry.main, argc, - tcb->group->tg_info->ta_argv); + up_task_start(tcb->entry.main, argc, argv); #endif }