sched/group: addrenv: allocate current group for each cpu
Summary: - In case of SMP and ADDRENV, allocate current group for each cpu - g_pid_current holds pid of the group and uses for addrenv switching - allocate g_group_current for each cpu in stead of g_pid_current - g_group_current is the array that pointed to the current task_group_s struct Impact: - ADDRENV=y and SMP=y Testing: - sabre-6quad:smp w/ qemu - sabre-6quad:knsh w/ qemu - sabre-6quad:knsh_smp w/ qemu (WIP) Signed-off-by: Oki Minabe <minabe.oki@gmail.com>
This commit is contained in:
parent
d9a519444c
commit
22787ee109
@ -52,14 +52,14 @@ extern FAR struct task_group_s *g_grouphead;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_ARCH_ADDRENV
|
#ifdef CONFIG_ARCH_ADDRENV
|
||||||
/* This variable holds the PID of the current task group. This ID is
|
/* This variable holds the current task group. This pointer is NULL
|
||||||
* zero if the current task is a kernel thread that has no address
|
* if the current task is a kernel thread that has no address environment
|
||||||
* environment (other than the kernel context).
|
* (other than the kernel context).
|
||||||
*
|
*
|
||||||
* This must only be accessed with interrupts disabled.
|
* This must only be accessed with interrupts disabled.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
extern pid_t g_pid_current;
|
extern FAR struct task_group_s *g_group_current[CONFIG_SMP_NCPUS];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
@ -39,14 +39,14 @@
|
|||||||
* Public Data
|
* Public Data
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/* This variable holds the PID of the current task group. This ID is
|
/* This variable holds the current task group. This pointer is NULL
|
||||||
* zero if the current task is a kernel thread that has no address
|
* if the current task is a kernel thread that has no address environment
|
||||||
* environment (other than the kernel context).
|
* (other than the kernel context).
|
||||||
*
|
*
|
||||||
* This must only be accessed with interrupts disabled.
|
* This must only be accessed with interrupts disabled.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
pid_t g_pid_current = INVALID_PROCESS_ID;
|
FAR struct task_group_s *g_group_current[CONFIG_SMP_NCPUS];
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Functions
|
* Public Functions
|
||||||
@ -85,7 +85,7 @@ int group_addrenv(FAR struct tcb_s *tcb)
|
|||||||
FAR struct task_group_s *group;
|
FAR struct task_group_s *group;
|
||||||
FAR struct task_group_s *oldgroup;
|
FAR struct task_group_s *oldgroup;
|
||||||
irqstate_t flags;
|
irqstate_t flags;
|
||||||
pid_t pid;
|
int cpu;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* NULL for the tcb means to use the TCB of the task at the head of the
|
/* NULL for the tcb means to use the TCB of the task at the head of the
|
||||||
@ -111,34 +111,24 @@ int group_addrenv(FAR struct tcb_s *tcb)
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the PID of the group that needs the address environment */
|
|
||||||
|
|
||||||
pid = group->tg_pid;
|
|
||||||
DEBUGASSERT(pid != INVALID_PROCESS_ID);
|
|
||||||
|
|
||||||
/* Are we going to change address environments? */
|
/* Are we going to change address environments? */
|
||||||
|
|
||||||
flags = enter_critical_section();
|
flags = enter_critical_section();
|
||||||
if (pid != g_pid_current)
|
|
||||||
|
cpu = this_cpu();
|
||||||
|
oldgroup = g_group_current[cpu];
|
||||||
|
if (group != oldgroup)
|
||||||
{
|
{
|
||||||
/* Yes.. Is there a current address environment in place? */
|
/* Yes.. Is there a current address environment in place? */
|
||||||
|
|
||||||
if (g_pid_current != INVALID_PROCESS_ID)
|
if (oldgroup)
|
||||||
{
|
{
|
||||||
/* Find the old group with this ID. */
|
/* We need to flush the D-Cache and Invalidate the I-Cache for
|
||||||
|
* the group whose environment is disappearing.
|
||||||
|
*/
|
||||||
|
|
||||||
oldgroup = group_findbypid(g_pid_current);
|
DEBUGASSERT((oldgroup->tg_flags & GROUP_FLAG_ADDRENV) != 0);
|
||||||
DEBUGASSERT(oldgroup &&
|
up_addrenv_coherent(&oldgroup->tg_addrenv);
|
||||||
(oldgroup->tg_flags & GROUP_FLAG_ADDRENV) != 0);
|
|
||||||
|
|
||||||
if (oldgroup)
|
|
||||||
{
|
|
||||||
/* We need to flush the D-Cache and Invalidate the I-Cache for
|
|
||||||
* the group whose environment is disappearing.
|
|
||||||
*/
|
|
||||||
|
|
||||||
up_addrenv_coherent(&oldgroup->tg_addrenv);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Instantiate the new address environment (removing the old
|
/* Instantiate the new address environment (removing the old
|
||||||
@ -155,7 +145,7 @@ int group_addrenv(FAR struct tcb_s *tcb)
|
|||||||
|
|
||||||
/* Save the new, current group */
|
/* Save the new, current group */
|
||||||
|
|
||||||
g_pid_current = pid;
|
g_group_current[cpu] = group;
|
||||||
}
|
}
|
||||||
|
|
||||||
leave_critical_section(flags);
|
leave_critical_section(flags);
|
||||||
|
@ -130,6 +130,7 @@ static inline void group_release(FAR struct task_group_s *group)
|
|||||||
{
|
{
|
||||||
#ifdef CONFIG_ARCH_ADDRENV
|
#ifdef CONFIG_ARCH_ADDRENV
|
||||||
save_addrenv_t oldenv;
|
save_addrenv_t oldenv;
|
||||||
|
int i;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CONFIG_TLS_TASK_NELEM > 0
|
#if CONFIG_TLS_TASK_NELEM > 0
|
||||||
@ -248,7 +249,13 @@ static inline void group_release(FAR struct task_group_s *group)
|
|||||||
|
|
||||||
/* Mark no address environment */
|
/* Mark no address environment */
|
||||||
|
|
||||||
g_pid_current = INVALID_PROCESS_ID;
|
for (i = 0; i < CONFIG_SMP_NCPUS; i++)
|
||||||
|
{
|
||||||
|
if (group == g_group_current[i])
|
||||||
|
{
|
||||||
|
g_group_current[i] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Restore the previous addrenv */
|
/* Restore the previous addrenv */
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user