sched/tcb: use shared group for kthreads
Kthreads can share the group data so that to reduce overheads. This implements shared kthread group via: - use `tcb_s` instead of `task_tcb_s` for kthreads - use `g_kthread_group` when creating kthreads - use stackargs to start tasks and kthreads see pull/12320 for test logs. Signed-off-by: Yanfeng Liu <yfliu2008@qq.com>
This commit is contained in:
parent
1d169fe325
commit
8a8c1f943e
7 changed files with 90 additions and 61 deletions
|
@ -72,7 +72,7 @@ int env_dup(FAR struct task_group_s *group, FAR char * const *envcp)
|
||||||
|
|
||||||
/* Is there an environment ? */
|
/* Is there an environment ? */
|
||||||
|
|
||||||
if (envcp != NULL)
|
if (envcp != NULL && group->tg_envp == NULL)
|
||||||
{
|
{
|
||||||
/* Pre-emption must be disabled throughout the following because the
|
/* Pre-emption must be disabled throughout the following because the
|
||||||
* environment may be shared.
|
* environment may be shared.
|
||||||
|
|
|
@ -40,9 +40,11 @@
|
||||||
#include "tls/tls.h"
|
#include "tls/tls.h"
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Data
|
* Private Data
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
static struct task_group_s g_kthread_group; /* Shared among kthreads */
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Functions
|
* Private Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
@ -119,9 +121,23 @@ int group_initialize(FAR struct task_tcb_s *tcb, uint8_t ttype)
|
||||||
|
|
||||||
DEBUGASSERT(tcb && !tcb->cmn.group);
|
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 */
|
||||||
|
|
||||||
|
if (ttype == TCB_FLAG_TTYPE_KERNEL)
|
||||||
|
{
|
||||||
|
group = &g_kthread_group;
|
||||||
|
tcb->cmn.group = group;
|
||||||
|
if (group->tg_info)
|
||||||
|
{
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
group = &tcb->group;
|
group = &tcb->group;
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(CONFIG_MM_KERNEL_HEAP)
|
#if defined(CONFIG_MM_KERNEL_HEAP)
|
||||||
/* If this group is being created for a privileged thread, then all
|
/* If this group is being created for a privileged thread, then all
|
||||||
|
@ -222,5 +238,8 @@ void group_postinitialize(FAR struct task_tcb_s *tcb)
|
||||||
* task has exited.
|
* task has exited.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
if (group != &g_kthread_group)
|
||||||
|
{
|
||||||
group->tg_pid = tcb->cmn.pid;
|
group->tg_pid = tcb->cmn.pid;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,8 +79,12 @@ int group_setuptaskfiles(FAR struct task_tcb_s *tcb,
|
||||||
|
|
||||||
/* Duplicate the parent task's file descriptors */
|
/* Duplicate the parent task's file descriptors */
|
||||||
|
|
||||||
ret = files_duplist(&rtcb->group->tg_filelist,
|
if (group != rtcb->group)
|
||||||
|
{
|
||||||
|
files_duplist(&rtcb->group->tg_filelist,
|
||||||
&group->tg_filelist, actions, cloexec);
|
&group->tg_filelist, actions, cloexec);
|
||||||
|
}
|
||||||
|
|
||||||
if (ret >= 0 && actions != NULL)
|
if (ret >= 0 && actions != NULL)
|
||||||
{
|
{
|
||||||
ret = spawn_file_actions(&tcb->cmn, actions);
|
ret = spawn_file_actions(&tcb->cmn, actions);
|
||||||
|
|
|
@ -206,7 +206,7 @@ uint8_t g_nx_initstate; /* See enum nx_initstate_e */
|
||||||
* bringing up the rest of the system.
|
* 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 */
|
/* This is the name of the idle task */
|
||||||
|
|
||||||
|
@ -351,10 +351,11 @@ static void tasklist_initialize(void)
|
||||||
|
|
||||||
static void idle_task_initialize(void)
|
static void idle_task_initialize(void)
|
||||||
{
|
{
|
||||||
FAR struct task_tcb_s *tcb;
|
FAR struct tcb_s *tcb;
|
||||||
FAR dq_queue_t *tasklist;
|
FAR dq_queue_t *tasklist;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
memset(g_idletcb, 0, sizeof(g_idletcb));
|
||||||
for (i = 0; i < CONFIG_SMP_NCPUS; i++)
|
for (i = 0; i < CONFIG_SMP_NCPUS; i++)
|
||||||
{
|
{
|
||||||
tcb = &g_idletcb[i];
|
tcb = &g_idletcb[i];
|
||||||
|
@ -366,9 +367,8 @@ static void idle_task_initialize(void)
|
||||||
* that has pid == 0 and sched_priority == 0.
|
* that has pid == 0 and sched_priority == 0.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
memset(tcb, 0, sizeof(struct task_tcb_s));
|
tcb->pid = i;
|
||||||
tcb->cmn.pid = i;
|
tcb->task_state = TSTATE_TASK_RUNNING;
|
||||||
tcb->cmn.task_state = TSTATE_TASK_RUNNING;
|
|
||||||
|
|
||||||
/* Set the entry point. This is only for debug purposes. NOTE: that
|
/* Set the entry point. This is only for debug purposes. NOTE: that
|
||||||
* the start_t entry point is not saved. That is acceptable, however,
|
* the start_t entry point is not saved. That is acceptable, however,
|
||||||
|
@ -379,14 +379,14 @@ static void idle_task_initialize(void)
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
if (i > 0)
|
if (i > 0)
|
||||||
{
|
{
|
||||||
tcb->cmn.start = nx_idle_trampoline;
|
tcb->start = nx_idle_trampoline;
|
||||||
tcb->cmn.entry.main = (main_t)nx_idle_trampoline;
|
tcb->entry.main = (main_t)nx_idle_trampoline;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
tcb->cmn.start = nx_start;
|
tcb->start = nx_start;
|
||||||
tcb->cmn.entry.main = (main_t)nx_start;
|
tcb->entry.main = (main_t)nx_start;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the task flags to indicate that this is a kernel thread and, if
|
/* Set the task flags to indicate that this is a kernel thread and, if
|
||||||
|
@ -394,8 +394,8 @@ static void idle_task_initialize(void)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
tcb->cmn.flags = (TCB_FLAG_TTYPE_KERNEL | TCB_FLAG_CPU_LOCKED);
|
tcb->flags = (TCB_FLAG_TTYPE_KERNEL | TCB_FLAG_CPU_LOCKED);
|
||||||
tcb->cmn.cpu = i;
|
tcb->cpu = i;
|
||||||
|
|
||||||
/* Set the affinity mask to allow the thread to run on all CPUs. No,
|
/* 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
|
* this IDLE thread can only run on its assigned CPU. That is
|
||||||
|
@ -405,19 +405,19 @@ static void idle_task_initialize(void)
|
||||||
* the IDLE task.
|
* the IDLE task.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
tcb->cmn.affinity =
|
tcb->affinity =
|
||||||
(cpu_set_t)(CONFIG_SMP_DEFAULT_CPUSET & SCHED_ALL_CPUS);
|
(cpu_set_t)(CONFIG_SMP_DEFAULT_CPUSET & SCHED_ALL_CPUS);
|
||||||
#else
|
#else
|
||||||
tcb->cmn.flags = TCB_FLAG_TTYPE_KERNEL;
|
tcb->flags = TCB_FLAG_TTYPE_KERNEL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CONFIG_TASK_NAME_SIZE > 0
|
#if CONFIG_TASK_NAME_SIZE > 0
|
||||||
/* Set the IDLE task name */
|
/* Set the IDLE task name */
|
||||||
|
|
||||||
# ifdef CONFIG_SMP
|
# 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
|
# else
|
||||||
strlcpy(tcb->cmn.name, g_idlename, CONFIG_TASK_NAME_SIZE);
|
strlcpy(tcb->name, g_idlename, CONFIG_TASK_NAME_SIZE);
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
/* Configure the task name in the argument list. The IDLE task does
|
/* Configure the task name in the argument list. The IDLE task does
|
||||||
|
@ -428,7 +428,7 @@ static void idle_task_initialize(void)
|
||||||
* stack and there is no support that yet.
|
* stack and there is no support that yet.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
g_idleargv[i][0] = tcb->cmn.name;
|
g_idleargv[i][0] = tcb->name;
|
||||||
#else
|
#else
|
||||||
g_idleargv[i][0] = (FAR char *)g_idlename;
|
g_idleargv[i][0] = (FAR char *)g_idlename;
|
||||||
#endif /* CONFIG_TASK_NAME_SIZE */
|
#endif /* CONFIG_TASK_NAME_SIZE */
|
||||||
|
@ -438,15 +438,15 @@ static void idle_task_initialize(void)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
tasklist = TLIST_HEAD(&tcb->cmn, i);
|
tasklist = TLIST_HEAD(tcb, i);
|
||||||
#else
|
#else
|
||||||
tasklist = TLIST_HEAD(&tcb->cmn);
|
tasklist = TLIST_HEAD(tcb);
|
||||||
#endif
|
#endif
|
||||||
dq_addfirst((FAR dq_entry_t *)tcb, tasklist);
|
dq_addfirst((FAR dq_entry_t *)tcb, tasklist);
|
||||||
|
|
||||||
/* Mark the idle task as the running task */
|
/* Mark the idle task as the running task */
|
||||||
|
|
||||||
g_running_tasks[i] = &tcb->cmn;
|
g_running_tasks[i] = tcb;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -460,7 +460,7 @@ static void idle_task_initialize(void)
|
||||||
|
|
||||||
static void idle_group_initialize(void)
|
static void idle_group_initialize(void)
|
||||||
{
|
{
|
||||||
FAR struct task_tcb_s *tcb;
|
FAR struct tcb_s *tcb;
|
||||||
int hashndx;
|
int hashndx;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -471,16 +471,17 @@ static void idle_group_initialize(void)
|
||||||
tcb = &g_idletcb[i];
|
tcb = &g_idletcb[i];
|
||||||
|
|
||||||
hashndx = PIDHASH(i);
|
hashndx = PIDHASH(i);
|
||||||
g_pidhash[hashndx] = &tcb->cmn;
|
g_pidhash[hashndx] = tcb;
|
||||||
|
|
||||||
/* Allocate the IDLE group */
|
/* Allocate the IDLE group */
|
||||||
|
|
||||||
DEBUGVERIFY(group_initialize(tcb, tcb->cmn.flags));
|
DEBUGVERIFY(
|
||||||
tcb->cmn.group->tg_info->ta_argv = &g_idleargv[i][0];
|
group_initialize((FAR struct task_tcb_s *)tcb, tcb->flags));
|
||||||
|
tcb->group->tg_info->ta_argv = &g_idleargv[i][0];
|
||||||
|
|
||||||
/* Initialize the task join */
|
/* Initialize the task join */
|
||||||
|
|
||||||
nxtask_joininit(&tcb->cmn);
|
nxtask_joininit(tcb);
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
/* Create a stack for all CPU IDLE threads (except CPU0 which already
|
/* Create a stack for all CPU IDLE threads (except CPU0 which already
|
||||||
|
@ -489,26 +490,24 @@ static void idle_group_initialize(void)
|
||||||
|
|
||||||
if (i > 0)
|
if (i > 0)
|
||||||
{
|
{
|
||||||
DEBUGVERIFY(up_cpu_idlestack(i, &tcb->cmn,
|
DEBUGVERIFY(up_cpu_idlestack(i, tcb, CONFIG_IDLETHREAD_STACKSIZE));
|
||||||
CONFIG_IDLETHREAD_STACKSIZE));
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Initialize the processor-specific portion of the TCB */
|
/* Initialize the processor-specific portion of the TCB */
|
||||||
|
|
||||||
up_initial_state(&tcb->cmn);
|
up_initial_state(tcb);
|
||||||
|
|
||||||
/* Initialize the thread local storage */
|
/* Initialize the thread local storage */
|
||||||
|
|
||||||
tls_init_info(&tcb->cmn);
|
tls_init_info(tcb);
|
||||||
|
|
||||||
/* Complete initialization of the IDLE group. Suppress retention
|
/* Complete initialization of the IDLE group. Suppress retention
|
||||||
* of child status in the IDLE group.
|
* of child status in the IDLE group.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
group_postinitialize(tcb);
|
group_postinitialize((FAR struct task_tcb_s *)tcb);
|
||||||
tcb->cmn.group->tg_flags = GROUP_FLAG_NOCLDWAIT |
|
tcb->group->tg_flags = GROUP_FLAG_NOCLDWAIT | GROUP_FLAG_PRIVILEGED;
|
||||||
GROUP_FLAG_PRIVILEGED;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -727,7 +726,7 @@ void nx_start(void)
|
||||||
|
|
||||||
/* Announce that the CPU0 IDLE task has started */
|
/* 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 */
|
/* 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. */
|
/* 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
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -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 void *stack_addr, int stack_size, main_t entry,
|
||||||
FAR char * const argv[], FAR char * const envp[])
|
FAR char * const argv[], FAR char * const envp[])
|
||||||
{
|
{
|
||||||
FAR struct task_tcb_s *tcb;
|
FAR struct tcb_s *tcb;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* Allocate a TCB for the new task. */
|
/* 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)
|
if (!tcb)
|
||||||
{
|
{
|
||||||
serr("ERROR: Failed to allocate TCB\n");
|
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 */
|
/* Setup the task type */
|
||||||
|
|
||||||
tcb->cmn.flags = ttype | TCB_FLAG_FREE_TCB;
|
tcb->flags = ttype | TCB_FLAG_FREE_TCB;
|
||||||
|
|
||||||
/* Initialize the task */
|
/* Initialize the task */
|
||||||
|
|
||||||
ret = nxtask_init(tcb, name, priority, stack_addr, stack_size,
|
ret = nxtask_init((FAR struct task_tcb_s *)tcb, name, priority,
|
||||||
entry, argv, envp, NULL);
|
stack_addr, stack_size, entry, argv, envp, NULL);
|
||||||
if (ret < OK)
|
if (ret < OK)
|
||||||
{
|
{
|
||||||
kmm_free(tcb);
|
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 */
|
/* Get the assigned pid before we start the task */
|
||||||
|
|
||||||
pid = tcb->cmn.pid;
|
pid = tcb->pid;
|
||||||
|
|
||||||
/* Activate the task */
|
/* Activate the task */
|
||||||
|
|
||||||
nxtask_activate(&tcb->cmn);
|
nxtask_activate(tcb);
|
||||||
|
|
||||||
return pid;
|
return pid;
|
||||||
}
|
}
|
||||||
|
|
|
@ -514,6 +514,7 @@ static void nxtask_setup_name(FAR struct task_tcb_s *tcb,
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* tcb - Address of the new task's TCB
|
* 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
|
* argv - A pointer to an array of input parameters. The array should be
|
||||||
* terminated with a NULL argv[] value. If no parameters are
|
* terminated with a NULL argv[] value. If no parameters are
|
||||||
* required, argv may be NULL.
|
* 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 const char *name,
|
||||||
FAR char * const argv[])
|
FAR char * const argv[])
|
||||||
{
|
{
|
||||||
|
uint8_t ttype = tcb->cmn.flags & TCB_FLAG_TTYPE_MASK;
|
||||||
FAR char **stackargv;
|
FAR char **stackargv;
|
||||||
FAR char *str;
|
FAR char *str;
|
||||||
size_t strtablen;
|
size_t strtablen;
|
||||||
|
@ -630,8 +632,11 @@ static int nxtask_setup_stackargs(FAR struct task_tcb_s *tcb,
|
||||||
|
|
||||||
stackargv[argc + 1] = NULL;
|
stackargv[argc + 1] = NULL;
|
||||||
|
|
||||||
|
if (ttype != TCB_FLAG_TTYPE_KERNEL)
|
||||||
|
{
|
||||||
tcb->cmn.group->tg_info->ta_argc = argc;
|
tcb->cmn.group->tg_info->ta_argc = argc;
|
||||||
tcb->cmn.group->tg_info->ta_argv = stackargv;
|
tcb->cmn.group->tg_info->ta_argv = stackargv;
|
||||||
|
}
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,17 +66,18 @@
|
||||||
void nxtask_start(void)
|
void nxtask_start(void)
|
||||||
{
|
{
|
||||||
FAR struct tcb_s *tcb = this_task();
|
FAR struct tcb_s *tcb = this_task();
|
||||||
|
uint8_t ttype = tcb->flags & TCB_FLAG_TTYPE_MASK;
|
||||||
#ifdef CONFIG_SCHED_STARTHOOK
|
#ifdef CONFIG_SCHED_STARTHOOK
|
||||||
FAR struct task_tcb_s *ttcb = (FAR struct task_tcb_s *)tcb;
|
FAR struct task_tcb_s *ttcb = (FAR struct task_tcb_s *)tcb;
|
||||||
#endif
|
#endif
|
||||||
int exitcode = EXIT_FAILURE;
|
int exitcode = EXIT_FAILURE;
|
||||||
|
FAR char **argv;
|
||||||
int argc;
|
int argc;
|
||||||
|
|
||||||
DEBUGASSERT((tcb->flags & TCB_FLAG_TTYPE_MASK) != \
|
DEBUGASSERT(ttype != TCB_FLAG_TTYPE_PTHREAD);
|
||||||
TCB_FLAG_TTYPE_PTHREAD);
|
|
||||||
|
|
||||||
#ifdef CONFIG_SIG_DEFAULT
|
#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 */
|
/* 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 */
|
/* Execute the start hook if one has been registered */
|
||||||
|
|
||||||
#ifdef CONFIG_SCHED_STARTHOOK
|
#ifdef CONFIG_SCHED_STARTHOOK
|
||||||
if (ttcb->starthook != NULL)
|
if (ttype != TCB_FLAG_TTYPE_KERNEL && ttcb->starthook != NULL)
|
||||||
{
|
{
|
||||||
ttcb->starthook(ttcb->starthookarg);
|
ttcb->starthook(ttcb->starthookarg);
|
||||||
}
|
}
|
||||||
#endif
|
#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
|
/* 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;
|
* 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.
|
* 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
|
else
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_BUILD_FLAT
|
#ifdef CONFIG_BUILD_FLAT
|
||||||
nxtask_startup(tcb->entry.main, argc,
|
nxtask_startup(tcb->entry.main, argc, argv);
|
||||||
tcb->group->tg_info->ta_argv);
|
|
||||||
#else
|
#else
|
||||||
up_task_start(tcb->entry.main, argc,
|
up_task_start(tcb->entry.main, argc, argv);
|
||||||
tcb->group->tg_info->ta_argv);
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue