sched/init: move idle task initialize to inline function
N/A, help to extend the multi-core implementation Signed-off-by: chao an <anchao@lixiang.com>
This commit is contained in:
parent
738bdb95b7
commit
7cc89bbd0e
|
@ -294,6 +294,181 @@ static const char g_idlename[] = "Idle_Task";
|
|||
|
||||
static FAR char *g_idleargv[CONFIG_SMP_NCPUS][2];
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: idle_task_initialize
|
||||
*
|
||||
* Description:
|
||||
* IDLE Task Initialization
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void idle_task_initialize(void)
|
||||
{
|
||||
FAR struct task_tcb_s *tcb;
|
||||
FAR dq_queue_t *tasklist;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < CONFIG_SMP_NCPUS; i++)
|
||||
{
|
||||
tcb = &g_idletcb[i];
|
||||
|
||||
/* Initialize a TCB for this thread of execution. NOTE: The default
|
||||
* value for most components of the g_idletcb are zero. The entire
|
||||
* structure is set to zero. Then only the (potentially) non-zero
|
||||
* elements are initialized. NOTE: The idle task is the only task in
|
||||
* 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;
|
||||
|
||||
/* Set the entry point. This is only for debug purposes. NOTE: that
|
||||
* the start_t entry point is not saved. That is acceptable, however,
|
||||
* because it can be used only for restarting a task: The IDLE task
|
||||
* cannot be restarted.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
if (i > 0)
|
||||
{
|
||||
tcb->cmn.start = nx_idle_trampoline;
|
||||
tcb->cmn.entry.main = (main_t)nx_idle_trampoline;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
tcb->cmn.start = nx_start;
|
||||
tcb->cmn.entry.main = (main_t)nx_start;
|
||||
}
|
||||
|
||||
/* Set the task flags to indicate that this is a kernel thread and, if
|
||||
* configured for SMP, that this task is locked to this CPU.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
tcb->cmn.flags = (TCB_FLAG_TTYPE_KERNEL | TCB_FLAG_CPU_LOCKED);
|
||||
tcb->cmn.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
|
||||
* enforced by the TCB_FLAG_CPU_LOCKED which overrides the affinity
|
||||
* mask. This is essential because all tasks inherit the affinity
|
||||
* mask from their parent and, ultimately, the parent of all tasks is
|
||||
* the IDLE task.
|
||||
*/
|
||||
|
||||
tcb->cmn.affinity =
|
||||
(cpu_set_t)(CONFIG_SMP_DEFAULT_CPUSET & SCHED_ALL_CPUS);
|
||||
#else
|
||||
tcb->cmn.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);
|
||||
# else
|
||||
strlcpy(tcb->cmn.name, g_idlename, CONFIG_TASK_NAME_SIZE);
|
||||
# endif
|
||||
|
||||
/* Configure the task name in the argument list. The IDLE task does
|
||||
* not really have an argument list, but this name is still useful
|
||||
* for things like the NSH PS command.
|
||||
*
|
||||
* In the kernel mode build, the arguments are saved on the task's
|
||||
* stack and there is no support that yet.
|
||||
*/
|
||||
|
||||
g_idleargv[i][0] = tcb->cmn.name;
|
||||
#else
|
||||
g_idleargv[i][0] = (FAR char *)g_idlename;
|
||||
#endif /* CONFIG_TASK_NAME_SIZE */
|
||||
|
||||
/* Then add the idle task's TCB to the head of the current ready to
|
||||
* run list.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
tasklist = TLIST_HEAD(&tcb->cmn, i);
|
||||
#else
|
||||
tasklist = TLIST_HEAD(&tcb->cmn);
|
||||
#endif
|
||||
dq_addfirst((FAR dq_entry_t *)tcb, tasklist);
|
||||
|
||||
/* Mark the idle task as the running task */
|
||||
|
||||
g_running_tasks[i] = &tcb->cmn;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: idle_group_initialize
|
||||
*
|
||||
* Description:
|
||||
* IDLE Group Initialization
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void idle_group_initialize(void)
|
||||
{
|
||||
FAR struct task_tcb_s *tcb;
|
||||
int hashndx;
|
||||
int i;
|
||||
|
||||
/* Assign the process ID(s) of ZERO to the idle task(s) */
|
||||
|
||||
for (i = 0; i < CONFIG_SMP_NCPUS; i++)
|
||||
{
|
||||
tcb = &g_idletcb[i];
|
||||
|
||||
hashndx = PIDHASH(i);
|
||||
nxsched_pidhash()[hashndx] = &tcb->cmn;
|
||||
|
||||
/* Allocate the IDLE group */
|
||||
|
||||
DEBUGVERIFY(group_initialize(tcb, tcb->cmn.flags));
|
||||
tcb->cmn.group->tg_info->ta_argv = &g_idleargv[i][0];
|
||||
|
||||
/* Initialize the task join */
|
||||
|
||||
nxtask_joininit(&tcb->cmn);
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
/* Create a stack for all CPU IDLE threads (except CPU0 which already
|
||||
* has a stack).
|
||||
*/
|
||||
|
||||
if (i > 0)
|
||||
{
|
||||
DEBUGVERIFY(up_cpu_idlestack(i, &tcb->cmn,
|
||||
CONFIG_IDLETHREAD_STACKSIZE));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Initialize the processor-specific portion of the TCB */
|
||||
|
||||
up_initial_state(&tcb->cmn);
|
||||
|
||||
/* Initialize the thread local storage */
|
||||
|
||||
tls_init_info(&tcb->cmn);
|
||||
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
@ -330,100 +505,7 @@ void nx_start(void)
|
|||
|
||||
/* Initialize the IDLE task TCB *******************************************/
|
||||
|
||||
for (i = 0; i < CONFIG_SMP_NCPUS; i++)
|
||||
{
|
||||
FAR dq_queue_t *tasklist;
|
||||
|
||||
/* Initialize a TCB for this thread of execution. NOTE: The default
|
||||
* value for most components of the g_idletcb are zero. The entire
|
||||
* structure is set to zero. Then only the (potentially) non-zero
|
||||
* elements are initialized. NOTE: The idle task is the only task in
|
||||
* that has pid == 0 and sched_priority == 0.
|
||||
*/
|
||||
|
||||
memset((void *)&g_idletcb[i], 0, sizeof(struct task_tcb_s));
|
||||
g_idletcb[i].cmn.pid = i;
|
||||
g_idletcb[i].cmn.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,
|
||||
* because it can be used only for restarting a task: The IDLE task
|
||||
* cannot be restarted.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
if (i > 0)
|
||||
{
|
||||
g_idletcb[i].cmn.start = nx_idle_trampoline;
|
||||
g_idletcb[i].cmn.entry.main = (main_t)nx_idle_trampoline;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
g_idletcb[i].cmn.start = nx_start;
|
||||
g_idletcb[i].cmn.entry.main = (main_t)nx_start;
|
||||
}
|
||||
|
||||
/* Set the task flags to indicate that this is a kernel thread and, if
|
||||
* configured for SMP, that this task is locked to this CPU.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
g_idletcb[i].cmn.flags = (TCB_FLAG_TTYPE_KERNEL | TCB_FLAG_CPU_LOCKED);
|
||||
g_idletcb[i].cmn.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
|
||||
* enforced by the TCB_FLAG_CPU_LOCKED which overrides the affinity
|
||||
* mask. This is essential because all tasks inherit the affinity
|
||||
* mask from their parent and, ultimately, the parent of all tasks is
|
||||
* the IDLE task.
|
||||
*/
|
||||
|
||||
g_idletcb[i].cmn.affinity =
|
||||
(cpu_set_t)(CONFIG_SMP_DEFAULT_CPUSET & SCHED_ALL_CPUS);
|
||||
#else
|
||||
g_idletcb[i].cmn.flags = TCB_FLAG_TTYPE_KERNEL;
|
||||
#endif
|
||||
|
||||
#if CONFIG_TASK_NAME_SIZE > 0
|
||||
/* Set the IDLE task name */
|
||||
|
||||
# ifdef CONFIG_SMP
|
||||
snprintf(g_idletcb[i].cmn.name, CONFIG_TASK_NAME_SIZE, "CPU%d IDLE",
|
||||
i);
|
||||
# else
|
||||
strlcpy(g_idletcb[i].cmn.name, g_idlename, CONFIG_TASK_NAME_SIZE);
|
||||
# endif
|
||||
|
||||
/* Configure the task name in the argument list. The IDLE task does
|
||||
* not really have an argument list, but this name is still useful
|
||||
* for things like the NSH PS command.
|
||||
*
|
||||
* In the kernel mode build, the arguments are saved on the task's
|
||||
* stack and there is no support that yet.
|
||||
*/
|
||||
|
||||
g_idleargv[i][0] = g_idletcb[i].cmn.name;
|
||||
#else
|
||||
g_idleargv[i][0] = (FAR char *)g_idlename;
|
||||
#endif /* CONFIG_TASK_NAME_SIZE */
|
||||
|
||||
/* Then add the idle task's TCB to the head of the current ready to
|
||||
* run list.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
tasklist = TLIST_HEAD(&g_idletcb[i].cmn, i);
|
||||
#else
|
||||
tasklist = TLIST_HEAD(&g_idletcb[i].cmn);
|
||||
#endif
|
||||
dq_addfirst((FAR dq_entry_t *)&g_idletcb[i], tasklist);
|
||||
|
||||
/* Mark the idle task as the running task */
|
||||
|
||||
g_running_tasks[i] = &g_idletcb[i].cmn;
|
||||
}
|
||||
idle_task_initialize();
|
||||
|
||||
/* Task lists are initialized */
|
||||
|
||||
|
@ -507,52 +589,7 @@ void nx_start(void)
|
|||
|
||||
/* IDLE Group Initialization **********************************************/
|
||||
|
||||
for (i = 0; i < CONFIG_SMP_NCPUS; i++)
|
||||
{
|
||||
int hashndx;
|
||||
|
||||
/* Assign the process ID(s) of ZERO to the idle task(s) */
|
||||
|
||||
hashndx = PIDHASH(i);
|
||||
nxsched_pidhash()[hashndx] = &g_idletcb[i].cmn;
|
||||
|
||||
/* Allocate the IDLE group */
|
||||
|
||||
DEBUGVERIFY(group_initialize(&g_idletcb[i], g_idletcb[i].cmn.flags));
|
||||
g_idletcb[i].cmn.group->tg_info->ta_argv = &g_idleargv[i][0];
|
||||
|
||||
/* Initialize the task join */
|
||||
|
||||
nxtask_joininit(&g_idletcb[i].cmn);
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
/* Create a stack for all CPU IDLE threads (except CPU0 which already
|
||||
* has a stack).
|
||||
*/
|
||||
|
||||
if (i > 0)
|
||||
{
|
||||
DEBUGVERIFY(up_cpu_idlestack(i, &g_idletcb[i].cmn,
|
||||
CONFIG_IDLETHREAD_STACKSIZE));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Initialize the processor-specific portion of the TCB */
|
||||
|
||||
up_initial_state(&g_idletcb[i].cmn);
|
||||
|
||||
/* Initialize the thread local storage */
|
||||
|
||||
tls_init_info(&g_idletcb[i].cmn);
|
||||
|
||||
/* Complete initialization of the IDLE group. Suppress retention
|
||||
* of child status in the IDLE group.
|
||||
*/
|
||||
|
||||
group_postinitialize(&g_idletcb[i]);
|
||||
g_idletcb[i].cmn.group->tg_flags = GROUP_FLAG_NOCLDWAIT |
|
||||
GROUP_FLAG_PRIVILEGED;
|
||||
}
|
||||
idle_group_initialize();
|
||||
|
||||
nxsched_lastpid() = CONFIG_SMP_NCPUS - 1;
|
||||
|
||||
|
|
Loading…
Reference in New Issue