+
+/* pset is locked */
+static processor_t
+choose_processor_for_realtime_thread(processor_set_t pset)
+{
+ uint64_t cpu_map = (pset->cpu_bitmask & pset->recommended_bitmask & ~pset->pending_AST_cpu_mask);
+
+ for (int cpuid = lsb_first(cpu_map); cpuid >= 0; cpuid = lsb_next(cpu_map, cpuid)) {
+ processor_t processor = processor_array[cpuid];
+
+ if (processor->processor_primary != processor) {
+ continue;
+ }
+
+ if (processor->state == PROCESSOR_IDLE) {
+ return processor;
+ }
+
+ if ((processor->state != PROCESSOR_RUNNING) && (processor->state != PROCESSOR_DISPATCHING)) {
+ continue;
+ }
+
+ if (processor->current_pri >= BASEPRI_RTQUEUES) {
+ continue;
+ }
+
+ return processor;
+
+ }
+
+ if (!sched_allow_rt_smt) {
+ return PROCESSOR_NULL;
+ }
+
+ /* Consider secondary processors */
+ for (int cpuid = lsb_first(cpu_map); cpuid >= 0; cpuid = lsb_next(cpu_map, cpuid)) {
+ processor_t processor = processor_array[cpuid];
+
+ if (processor->processor_primary == processor) {
+ continue;
+ }
+
+ if (processor->state == PROCESSOR_IDLE) {
+ return processor;
+ }
+
+ if ((processor->state != PROCESSOR_RUNNING) && (processor->state != PROCESSOR_DISPATCHING)) {
+ continue;
+ }
+
+ if (processor->current_pri >= BASEPRI_RTQUEUES) {
+ continue;
+ }
+
+ return processor;
+
+ }
+
+ return PROCESSOR_NULL;
+}
+
+/* pset is locked */
+static bool
+all_available_primaries_are_running_realtime_threads(processor_set_t pset)
+{
+ uint64_t cpu_map = (pset->cpu_bitmask & pset->recommended_bitmask);
+
+ for (int cpuid = lsb_first(cpu_map); cpuid >= 0; cpuid = lsb_next(cpu_map, cpuid)) {
+ processor_t processor = processor_array[cpuid];
+
+ if (processor->processor_primary != processor) {
+ continue;
+ }
+
+ if (processor->state == PROCESSOR_IDLE) {
+ return false;
+ }
+
+ if (processor->state == PROCESSOR_DISPATCHING) {
+ return false;
+ }
+
+ if (processor->state != PROCESSOR_RUNNING) {
+ /*
+ * All other processor states are considered unavailable to run
+ * realtime threads. In particular, we prefer an available secondary
+ * processor over the risk of leaving a realtime thread on the run queue
+ * while waiting for a processor in PROCESSOR_START state,
+ * which should anyway be a rare case.
+ */
+ continue;
+ }
+
+ if (processor->current_pri < BASEPRI_RTQUEUES) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+