| 448 | } |
| 449 | |
| 450 | static void |
| 451 | taskqueue_run_locked(struct taskqueue *queue) |
| 452 | { |
| 453 | struct epoch_tracker et; |
| 454 | struct taskqueue_busy tb; |
| 455 | struct task *task; |
| 456 | bool in_net_epoch; |
| 457 | int pending; |
| 458 | |
| 459 | KASSERT(queue != NULL, ("tq is NULL")); |
| 460 | TQ_ASSERT_LOCKED(queue); |
| 461 | tb.tb_running = NULL; |
| 462 | LIST_INSERT_HEAD(&queue->tq_active, &tb, tb_link); |
| 463 | in_net_epoch = false; |
| 464 | |
| 465 | while ((task = STAILQ_FIRST(&queue->tq_queue)) != NULL) { |
| 466 | STAILQ_REMOVE_HEAD(&queue->tq_queue, ta_link); |
| 467 | if (queue->tq_hint == task) |
| 468 | queue->tq_hint = NULL; |
| 469 | pending = task->ta_pending; |
| 470 | task->ta_pending = 0; |
| 471 | tb.tb_running = task; |
| 472 | tb.tb_seq = ++queue->tq_seq; |
| 473 | TQ_UNLOCK(queue); |
| 474 | |
| 475 | KASSERT(task->ta_func != NULL, ("task->ta_func is NULL")); |
| 476 | if (!in_net_epoch && TASK_IS_NET(task)) { |
| 477 | in_net_epoch = true; |
| 478 | NET_EPOCH_ENTER(et); |
| 479 | } else if (in_net_epoch && !TASK_IS_NET(task)) { |
| 480 | NET_EPOCH_EXIT(et); |
| 481 | in_net_epoch = false; |
| 482 | } |
| 483 | task->ta_func(task->ta_context, pending); |
| 484 | |
| 485 | TQ_LOCK(queue); |
| 486 | wakeup(task); |
| 487 | } |
| 488 | if (in_net_epoch) |
| 489 | NET_EPOCH_EXIT(et); |
| 490 | LIST_REMOVE(&tb, tb_link); |
| 491 | } |
| 492 | |
| 493 | void |
| 494 | taskqueue_run(struct taskqueue *queue) |
no test coverage detected