taskq: add taskq_try_dispatch_ent()
Non-blocking form of taskq_dispatch_ent(), returns false if it can't acquire the taskq lock. Signed-off-by: Rob Norris <rob.norris@klarasystems.com>
This commit is contained in:
parent
2fec57bf03
commit
c85d31a88b
|
@ -91,6 +91,8 @@ extern taskqid_t taskq_dispatch_delay(taskq_t *, task_func_t, void *,
|
||||||
uint_t, clock_t);
|
uint_t, clock_t);
|
||||||
extern void taskq_dispatch_ent(taskq_t *, task_func_t, void *, uint_t,
|
extern void taskq_dispatch_ent(taskq_t *, task_func_t, void *, uint_t,
|
||||||
taskq_ent_t *);
|
taskq_ent_t *);
|
||||||
|
extern boolean_t taskq_try_dispatch_ent(taskq_t *, task_func_t, void *, uint_t,
|
||||||
|
taskq_ent_t *);
|
||||||
extern int taskq_empty_ent(taskq_ent_t *);
|
extern int taskq_empty_ent(taskq_ent_t *);
|
||||||
taskq_t *taskq_create(const char *, int, pri_t, int, int, uint_t);
|
taskq_t *taskq_create(const char *, int, pri_t, int, int, uint_t);
|
||||||
taskq_t *taskq_create_instance(const char *, int, int, pri_t, int, int, uint_t);
|
taskq_t *taskq_create_instance(const char *, int, int, pri_t, int, int, uint_t);
|
||||||
|
|
|
@ -146,6 +146,8 @@ extern taskqid_t taskq_dispatch_delay(taskq_t *, task_func_t, void *,
|
||||||
uint_t, clock_t);
|
uint_t, clock_t);
|
||||||
extern void taskq_dispatch_ent(taskq_t *, task_func_t, void *, uint_t,
|
extern void taskq_dispatch_ent(taskq_t *, task_func_t, void *, uint_t,
|
||||||
taskq_ent_t *);
|
taskq_ent_t *);
|
||||||
|
extern boolean_t taskq_try_dispatch_ent(taskq_t *, task_func_t, void *, uint_t,
|
||||||
|
taskq_ent_t *);
|
||||||
extern int taskq_empty_ent(taskq_ent_t *);
|
extern int taskq_empty_ent(taskq_ent_t *);
|
||||||
extern void taskq_init_ent(taskq_ent_t *);
|
extern void taskq_init_ent(taskq_ent_t *);
|
||||||
extern taskq_t *taskq_create(const char *, int, pri_t, int, int, uint_t);
|
extern taskq_t *taskq_create(const char *, int, pri_t, int, int, uint_t);
|
||||||
|
|
|
@ -503,6 +503,8 @@ extern taskqid_t taskq_dispatch_delay(taskq_t *, task_func_t, void *, uint_t,
|
||||||
clock_t);
|
clock_t);
|
||||||
extern void taskq_dispatch_ent(taskq_t *, task_func_t, void *, uint_t,
|
extern void taskq_dispatch_ent(taskq_t *, task_func_t, void *, uint_t,
|
||||||
taskq_ent_t *);
|
taskq_ent_t *);
|
||||||
|
extern boolean_t taskq_try_dispatch_ent(taskq_t *, task_func_t, void *, uint_t,
|
||||||
|
taskq_ent_t *);
|
||||||
extern int taskq_empty_ent(taskq_ent_t *);
|
extern int taskq_empty_ent(taskq_ent_t *);
|
||||||
extern void taskq_init_ent(taskq_ent_t *);
|
extern void taskq_init_ent(taskq_ent_t *);
|
||||||
extern void taskq_destroy(taskq_t *);
|
extern void taskq_destroy(taskq_t *);
|
||||||
|
|
|
@ -156,8 +156,8 @@ taskq_init_ent(taskq_ent_t *t)
|
||||||
t->tqent_flags = 0;
|
t->tqent_flags = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
taskq_dispatch_ent(taskq_t *tq, task_func_t func, void *arg, uint_t flags,
|
taskq_dispatch_ent_impl(taskq_t *tq, task_func_t func, void *arg, uint_t flags,
|
||||||
taskq_ent_t *t)
|
taskq_ent_t *t)
|
||||||
{
|
{
|
||||||
ASSERT(func != NULL);
|
ASSERT(func != NULL);
|
||||||
|
@ -170,7 +170,6 @@ taskq_dispatch_ent(taskq_t *tq, task_func_t func, void *arg, uint_t flags,
|
||||||
/*
|
/*
|
||||||
* Enqueue the task to the underlying queue.
|
* Enqueue the task to the underlying queue.
|
||||||
*/
|
*/
|
||||||
mutex_enter(&tq->tq_lock);
|
|
||||||
|
|
||||||
if (flags & TQ_FRONT) {
|
if (flags & TQ_FRONT) {
|
||||||
t->tqent_next = tq->tq_task.tqent_next;
|
t->tqent_next = tq->tq_task.tqent_next;
|
||||||
|
@ -184,9 +183,28 @@ taskq_dispatch_ent(taskq_t *tq, task_func_t func, void *arg, uint_t flags,
|
||||||
t->tqent_func = func;
|
t->tqent_func = func;
|
||||||
t->tqent_arg = arg;
|
t->tqent_arg = arg;
|
||||||
cv_signal(&tq->tq_dispatch_cv);
|
cv_signal(&tq->tq_dispatch_cv);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
taskq_dispatch_ent(taskq_t *tq, task_func_t func, void *arg, uint_t flags,
|
||||||
|
taskq_ent_t *t)
|
||||||
|
{
|
||||||
|
mutex_enter(&tq->tq_lock);
|
||||||
|
taskq_dispatch_ent_impl(tq, func, arg, flags, t);
|
||||||
mutex_exit(&tq->tq_lock);
|
mutex_exit(&tq->tq_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean_t
|
||||||
|
taskq_try_dispatch_ent(taskq_t *tq, task_func_t func, void *arg, uint_t flags,
|
||||||
|
taskq_ent_t *t)
|
||||||
|
{
|
||||||
|
if (!mutex_tryenter(&tq->tq_lock))
|
||||||
|
return (B_FALSE);
|
||||||
|
taskq_dispatch_ent_impl(tq, func, arg, flags, t);
|
||||||
|
mutex_exit(&tq->tq_lock);
|
||||||
|
return (B_TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
taskq_wait(taskq_t *tq)
|
taskq_wait(taskq_t *tq)
|
||||||
{
|
{
|
||||||
|
|
|
@ -411,6 +411,15 @@ taskq_dispatch_ent(taskq_t *tq, task_func_t func, void *arg, uint32_t flags,
|
||||||
taskqueue_enqueue(tq->tq_queue, &task->tqent_task);
|
taskqueue_enqueue(tq->tq_queue, &task->tqent_task);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean_t
|
||||||
|
taskq_dispatch_ent(taskq_t *tq, task_func_t func, void *arg, uint32_t flags,
|
||||||
|
taskq_ent_t *task)
|
||||||
|
{
|
||||||
|
/* XXX: implement me -- robn, 2023-10-23 */
|
||||||
|
taskq_dispatch_ent(tq, func, arg, flags, task);
|
||||||
|
return (B_TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
taskq_wait(taskq_t *tq)
|
taskq_wait(taskq_t *tq)
|
||||||
{
|
{
|
||||||
|
|
|
@ -673,17 +673,13 @@ out:
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(taskq_dispatch_delay);
|
EXPORT_SYMBOL(taskq_dispatch_delay);
|
||||||
|
|
||||||
void
|
static void
|
||||||
taskq_dispatch_ent(taskq_t *tq, task_func_t func, void *arg, uint_t flags,
|
taskq_dispatch_ent_impl(taskq_t *tq, task_func_t func, void *arg, uint_t flags,
|
||||||
taskq_ent_t *t)
|
taskq_ent_t *t)
|
||||||
{
|
{
|
||||||
unsigned long irqflags;
|
|
||||||
ASSERT(tq);
|
ASSERT(tq);
|
||||||
ASSERT(func);
|
ASSERT(func);
|
||||||
|
|
||||||
spin_lock_irqsave_nested(&tq->tq_lock, irqflags,
|
|
||||||
tq->tq_lock_class);
|
|
||||||
|
|
||||||
/* Taskq being destroyed and all tasks drained */
|
/* Taskq being destroyed and all tasks drained */
|
||||||
if (!(tq->tq_flags & TASKQ_ACTIVE)) {
|
if (!(tq->tq_flags & TASKQ_ACTIVE)) {
|
||||||
t->tqent_id = TASKQID_INVALID;
|
t->tqent_id = TASKQID_INVALID;
|
||||||
|
@ -694,7 +690,7 @@ taskq_dispatch_ent(taskq_t *tq, task_func_t func, void *arg, uint_t flags,
|
||||||
/* Dynamic taskq may be able to spawn another thread */
|
/* Dynamic taskq may be able to spawn another thread */
|
||||||
if (!(tq->tq_flags & TASKQ_DYNAMIC) ||
|
if (!(tq->tq_flags & TASKQ_DYNAMIC) ||
|
||||||
taskq_thread_spawn(tq) == 0)
|
taskq_thread_spawn(tq) == 0)
|
||||||
goto out2;
|
return;
|
||||||
flags |= TQ_FRONT;
|
flags |= TQ_FRONT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -734,11 +730,45 @@ out:
|
||||||
/* Spawn additional taskq threads if required. */
|
/* Spawn additional taskq threads if required. */
|
||||||
if (tq->tq_nactive == tq->tq_nthreads)
|
if (tq->tq_nactive == tq->tq_nthreads)
|
||||||
(void) taskq_thread_spawn(tq);
|
(void) taskq_thread_spawn(tq);
|
||||||
out2:
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
taskq_dispatch_ent(taskq_t *tq, task_func_t func, void *arg, uint_t flags,
|
||||||
|
taskq_ent_t *t)
|
||||||
|
{
|
||||||
|
unsigned long irqflags;
|
||||||
|
|
||||||
|
spin_lock_irqsave_nested(&tq->tq_lock, irqflags,
|
||||||
|
tq->tq_lock_class);
|
||||||
|
|
||||||
|
taskq_dispatch_ent_impl(tq, func, arg, flags, t);
|
||||||
|
|
||||||
spin_unlock_irqrestore(&tq->tq_lock, irqflags);
|
spin_unlock_irqrestore(&tq->tq_lock, irqflags);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(taskq_dispatch_ent);
|
EXPORT_SYMBOL(taskq_dispatch_ent);
|
||||||
|
|
||||||
|
boolean_t
|
||||||
|
taskq_try_dispatch_ent(taskq_t *tq, task_func_t func, void *arg, uint_t flags,
|
||||||
|
taskq_ent_t *t)
|
||||||
|
{
|
||||||
|
unsigned long irqflags;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XXX I don't _think_ losing _nested matters, because I think its
|
||||||
|
* only related to lockdep, and we don't have access to that anyway
|
||||||
|
* -- robn, 2023-10-23
|
||||||
|
*/
|
||||||
|
if (!spin_trylock_irqsave(&tq->tq_lock, irqflags))
|
||||||
|
return (B_FALSE);
|
||||||
|
|
||||||
|
taskq_dispatch_ent_impl(tq, func, arg, flags, t);
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&tq->tq_lock, irqflags);
|
||||||
|
|
||||||
|
return (B_TRUE);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(taskq_try_dispatch_ent);
|
||||||
|
|
||||||
int
|
int
|
||||||
taskq_empty_ent(taskq_ent_t *t)
|
taskq_empty_ent(taskq_ent_t *t)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue