* This is the main code for interrupt threads. */
| 1216 | * This is the main code for interrupt threads. |
| 1217 | */ |
| 1218 | static void |
| 1219 | ithread_loop(void *arg) |
| 1220 | { |
| 1221 | struct epoch_tracker et; |
| 1222 | struct intr_thread *ithd; |
| 1223 | struct intr_event *ie; |
| 1224 | struct thread *td; |
| 1225 | struct proc *p; |
| 1226 | int wake, epoch_count; |
| 1227 | bool needs_epoch; |
| 1228 | |
| 1229 | td = curthread; |
| 1230 | p = td->td_proc; |
| 1231 | ithd = (struct intr_thread *)arg; |
| 1232 | KASSERT(ithd->it_thread == td, |
| 1233 | ("%s: ithread and proc linkage out of sync", __func__)); |
| 1234 | ie = ithd->it_event; |
| 1235 | ie->ie_count = 0; |
| 1236 | wake = 0; |
| 1237 | |
| 1238 | /* |
| 1239 | * As long as we have interrupts outstanding, go through the |
| 1240 | * list of handlers, giving each one a go at it. |
| 1241 | */ |
| 1242 | for (;;) { |
| 1243 | /* |
| 1244 | * If we are an orphaned thread, then just die. |
| 1245 | */ |
| 1246 | if (ithd->it_flags & IT_DEAD) { |
| 1247 | CTR3(KTR_INTR, "%s: pid %d (%s) exiting", __func__, |
| 1248 | p->p_pid, td->td_name); |
| 1249 | free(ithd, M_ITHREAD); |
| 1250 | kthread_exit(); |
| 1251 | } |
| 1252 | |
| 1253 | /* |
| 1254 | * Service interrupts. If another interrupt arrives while |
| 1255 | * we are running, it will set it_need to note that we |
| 1256 | * should make another pass. |
| 1257 | * |
| 1258 | * The load_acq part of the following cmpset ensures |
| 1259 | * that the load of ih_need in ithread_execute_handlers() |
| 1260 | * is ordered after the load of it_need here. |
| 1261 | */ |
| 1262 | needs_epoch = |
| 1263 | (atomic_load_int(&ie->ie_hflags) & IH_NET) != 0; |
| 1264 | if (needs_epoch) { |
| 1265 | epoch_count = 0; |
| 1266 | NET_EPOCH_ENTER(et); |
| 1267 | } |
| 1268 | while (atomic_cmpset_acq_int(&ithd->it_need, 1, 0) != 0) { |
| 1269 | ithread_execute_handlers(p, ie); |
| 1270 | if (needs_epoch && |
| 1271 | ++epoch_count >= intr_epoch_batch) { |
| 1272 | NET_EPOCH_EXIT(et); |
| 1273 | epoch_count = 0; |
| 1274 | NET_EPOCH_ENTER(et); |
| 1275 | } |
nothing calls this directly
no test coverage detected