This is an automated email from the ASF dual-hosted git repository. xiaoxiang pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
commit 5beb32bf0b1a9373f6a26a797e495757a2422e31 Author: Sebastian Ene <nu...@fitbit.com> AuthorDate: Fri Sep 4 11:54:57 2020 +0300 arch/sim: Use pthread_cond for signalling CPU initialisation done ## Summary of changes On OSX with CONFIG_SMP=y the semaphore which notifies that the CPU is initialised, is not created and the up_cpu_start() returns with error from sem_init(). This patch fixes the problem by using pthread_cond_t signalling mechanism which is supported on Mac. Signed-off-by: Sebastian Ene <nu...@fitbit.com> --- arch/sim/src/sim/up_simsmp.c | 41 ++++++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/arch/sim/src/sim/up_simsmp.c b/arch/sim/src/sim/up_simsmp.c index 243f89b..56f8ac6 100644 --- a/arch/sim/src/sim/up_simsmp.c +++ b/arch/sim/src/sim/up_simsmp.c @@ -39,7 +39,8 @@ #include <stdint.h> #include <pthread.h> -#include <semaphore.h> +#include <stdlib.h> +#include <stdbool.h> #include <signal.h> #include <sched.h> #include <errno.h> @@ -52,8 +53,10 @@ struct sim_cpuinfo_s { - int cpu; /* CPU number */ - sem_t done; /* For synchronization */ + int cpu; /* CPU number */ + pthread_cond_t cpu_init_done; /* For synchronization */ + pthread_mutex_t cpu_init_lock; + bool is_cpu_initialized; }; /**************************************************************************** @@ -145,7 +148,12 @@ static void *sim_idle_trampoline(void *arg) /* Let up_cpu_start() continue */ - sem_post(&cpuinfo->done); + pthread_mutex_lock(&cpuinfo->cpu_init_lock); + + cpuinfo->is_cpu_initialized = true; + pthread_cond_signal(&cpuinfo->cpu_init_done); + + pthread_mutex_unlock(&cpuinfo->cpu_init_lock); /* up_cpu_started() is logically a part of this function but needs to be * inserted in the path because in needs to access NuttX domain definition. @@ -324,11 +332,10 @@ int up_cpu_start(int cpu) /* Initialize the CPU info */ cpuinfo.cpu = cpu; - ret = sem_init(&cpuinfo.done, 0, 0); - if (ret != 0) - { - return -errno; /* REVISIT: That is a host errno value. */ - } + cpuinfo.is_cpu_initialized = false; + + pthread_mutex_init(&cpuinfo.cpu_init_lock, NULL); + pthread_cond_init(&cpuinfo.cpu_init_done, NULL); /* Start the CPU emulation thread. This is analogous to starting the CPU * in a multi-CPU hardware model. @@ -339,19 +346,23 @@ int up_cpu_start(int cpu) if (ret != 0) { ret = -ret; /* REVISIT: That is a host errno value. */ - goto errout_with_sem; + goto errout_with_cond; } /* This will block until the pthread post the semaphore */ - ret = sem_wait(&cpuinfo.done); - if (ret != 0) + pthread_mutex_lock(&cpuinfo.cpu_init_lock); + + while (!cpuinfo.is_cpu_initialized) { - ret = -errno; /* REVISIT: That is a host errno value. */ + pthread_cond_wait(&cpuinfo.cpu_init_done, &cpuinfo.cpu_init_lock); } -errout_with_sem: - sem_destroy(&cpuinfo.done); + pthread_mutex_unlock(&cpuinfo.cpu_init_lock); + +errout_with_cond: + pthread_mutex_destroy(&cpuinfo.cpu_init_lock); + pthread_cond_destroy(&cpuinfo.cpu_init_done); return ret; }