Subject: Re: Synchronization with locks in kernel
To: None <>
From: Ben Harris <>
List: tech-kern
Date: 06/22/2003 15:01:19
In article <> you write:
>So i want to block inside client's code waiting for some external
>asynchronous event [hardware interrupt in my case].
>I have tried to do this with tsleep()/wakeup() synchronization calls like
>void dev_interrupt_handler(void *aux) {
>    struct dev_softc *sc =3D aux;
>    wakeup(sc);
>dev_do_something() {
>    struct dev_softc *sc = device_lookup().
>    dev_request_interrupt(sc);    /* 1 */
>    print("tralala\n");           /* 2 */
>    tsleep(sc);                   /* 3 */
>...but [obviously] i do loose interrupts when interrupt is occured fast
>enough i.e. between points 1 and 3 so tsleep(sc) is blocked too late and
>for nothing.

The usual way around this is to block interrupts in that period, so you'd do
something like:

dev_do_something() {
    struct dev_softc *sc = device_lookup();
    int s;

    s = spldev();

where spldev() is whatever spl*() function is correct for your device, which
depends on the level at which you established your interrupt handler. 
tsleep() handles saving and restoring the interrupt level in a way that
won't lose wakeup()s.

In the modern, SMP-capable world, you might want to use locks, but I'll
leave them to someone else to explain, as I've never written a device driver
using them.

Ben Harris                                                   <>
Portmaster, NetBSD/acorn26           <URL:>