Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 27 Jul 2005 08:48:57 +0200
From:      "Norbert Koch" <NKoch@demig.de>
To:        "Scott Long" <scottl@samsco.org>
Cc:        "Freebsd-Hackers@Freebsd. Org" <freebsd-hackers@freebsd.org>
Subject:   RE: await & asleep
Message-ID:  <001801c59277$432fd960$4801a8c0@ws-ew-3.W2KDEMIG>
In-Reply-To: <42E65A9F.4010504@samsco.org>

next in thread | previous in thread | raw e-mail | index | archive | help
> > 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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?001801c59277$432fd960$4801a8c0>