From owner-freebsd-arch Fri May 12 12:40:33 2000 Delivered-To: freebsd-arch@freebsd.org Received: from anchor-post-33.mail.demon.net (anchor-post-33.mail.demon.net [194.217.242.91]) by hub.freebsd.org (Postfix) with ESMTP id 31E0537BF24 for ; Fri, 12 May 2000 12:40:21 -0700 (PDT) (envelope-from dfr@nlsystems.com) Received: from nlsys.demon.co.uk ([158.152.125.33] helo=herring.nlsystems.com) by anchor-post-33.mail.demon.net with esmtp (Exim 2.12 #1) id 12qLIC-0002A2-0X for arch@freebsd.org; Fri, 12 May 2000 20:40:12 +0100 Received: from salmon.nlsystems.com (salmon.nlsystems.com [10.0.0.3]) by herring.nlsystems.com (8.9.3/8.8.8) with ESMTP id UAA12729 for ; Fri, 12 May 2000 20:43:59 +0100 (BST) (envelope-from dfr@nlsystems.com) Date: Fri, 12 May 2000 20:44:39 +0100 (BST) From: Doug Rabson To: arch@freebsd.org Subject: A new api for asynchronous task execution Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: owner-freebsd-arch@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG 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 #include #include 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