Skip to content

Commit

Permalink
sched/tcb: reduce kthreads TCB overheads
Browse files Browse the repository at this point in the history
This uses `tcb_s` and shared `task_group_s` instance for kthreads
so that to reduce overheads.

Signed-off-by: Yanfeng Liu <[email protected]>
  • Loading branch information
yf13 committed May 11, 2024
1 parent a8f81e4 commit 15ec864
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 36 deletions.
20 changes: 18 additions & 2 deletions sched/group/group_create.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
****************************************************************************/
Expand Down Expand Up @@ -119,9 +121,23 @@ int group_initialize(FAR struct task_tcb_s *tcb, uint8_t ttype)

DEBUGASSERT(tcb && !tcb->cmn.group);

ttype &= TCB_FLAG_TTYPE_MASK;

if (ttype == TCB_FLAG_TTYPE_KERNEL && g_kthread_group.tg_info)
{
tcb->cmn.group = &g_kthread_group;
return OK;
}

if (NULL == g_kthread_group.tg_info)
{
sinfo("group=%zu task=%zu kthread=%zu\n", sizeof(*group),
sizeof(struct task_tcb_s), sizeof(struct tcb_s));
}

/* Allocate the group structure and assign it to the TCB */

group = &tcb->group;
group = (ttype == TCB_FLAG_TTYPE_KERNEL) ? &g_kthread_group : &tcb->group;

#if defined(CONFIG_MM_KERNEL_HEAP)
/* If this group is being created for a privileged thread, then all
Expand Down
67 changes: 34 additions & 33 deletions sched/init/nx_start.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */

Expand Down Expand Up @@ -350,7 +350,7 @@ 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;

Expand All @@ -365,9 +365,9 @@ 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;
memset(tcb, 0, sizeof(*tcb));
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,
Expand All @@ -378,23 +378,23 @@ 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
* 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;
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
Expand All @@ -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
Expand All @@ -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 */
Expand All @@ -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;
}
}

Expand All @@ -459,27 +459,28 @@ static void idle_task_initialize(void)

static void idle_group_initialize(void)
{
FAR struct task_tcb_s *tcb;
FAR struct tcb_s *tcb;
FAR struct task_tcb_s *ttcb;
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];
ttcb = (FAR struct task_tcb_s *)(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(ttcb, 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
Expand All @@ -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(ttcb);
tcb->group->tg_flags = GROUP_FLAG_NOCLDWAIT | GROUP_FLAG_PRIVILEGED;
}
}

Expand All @@ -533,6 +532,7 @@ static void idle_group_initialize(void)

void nx_start(void)
{
FAR struct task_tcb_s *ttcb;
int i;

sinfo("Entry\n");
Expand Down Expand Up @@ -733,11 +733,12 @@ void nx_start(void)

for (i = 0; i < CONFIG_SMP_NCPUS; i++)
{
ttcb = (FAR struct task_tcb_s *)&g_idletcb[i];
if (i > 0)
{
/* Clone stdout, stderr, stdin from the CPU0 IDLE task. */

DEBUGVERIFY(group_setuptaskfiles(&g_idletcb[i], NULL, true));
DEBUGVERIFY(group_setuptaskfiles(ttcb, NULL, true));
}
else
{
Expand Down
3 changes: 2 additions & 1 deletion sched/task/task_create.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ int nxthread_create(FAR const char *name, uint8_t ttype, int priority,

/* 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");
Expand Down

0 comments on commit 15ec864

Please sign in to comment.