SIM: Add SMP idle thread setup logic

This commit is contained in:
Gregory Nutt 2016-02-11 12:16:19 -06:00
parent 2f08f2fe6c
commit b087cb7f9a
5 changed files with 50 additions and 10 deletions

@ -46,6 +46,7 @@
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Must match definitions in up_testset.c */
#define SP_UNLOCKED false /* The Un-locked state */
#define SP_LOCKED true /* The Locked state */
@ -53,6 +54,7 @@
/****************************************************************************
* Public Types
****************************************************************************/
/* Must match definitions in up_testset.c */
typedef bool spinlock_t;

@ -65,7 +65,12 @@ ifeq ($(CONFIG_SCHED_TICKLESS),y)
CSRCS += up_tickless.c
endif
ifeq ($(CONFIG_SPINLOCK),y)
HOSTSRCS += up_testset.c
endif
ifeq ($(CONFIG_SMP),y)
CSRCS += up_idlesetup.c
HOSTSRCS += up_simsmp.c
endif
@ -115,6 +120,10 @@ else
endif
endif
ifeq ($(CONFIG_SMP),y)
HOSTCFLAGS += -DCONFIG_SMP=1
endif
ifeq ($(CONFIG_FS_HOSTFS),y)
HOSTSRCS += up_hostfs.c

@ -1,7 +1,7 @@
/****************************************************************************
* arch/sim/src/up_idle.c
*
* Copyright (C) 2007-2009, 2011-2012, 2014 Gregory Nutt. All rights reserved.
* Copyright (C) 2007-2009, 2011-2012, 2014, 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -42,6 +42,7 @@
#include <time.h>
#include <nuttx/arch.h>
#include <nuttx/spinlock.h>
#include <nuttx/power/pm.h>
#include "up_internal.h"
@ -94,6 +95,23 @@ extern void up_x11update(void);
void up_idle(void)
{
#ifdef CONFIG_SMP
/* In the SMP configuration, only one CPU should do these operations. It
* should not matter which, however.
*/
static volatile spinlock_t lock;
/* The one that gets the lock is the one that executes the IDLE operations */
if (up_testset(&lock) != SP_UNLOCKED)
{
/* We didn't get it... just return and try again later */
return;
}
#endif
#ifdef CONFIG_SCHED_TICKLESS
/* Driver the simulated interval timer */
@ -172,5 +190,10 @@ void up_idle(void)
}
#endif
#endif
}
#ifdef CONFIG_SMP
/* Release the spinlock and return */
lock = SP_UNLOCKED;
#endif
}

@ -49,6 +49,9 @@
# include <nuttx/irq.h>
# include <arch/irq.h>
# ifdef CONFIG_SMP
# include <nuttx/sched.h>
# endif
#endif
/****************************************************************************
@ -214,6 +217,7 @@ void up_longjmp(xcpt_reg_t *jb, int val) noreturn_function;
#ifdef CONFIG_SMP
int sim_cpu0initialize(void);
int sim_cpustart(int cpu, main_t idletask);
#endif
/* up_tickless.c **********************************************************/

@ -69,7 +69,7 @@ static pthread_key_t g_cpukey;
* Description:
* This is a pthread task entry point. A (host) pthread is used to
* simulate a CPU. Multiple pthreads is a good analog to tasks running on
* multiple CPUs
* multiple CPUs
*
* This function is simply a wrapper that sets the pthread specific data
* that presents the CPU number and then calls into the IDLE task entry
@ -171,7 +171,7 @@ int up_cpundx(void)
}
/****************************************************************************
* Name: up_cpustart
* Name: sim_cpustart
*
* Description:
* In an SMP configution, only one CPU is initially active (CPU 0). System
@ -194,7 +194,7 @@ int up_cpundx(void)
*
****************************************************************************/
int up_cpustart(int cpu, main_t idletask)
int sim_cpustart(int cpu, main_t idletask)
{
struct sim_cpuinfo_s cpuinfo;
pthread_t thread;
@ -207,7 +207,7 @@ int up_cpustart(int cpu, main_t idletask)
ret = pthread_mutex_init(&cpuinfo.mutex, NULL);
if (ret != 0)
{
return -ret;
return -ret; /* REVISIT: That is a host errno value. */
}
/* Lock the mutex */
@ -215,16 +215,18 @@ int up_cpustart(int cpu, main_t idletask)
ret = pthread_mutex_lock(&cpuinfo.mutex);
if (ret != 0)
{
ret = -ret;
ret = -ret; /* REVISIT: This is a host errno value. */
goto errout_with_mutex;
}
/* Start the CPU emulation thread */
/* Start the CPU emulation thread. This is analogous to starting the CPU
* in a multi-CPU hardware model.
*/
ret = pthread_create(&thread, NULL, sim_idle_trampoline, &cpuinfo);
if (ret != 0)
{
ret = -ret;
ret = -ret; /* REVISIT: That is a host errno value. */
goto errout_with_lock;
}
@ -235,7 +237,7 @@ int up_cpustart(int cpu, main_t idletask)
ret = pthread_mutex_lock(&cpuinfo.mutex);
if (ret != 0)
{
ret = -ret;
ret = -ret; /* REVISIT: That is a host errno value. */
}
errout_with_lock: