Lines 346-358
taskqueue_task_nop_fn(void *context, int pending)
Link Here
|
346 |
* have begun execution. Tasks queued during execution of |
346 |
* have begun execution. Tasks queued during execution of |
347 |
* this function are ignored. |
347 |
* this function are ignored. |
348 |
*/ |
348 |
*/ |
349 |
static void |
349 |
static int |
350 |
taskqueue_drain_tq_queue(struct taskqueue *queue) |
350 |
taskqueue_drain_tq_queue(struct taskqueue *queue) |
351 |
{ |
351 |
{ |
352 |
struct task t_barrier; |
352 |
struct task t_barrier; |
353 |
|
353 |
|
354 |
if (STAILQ_EMPTY(&queue->tq_queue)) |
354 |
if (STAILQ_EMPTY(&queue->tq_queue)) |
355 |
return; |
355 |
return (0); |
356 |
|
356 |
|
357 |
/* |
357 |
/* |
358 |
* Enqueue our barrier after all current tasks, but with |
358 |
* Enqueue our barrier after all current tasks, but with |
Lines 372-377
taskqueue_drain_tq_queue(struct taskqueue *queue)
Link Here
|
372 |
*/ |
372 |
*/ |
373 |
while (t_barrier.ta_pending != 0) |
373 |
while (t_barrier.ta_pending != 0) |
374 |
TQ_SLEEP(queue, &t_barrier, &queue->tq_mutex, PWAIT, "-", 0); |
374 |
TQ_SLEEP(queue, &t_barrier, &queue->tq_mutex, PWAIT, "-", 0); |
|
|
375 |
return (1); |
375 |
} |
376 |
} |
376 |
|
377 |
|
377 |
/* |
378 |
/* |
Lines 379-391
taskqueue_drain_tq_queue(struct taskqueue *queue)
Link Here
|
379 |
* complete. Tasks that begin execution during the execution |
380 |
* complete. Tasks that begin execution during the execution |
380 |
* of this function are ignored. |
381 |
* of this function are ignored. |
381 |
*/ |
382 |
*/ |
382 |
static void |
383 |
static int |
383 |
taskqueue_drain_tq_active(struct taskqueue *queue) |
384 |
taskqueue_drain_tq_active(struct taskqueue *queue) |
384 |
{ |
385 |
{ |
385 |
struct taskqueue_busy tb_marker, *tb_first; |
386 |
struct taskqueue_busy tb_marker, *tb_first; |
386 |
|
387 |
|
387 |
if (TAILQ_EMPTY(&queue->tq_active)) |
388 |
if (TAILQ_EMPTY(&queue->tq_active)) |
388 |
return; |
389 |
return (0); |
389 |
|
390 |
|
390 |
/* Block taskq_terminate().*/ |
391 |
/* Block taskq_terminate().*/ |
391 |
queue->tq_callouts++; |
392 |
queue->tq_callouts++; |
Lines 412-417
taskqueue_drain_tq_active(struct taskqueue *queue)
Link Here
|
412 |
queue->tq_callouts--; |
413 |
queue->tq_callouts--; |
413 |
if ((queue->tq_flags & TQ_FLAGS_ACTIVE) == 0) |
414 |
if ((queue->tq_flags & TQ_FLAGS_ACTIVE) == 0) |
414 |
wakeup_one(queue->tq_threads); |
415 |
wakeup_one(queue->tq_threads); |
|
|
416 |
return (1); |
415 |
} |
417 |
} |
416 |
|
418 |
|
417 |
void |
419 |
void |
Lines 582-589
taskqueue_drain_all(struct taskqueue *queue)
Link Here
|
582 |
WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, __func__); |
584 |
WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, __func__); |
583 |
|
585 |
|
584 |
TQ_LOCK(queue); |
586 |
TQ_LOCK(queue); |
585 |
taskqueue_drain_tq_queue(queue); |
587 |
(void)taskqueue_drain_tq_queue(queue); |
586 |
taskqueue_drain_tq_active(queue); |
588 |
(void)taskqueue_drain_tq_active(queue); |
587 |
TQ_UNLOCK(queue); |
589 |
TQ_UNLOCK(queue); |
588 |
} |
590 |
} |
589 |
|
591 |
|
Lines 612-617
taskqueue_drain_timeout(struct taskqueue *queue,
Link Here
|
612 |
TQ_UNLOCK(queue); |
614 |
TQ_UNLOCK(queue); |
613 |
} |
615 |
} |
614 |
|
616 |
|
|
|
617 |
void |
618 |
taskqueue_quiesce(struct taskqueue *queue) |
619 |
{ |
620 |
int ret; |
621 |
|
622 |
TQ_LOCK(queue); |
623 |
do { |
624 |
ret = taskqueue_drain_tq_queue(queue); |
625 |
if (ret == 0) |
626 |
ret = taskqueue_drain_tq_active(queue); |
627 |
} while (ret != 0); |
628 |
TQ_UNLOCK(queue); |
629 |
} |
630 |
|
615 |
static void |
631 |
static void |
616 |
taskqueue_swi_enqueue(void *context) |
632 |
taskqueue_swi_enqueue(void *context) |
617 |
{ |
633 |
{ |