nx_start: Simplify and unify the partial initialization process

for both SMP and non-SMP

Change-Id: I0fea8b4f59fc27d253a2ef9b7503acbb7410cc14
Signed-off-by: Jiuzhu Dong <dongjiuzhu1@xiaomi.com>
This commit is contained in:
Jiuzhu Dong 2021-07-10 09:01:20 +08:00 committed by Xiang Xiao
parent 85470176e7
commit bb867a38fc

View File

@ -63,6 +63,10 @@
* Pre-processor Definitions * Pre-processor Definitions
****************************************************************************/ ****************************************************************************/
#ifndef CONFIG_SMP_NCPUS
# define CONFIG_SMP_NCPUS 1
#endif
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
/* This set of all CPUs */ /* This set of all CPUs */
@ -92,7 +96,6 @@
volatile dq_queue_t g_readytorun; volatile dq_queue_t g_readytorun;
#ifdef CONFIG_SMP
/* In order to support SMP, the function of the g_readytorun list changes, /* In order to support SMP, the function of the g_readytorun list changes,
* The g_readytorun is still used but in the SMP case it will contain only: * The g_readytorun is still used but in the SMP case it will contain only:
* *
@ -123,7 +126,9 @@ volatile dq_queue_t g_readytorun;
* always the CPU's IDLE task. * always the CPU's IDLE task.
*/ */
#ifdef CONFIG_SMP
volatile dq_queue_t g_assignedtasks[CONFIG_SMP_NCPUS]; volatile dq_queue_t g_assignedtasks[CONFIG_SMP_NCPUS];
#endif
/* g_running_tasks[] holds a references to the running task for each cpu. /* g_running_tasks[] holds a references to the running task for each cpu.
* It is valid only when up_interrupt_context() returns true. * It is valid only when up_interrupt_context() returns true.
@ -131,12 +136,6 @@ volatile dq_queue_t g_assignedtasks[CONFIG_SMP_NCPUS];
FAR struct tcb_s *g_running_tasks[CONFIG_SMP_NCPUS]; FAR struct tcb_s *g_running_tasks[CONFIG_SMP_NCPUS];
#else
FAR struct tcb_s *g_running_tasks[1];
#endif
/* This is the list of all tasks that are ready-to-run, but cannot be placed /* This is the list of all tasks that are ready-to-run, but cannot be placed
* in the g_readytorun list because: (1) They are higher priority than the * in the g_readytorun list because: (1) They are higher priority than the
* currently active task at the head of the g_readytorun list, and (2) the * currently active task at the head of the g_readytorun list, and (2) the
@ -303,11 +302,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.
*/ */
#ifdef CONFIG_SMP
static struct task_tcb_s g_idletcb[CONFIG_SMP_NCPUS]; static struct task_tcb_s g_idletcb[CONFIG_SMP_NCPUS];
#else
static struct task_tcb_s g_idletcb[1];
#endif
/* This is the name of the idle task */ /* This is the name of the idle task */
@ -324,11 +319,7 @@ static const char g_idlename[] = "Idle Task";
* do things s little differently here for the IDLE tasks. * do things s little differently here for the IDLE tasks.
*/ */
#ifdef CONFIG_SMP
static FAR char *g_idleargv[CONFIG_SMP_NCPUS][2]; static FAR char *g_idleargv[CONFIG_SMP_NCPUS][2];
#else
static FAR char *g_idleargv[1][2];
#endif
/**************************************************************************** /****************************************************************************
* Public Functions * Public Functions
@ -352,7 +343,6 @@ static FAR char *g_idleargv[1][2];
void nx_start(void) void nx_start(void)
{ {
int cpu = 0;
int i; int i;
sinfo("Entry\n"); sinfo("Entry\n");
@ -399,18 +389,16 @@ void nx_start(void)
/* Initialize the IDLE task TCB *******************************************/ /* Initialize the IDLE task TCB *******************************************/
#ifdef CONFIG_SMP for (i = 0; i < CONFIG_SMP_NCPUS; i++)
for (cpu = 0; cpu < CONFIG_SMP_NCPUS; cpu++, g_lastpid++)
#endif
{ {
FAR dq_queue_t *tasklist; FAR dq_queue_t *tasklist;
int hashndx; int hashndx;
/* Assign the process ID(s) of ZERO to the idle task(s) */ /* Assign the process ID(s) of ZERO to the idle task(s) */
hashndx = PIDHASH(g_lastpid); hashndx = PIDHASH(i);
g_pidhash[hashndx].tcb = &g_idletcb[cpu].cmn; g_pidhash[hashndx].tcb = &g_idletcb[i].cmn;
g_pidhash[hashndx].pid = g_lastpid; g_pidhash[hashndx].pid = i;
/* Initialize a TCB for this thread of execution. NOTE: The default /* Initialize a TCB for this thread of execution. NOTE: The default
* value for most components of the g_idletcb are zero. The entire * value for most components of the g_idletcb are zero. The entire
@ -419,9 +407,9 @@ void nx_start(void)
* that has pid == 0 and sched_priority == 0. * that has pid == 0 and sched_priority == 0.
*/ */
memset((void *)&g_idletcb[cpu], 0, sizeof(struct task_tcb_s)); memset((void *)&g_idletcb[i], 0, sizeof(struct task_tcb_s));
g_idletcb[cpu].cmn.pid = g_lastpid; g_idletcb[i].cmn.pid = i;
g_idletcb[cpu].cmn.task_state = TSTATE_TASK_RUNNING; g_idletcb[i].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,
@ -430,16 +418,16 @@ void nx_start(void)
*/ */
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
if (cpu > 0) if (i > 0)
{ {
g_idletcb[cpu].cmn.start = nx_idle_trampoline; g_idletcb[i].cmn.start = nx_idle_trampoline;
g_idletcb[cpu].cmn.entry.main = (main_t)nx_idle_trampoline; g_idletcb[i].cmn.entry.main = (main_t)nx_idle_trampoline;
} }
else else
#endif #endif
{ {
g_idletcb[cpu].cmn.start = nx_start; g_idletcb[i].cmn.start = nx_start;
g_idletcb[cpu].cmn.entry.main = (main_t)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 /* Set the task flags to indicate that this is a kernel thread and, if
@ -447,12 +435,12 @@ void nx_start(void)
*/ */
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
g_idletcb[cpu].cmn.flags = (TCB_FLAG_TTYPE_KERNEL | g_idletcb[i].cmn.flags = (TCB_FLAG_TTYPE_KERNEL |
TCB_FLAG_NONCANCELABLE | TCB_FLAG_NONCANCELABLE |
TCB_FLAG_CPU_LOCKED); TCB_FLAG_CPU_LOCKED);
g_idletcb[cpu].cmn.cpu = cpu; g_idletcb[i].cmn.cpu = i;
#else #else
g_idletcb[cpu].cmn.flags = (TCB_FLAG_TTYPE_KERNEL | g_idletcb[i].cmn.flags = (TCB_FLAG_TTYPE_KERNEL |
TCB_FLAG_NONCANCELABLE); TCB_FLAG_NONCANCELABLE);
#endif #endif
@ -465,18 +453,18 @@ void nx_start(void)
* the IDLE task. * the IDLE task.
*/ */
g_idletcb[cpu].cmn.affinity = SCHED_ALL_CPUS; g_idletcb[i].cmn.affinity = SCHED_ALL_CPUS;
#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(g_idletcb[cpu].cmn.name, CONFIG_TASK_NAME_SIZE, "CPU%d IDLE", snprintf(g_idletcb[i].cmn.name, CONFIG_TASK_NAME_SIZE, "CPU%d IDLE",
cpu); i);
# else # else
strncpy(g_idletcb[cpu].cmn.name, g_idlename, CONFIG_TASK_NAME_SIZE); strncpy(g_idletcb[i].cmn.name, g_idlename, CONFIG_TASK_NAME_SIZE);
g_idletcb[cpu].cmn.name[CONFIG_TASK_NAME_SIZE] = '\0'; g_idletcb[i].cmn.name[CONFIG_TASK_NAME_SIZE] = '\0';
# endif # endif
#endif #endif
@ -489,39 +477,41 @@ void nx_start(void)
*/ */
#if CONFIG_TASK_NAME_SIZE > 0 #if CONFIG_TASK_NAME_SIZE > 0
g_idleargv[cpu][0] = g_idletcb[cpu].cmn.name; g_idleargv[i][0] = g_idletcb[i].cmn.name;
#else #else
g_idleargv[cpu][0] = (FAR char *)g_idlename; g_idleargv[i][0] = (FAR char *)g_idlename;
#endif /* CONFIG_TASK_NAME_SIZE */ #endif /* CONFIG_TASK_NAME_SIZE */
g_idleargv[cpu][1] = NULL; g_idleargv[i][1] = NULL;
g_idletcb[cpu].argv = &g_idleargv[cpu][0]; g_idletcb[i].argv = &g_idleargv[i][0];
/* Then add the idle task's TCB to the head of the current ready to /* Then add the idle task's TCB to the head of the current ready to
* run list. * run list.
*/ */
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
tasklist = TLIST_HEAD(TSTATE_TASK_RUNNING, cpu); tasklist = TLIST_HEAD(TSTATE_TASK_RUNNING, i);
#else #else
tasklist = TLIST_HEAD(TSTATE_TASK_RUNNING); tasklist = TLIST_HEAD(TSTATE_TASK_RUNNING);
#endif #endif
dq_addfirst((FAR dq_entry_t *)&g_idletcb[cpu], tasklist); dq_addfirst((FAR dq_entry_t *)&g_idletcb[i], tasklist);
/* Mark the idle task as the running task */ /* Mark the idle task as the running task */
g_running_tasks[cpu] = &g_idletcb[cpu].cmn; g_running_tasks[i] = &g_idletcb[i].cmn;
/* Initialize the 1st processor-specific portion of the TCB /* Initialize the 1st processor-specific portion of the TCB
* Note: other idle thread get initialized in nx_smpstart * Note: other idle thread get initialized in nx_smpstart
*/ */
if (cpu == 0) if (i == 0)
{ {
up_initial_state(&g_idletcb[cpu].cmn); up_initial_state(&g_idletcb[i].cmn);
up_stack_frame(&g_idletcb[cpu].cmn, sizeof(struct task_info_s)); up_stack_frame(&g_idletcb[i].cmn, sizeof(struct task_info_s));
} }
} }
g_lastpid = CONFIG_SMP_NCPUS - 1;
/* Task lists are initialized */ /* Task lists are initialized */
g_nx_initstate = OSINIT_TASKLISTS; g_nx_initstate = OSINIT_TASKLISTS;
@ -714,40 +704,36 @@ void nx_start(void)
sched_note_start(&g_idletcb[0].cmn); sched_note_start(&g_idletcb[0].cmn);
#ifdef CONFIG_SMP
/* Initialize the IDLE group for the IDLE task of each CPU */ /* Initialize the IDLE group for the IDLE task of each CPU */
for (cpu = 0; cpu < CONFIG_SMP_NCPUS; cpu++) for (i = 0; i < CONFIG_SMP_NCPUS; i++)
#endif
{ {
/* Allocate the IDLE group */ /* Allocate the IDLE group */
DEBUGVERIFY(group_allocate(&g_idletcb[cpu], g_idletcb[cpu].cmn.flags)); DEBUGVERIFY(group_allocate(&g_idletcb[i], g_idletcb[i].cmn.flags));
#ifdef CONFIG_SMP if (i > 0)
if (cpu > 0)
{ {
/* Clone stdout, stderr, stdin from the CPU0 IDLE task. */ /* Clone stdout, stderr, stdin from the CPU0 IDLE task. */
DEBUGVERIFY(group_setuptaskfiles(&g_idletcb[cpu])); DEBUGVERIFY(group_setuptaskfiles(&g_idletcb[i]));
} }
else else
#endif
{ {
/* Create stdout, stderr, stdin on the CPU0 IDLE task. These /* Create stdout, stderr, stdin on the CPU0 IDLE task. These
* will be inherited by all of the threads created by the CPU0 * will be inherited by all of the threads created by the CPU0
* IDLE task. * IDLE task.
*/ */
DEBUGVERIFY(group_setupidlefiles(&g_idletcb[cpu])); DEBUGVERIFY(group_setupidlefiles(&g_idletcb[i]));
} }
/* 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.
*/ */
DEBUGVERIFY(group_initialize(&g_idletcb[cpu])); DEBUGVERIFY(group_initialize(&g_idletcb[i]));
g_idletcb[cpu].cmn.group->tg_flags = GROUP_FLAG_NOCLDWAIT; g_idletcb[i].cmn.group->tg_flags = GROUP_FLAG_NOCLDWAIT;
} }
/* Start SYSLOG ***********************************************************/ /* Start SYSLOG ***********************************************************/