* Steals load from a timeshare queue. Honors the rotating queue head * index. */
| 1108 | * index. |
| 1109 | */ |
| 1110 | static struct thread * |
| 1111 | runq_steal_from(struct runq *rq, int cpu, u_char start) |
| 1112 | { |
| 1113 | struct rqbits *rqb; |
| 1114 | struct rqhead *rqh; |
| 1115 | struct thread *td, *first; |
| 1116 | int bit; |
| 1117 | int i; |
| 1118 | |
| 1119 | rqb = &rq->rq_status; |
| 1120 | bit = start & (RQB_BPW -1); |
| 1121 | first = NULL; |
| 1122 | again: |
| 1123 | for (i = RQB_WORD(start); i < RQB_LEN; bit = 0, i++) { |
| 1124 | if (rqb->rqb_bits[i] == 0) |
| 1125 | continue; |
| 1126 | if (bit == 0) |
| 1127 | bit = RQB_FFS(rqb->rqb_bits[i]); |
| 1128 | for (; bit < RQB_BPW; bit++) { |
| 1129 | if ((rqb->rqb_bits[i] & (1ul << bit)) == 0) |
| 1130 | continue; |
| 1131 | rqh = &rq->rq_queues[bit + (i << RQB_L2BPW)]; |
| 1132 | TAILQ_FOREACH(td, rqh, td_runq) { |
| 1133 | if (first && THREAD_CAN_MIGRATE(td) && |
| 1134 | THREAD_CAN_SCHED(td, cpu)) |
| 1135 | return (td); |
| 1136 | first = td; |
| 1137 | } |
| 1138 | } |
| 1139 | } |
| 1140 | if (start != 0) { |
| 1141 | start = 0; |
| 1142 | goto again; |
| 1143 | } |
| 1144 | |
| 1145 | if (first && THREAD_CAN_MIGRATE(first) && |
| 1146 | THREAD_CAN_SCHED(first, cpu)) |
| 1147 | return (first); |
| 1148 | return (NULL); |
| 1149 | } |
| 1150 | |
| 1151 | /* |
| 1152 | * Steals load from a standard linear queue. |