Date: Fri, 12 May 2000 20:44:39 +0100 (BST) From: Doug Rabson <dfr@nlsystems.com> To: arch@freebsd.org Subject: A new api for asynchronous task execution Message-ID: <Pine.BSF.4.21.0005122041530.47945-100000@salmon.nlsystems.com>
next in thread | raw e-mail | index | archive | help
I'm planning to add a new system to the kernel which should make it much
easier for drivers (especially loadable drivers) to use software
interrupts to implement split-level interrupt handlers. The api was
inspired by the Linux tqueue system but the implementation is quite
different.
Here is the manpage for the new api. Comments welcome.
TASKQUEUE(9) FreeBSD Kernel Developer's Manual TASKQUEUE(9)
NAME
taskqueue - asynchronous task execution
SYNOPSIS
#include <sys/param.h>
#include <sys/queue.h>
#include <sys/taskqueue.h>
struct task {
STAILQ_ENTRY(task) link; /* link for queue */
int pending; /* count times task is queued */
void (*func)(void *, int); /* task handler */
void *arg; /* argument for handler */
};
struct taskqueue {
STAILQ_HEAD(, task) queue;
void (*enqueue)(struct taskqueue *queue);
};
void
taskqueue_init(struct taskqueue *queue,
void (*enqueue)(struct taskqueue *queue))
void
taskqueue_enqueue(struct taskqueue *queue, struct task *task)
void
taskqueue_run(struct taskqueue *queue)
DESCRIPTION
These functions provide a simple interface for asynchronous execution of
code. To add a task to the list of tasks queued on a taskqueue, call
taskqueue_enqueue() with pointers to the queue and task. If the task's
pending field is zero, the task is added to the end of the list and
pending is set to one, otherwise, pending is incremented.
When a task is enqueued, a taskqueue specific function, enqueue, is
called to allow the queue to arrange to be run later (for instance by
scheduling a software interrupt or waking a kernel thread). Enqueueing a
task does not perform any memory allocation which makes it suitable for
calling from an interrupt handler.
Before tasks can be added to a queue, it must first be initialised by
calling taskqueue_init() with the address of the queue and a function to
be called when tasks are queued.
To execute all the tasks on a queue, call taskqueue_run(). When a task
is executed, first it is removed from the queue, the value of pending is
recorded and the field is zeroed. The function func from the task struc-
ture is called with the value arg from the structure as its first argu-
ment and the value of pending as its second argument.
The system provides a global taskqueue, taskqueue_swi, which is run via a
software interrupt mechanism. To use this queue, call
taskqueue_enqueue() with the address of the global variable
taskqueue_swi. The queue will be run at splsofttq().
This queue can be used, for instance, for implementing interrupt handlers
which must perform a significant amount of processing in the handler.
The hardware interrupt handler would perform minimal processing of the
interrupt and then enqueue a task to finish the work. This reduces the
amount of time spent with interrupts disabled to a minimum.
HISTORY
This interface first appeared in FreeBSD 5.0. There is a similar facili-
ty called tqueue in the Linux kernel.
AUTHORS
This man page was written by Doug Rabson.
FreeBSD May 12, 2000 2
--
Doug Rabson Mail: dfr@nlsystems.com
Nonlinear Systems Ltd. Phone: +44 20 8442 9037
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-arch" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.4.21.0005122041530.47945-100000>
