RE: await & asleep

From: Norbert Koch (NKoch_at_demig.de)
Date: 07/27/05

  • Next message: loader: "Re: FreeBSD ported to the XBox!"
    To: "Scott Long" <scottl@samsco.org>
    Date: Wed, 27 Jul 2005 08:48:57 +0200
    
    

    > > The functions await() and asleep() in kern_synch.c
    > > are marked as EXPERIMENTAL/UNTESTED.
    > > Is this comment still valid? Does anyone have used
    > > those functions successfully? Should I better not
    > > use them in my device driver code for RELENG_4?
    > > How do I correctly cancel a request (as I should do
    > > according to the man page): "asleep (NULL, 0, NULL, 0)"?
    >
    > The await family was removed in 5.x and beyond, so trying to
    > use them in 4.x will make your driver very unportable. There
    > are better ways than await to handle delayed events.

    Ok, my [classical] situation is this:
     1. an interrupt handler writes into a queue
     2. a read function reading from the queue

    pseudo code using asleep()/await() (no error handling):

    read()
    {
            forever {
                    while ! empty_queue() {
                            uiomove(&uio, ...);
                            if (uio->uio_resid == 0) {
                                    return 0;
                            }
                    }
                    asleep(& read_queue, ...);
                    if (empty_queue ()) {
                            error = await (...);
                    } else {
                            asleep (NULL, ...);
                    }
            }
    }

    If I want to do that with plain tsleep() I
    have to use spl??() to lock the empty_queue() call
    and not lose a wakeup() from the interrupt handler.
    But if I add error checks the code becomes very ugly
    compared to the solution above.

    I never wrote a driver under 5.X. As I understand
    I would use a mutex to access the queue and call msleep()
    to sleep with the mutex unlocked. (That seems to simulate
    pthread_cond_timedwait(), doesn't it?)

    pseudo code:

    read()
    {
            forever {
                    while ! empty_queue() {
                            uiomove(&uio, ...);
                            if (uio->uio_resid == 0) {
                                    return 0;
                            }
                    }
                    mtx_lock (&mutex);
                    if (empty_queue ()) {
                            error = msleep (&queue, &mutex, ...);
                    };
                    mtx_unlock (&mutex);
            }
    }

    How would you suggest to do that under 4.X
    in an _elegant_ way w/o asleep/await?

    Norbert
    _______________________________________________
    freebsd-hackers@freebsd.org mailing list
    http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
    To unsubscribe, send any mail to "freebsd-hackers-unsubscribe@freebsd.org"


  • Next message: loader: "Re: FreeBSD ported to the XBox!"

    Relevant Pages