Add taskqueue_enqueue_timeout_sbt(), because sometimes you want more control

over the scheduling precision than 'ticks' can offer, and because sometimes
you're already working with sbintime_t units and it's dumb to convert them
to ticks just so they can get converted back to sbintime_t under the hood.
This commit is contained in:
Ian Lepore 2017-07-31 00:54:50 +00:00
parent b618318ae3
commit f37b7fc2d4
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=321743
3 changed files with 34 additions and 10 deletions

View File

@ -28,7 +28,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd March 1, 2016
.Dd July 30, 2017
.Dt TASKQUEUE 9
.Os
.Sh NAME
@ -82,6 +82,8 @@ struct timeout_task;
.Ft int
.Fn taskqueue_enqueue_timeout "struct taskqueue *queue" "struct timeout_task *timeout_task" "int ticks"
.Ft int
.Fn taskqueue_enqueue_timeout_sbt "struct taskqueue *queue" "struct timeout_task *timeout_task" "sbintime_t sbt" "sbintime_t pr" "int flags"
.Ft int
.Fn taskqueue_cancel "struct taskqueue *queue" "struct task *task" "u_int *pendp"
.Ft int
.Fn taskqueue_cancel_timeout "struct taskqueue *queue" "struct timeout_task *timeout_task" "u_int *pendp"
@ -211,8 +213,17 @@ is called on the task pointer passed to
.Pp
The
.Fn taskqueue_enqueue_timeout
is used to schedule the enqueue after the specified amount of
function is used to schedule the enqueue after the specified number of
.Va ticks .
The
.Fn taskqueue_enqueue_timeout_sbt
function provides finer control over the scheduling based on
.Va sbt ,
.Va pr ,
and
.Va flags ,
as detailed in
.Xr timeout 9 .
Only non-fast task queues can be used for
.Va timeout_task
scheduling.
@ -483,6 +494,7 @@ be created with a dedicated processing thread.
.Xr ithread 9 ,
.Xr kthread 9 ,
.Xr swi 9
.Xr timeout 9
.Sh HISTORY
This interface first appeared in
.Fx 5.0 .

View File

@ -289,8 +289,8 @@ taskqueue_timeout_func(void *arg)
}
int
taskqueue_enqueue_timeout(struct taskqueue *queue,
struct timeout_task *timeout_task, int ticks)
taskqueue_enqueue_timeout_sbt(struct taskqueue *queue,
struct timeout_task *timeout_task, sbintime_t sbt, sbintime_t pr, int flags)
{
int res;
@ -304,7 +304,7 @@ taskqueue_enqueue_timeout(struct taskqueue *queue,
/* Do nothing */
TQ_UNLOCK(queue);
res = -1;
} else if (ticks == 0) {
} else if (sbt == 0) {
taskqueue_enqueue_locked(queue, &timeout_task->t);
/* The lock is released inside. */
} else {
@ -313,18 +313,27 @@ taskqueue_enqueue_timeout(struct taskqueue *queue,
} else {
queue->tq_callouts++;
timeout_task->f |= DT_CALLOUT_ARMED;
if (ticks < 0)
ticks = -ticks; /* Ignore overflow. */
if (sbt < 0)
sbt = -sbt; /* Ignore overflow. */
}
if (ticks > 0) {
callout_reset(&timeout_task->c, ticks,
taskqueue_timeout_func, timeout_task);
if (sbt > 0) {
callout_reset_sbt(&timeout_task->c, sbt, pr,
taskqueue_timeout_func, timeout_task, flags);
}
TQ_UNLOCK(queue);
}
return (res);
}
int
taskqueue_enqueue_timeout(struct taskqueue *queue,
struct timeout_task *ttask, int ticks)
{
return (taskqueue_enqueue_timeout_sbt(queue, ttask, ticks * tick_sbt,
0, 0));
}
static void
taskqueue_task_nop_fn(void *context, int pending)
{

View File

@ -79,6 +79,9 @@ int taskqueue_start_threads_cpuset(struct taskqueue **tqp, int count,
int taskqueue_enqueue(struct taskqueue *queue, struct task *task);
int taskqueue_enqueue_timeout(struct taskqueue *queue,
struct timeout_task *timeout_task, int ticks);
int taskqueue_enqueue_timeout_sbt(struct taskqueue *queue,
struct timeout_task *timeout_task, sbintime_t sbt, sbintime_t pr,
int flags);
int taskqueue_poll_is_busy(struct taskqueue *queue, struct task *task);
int taskqueue_cancel(struct taskqueue *queue, struct task *task,
u_int *pendp);