diff --git a/headers/private/kernel/smp.h b/headers/private/kernel/smp.h index 6cec754528..8e9c793d69 100644 --- a/headers/private/kernel/smp.h +++ b/headers/private/kernel/smp.h @@ -44,7 +44,7 @@ extern "C" { status_t smp_init(struct kernel_args *args); status_t smp_per_cpu_init(struct kernel_args *args, int32 cpu); status_t smp_init_post_generic_syscalls(void); -bool smp_trap_non_boot_cpus(int32 cpu); +bool smp_trap_non_boot_cpus(int32 cpu, uint32* rendezVous); void smp_wake_up_non_boot_cpus(void); void smp_cpu_rendezvous(volatile uint32 *var, int current_cpu); void smp_send_ici(int32 targetCPU, int32 message, uint32 data, uint32 data2, uint32 data3, diff --git a/src/system/kernel/main.cpp b/src/system/kernel/main.cpp index 2718939471..c7d61e32ca 100644 --- a/src/system/kernel/main.cpp +++ b/src/system/kernel/main.cpp @@ -67,6 +67,7 @@ bool gKernelStartup = true; static kernel_args sKernelArgs; static uint32 sCpuRendezvous; static uint32 sCpuRendezvous2; +static uint32 sCpuRendezvous3; static int32 main2(void *); @@ -100,7 +101,7 @@ _start(kernel_args *bootKernelArgs, int currentCPU) thread_preboot_init_percpu(&sKernelArgs, currentCPU); // if we're not a boot cpu, spin here until someone wakes us up - if (smp_trap_non_boot_cpus(currentCPU)) { + if (smp_trap_non_boot_cpus(currentCPU, &sCpuRendezvous3)) { // init platform arch_platform_init(&sKernelArgs); diff --git a/src/system/kernel/smp.cpp b/src/system/kernel/smp.cpp index 7a7dc3479e..fa2cd6e3e2 100644 --- a/src/system/kernel/smp.cpp +++ b/src/system/kernel/smp.cpp @@ -1044,20 +1044,25 @@ smp_send_broadcast_ici_interrupts_disabled(int32 currentCPU, int32 message, } +/*! Spin on non-boot CPUs until smp_wake_up_non_boot_cpus() has been called. + + \param cpu The index of the calling CPU. + \param rendezVous A rendez-vous variable to make sure that the boot CPU + does not return before all other CPUs have started waiting. + \return \c true on the boot CPU, \c false otherwise. +*/ bool -smp_trap_non_boot_cpus(int32 cpu) +smp_trap_non_boot_cpus(int32 cpu, uint32* rendezVous) { - if (cpu > 0) { -#if B_DEBUG_SPINLOCK_CONTENTION - boot_cpu_spin[cpu].lock = 1; -#else - boot_cpu_spin[cpu] = 1; -#endif - acquire_spinlock_nocheck(&boot_cpu_spin[cpu]); - return false; + if (cpu == 0) { + smp_cpu_rendezvous(rendezVous, cpu); + return true; } - return true; + acquire_spinlock_nocheck(&boot_cpu_spin[cpu]); + smp_cpu_rendezvous(rendezVous, cpu); + acquire_spinlock_nocheck(&boot_cpu_spin[cpu]); + return false; }