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:
parent
85470176e7
commit
bb867a38fc
@ -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 ***********************************************************/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user