/* * Halt all running cpus, excluding current cpu. */ void cpu_halt_others(void) { kcpuset_t *kcp; // If we are the only CPU running, there's nothing to do. if (kcpuset_match(cpus_running, curcpu()->ci_data.cpu_kcpuset)) return; // Get all running CPUs kcpuset_clone(&kcp, cpus_running); // Remove ourself kcpuset_remove(kcp, curcpu()->ci_data.cpu_kcpuset); // Remove any halted CPUs kcpuset_remove(kcp, cpus_halted); // If there are CPUs left, send the IPIs if (!kcpuset_iszero(kcp)) { cpu_multicast_ipi(kcp, IPI_HALT); cpu_ipi_wait("halt", cpus_halted, kcp); } kcpuset_destroy(kcp); /* * TBD * Depending on available firmware methods, other cpus will * either shut down themselves, or spin and wait for us to * stop them. */ }
/* * Pause all running cpus, excluding current cpu. */ void cpu_pause_others(void) { __cpuset_t cpuset; CPUSET_ASSIGN(cpuset, cpus_running); CPUSET_DEL(cpuset, cpu_index(curcpu())); if (CPUSET_EMPTY_P(cpuset)) return; cpu_multicast_ipi(cpuset, IPI_SUSPEND); if (cpu_ipi_wait(&cpus_paused, cpuset)) cpu_ipi_error("pause", cpus_paused, cpuset); }
/* * Halt all running cpus, excluding current cpu. */ void cpu_halt_others(void) { __cpuset_t cpumask, cpuset; CPUSET_ASSIGN(cpuset, cpus_running); CPUSET_DEL(cpuset, cpu_index(curcpu())); CPUSET_ASSIGN(cpumask, cpuset); CPUSET_SUB(cpuset, cpus_halted); if (CPUSET_EMPTY_P(cpuset)) return; cpu_multicast_ipi(cpuset, IPI_HALT); if (cpu_ipi_wait(&cpus_halted, cpumask)) cpu_ipi_error("halt", cpumask, cpus_halted); /* * TBD * Depending on available firmware methods, other cpus will * either shut down themselfs, or spin and wait for us to * stop them. */ }
void cpu_broadcast_ipi(int tag) { // No reason to remove ourselves since multicast_ipi will do that for us cpu_multicast_ipi(cpus_running, tag); }
void cpu_broadcast_ipi(int tag) { (void)cpu_multicast_ipi( CPUSET_EXCEPT(cpus_running, cpu_index(curcpu())), tag); }