Date: Mon, 4 Dec 1995 21:58:03 +1100 From: Bruce Evans <bde@zeta.org.au> To: bde@zeta.org.au, witr@rwwa.com Cc: freebsd-hackers@freebsd.org Subject: Re: Proper way to determine non-blocking status... Message-ID: <199512041058.VAA03902@godzilla.zeta.org.au>
next in thread | raw e-mail | index | archive | help
>Do you mind if I pepper you with some more questions?
Perhaps these should be added to the NFAQ :-).
>1) Is there any guidance on what priority pass to tsleep?
It doesn't matter much. Normally use something between
PZERO and PUSER, and OR in PCATCH for interruptible
sleeps.
>2) Would I be correct in assuming that IPL will be the
>same *after* tsleep returns as it was *before*. (I'm
>already pretty sure of that, reading the code. It makes
>sense anyway.)
Yes.
>3) Is there anyway short of using timeout() to hook
>into the clock interrupt (like xxpoll() in SYSV)?
No. Restart the timeout when the timeout handler gets
called (or when it returns).
>4) I'm porting a streams driver to FreeBSD. It isn't
>a network style device, so I need to use the character
>dev model. The backend (and parts of the frontend)
>construct and enqueue messages to pass to the user
>when he eventually does a read. I need to alloc
>memory for each of these messages (which have random
>sizes, from dozens of bytes up to 1024 bytes). I'm curently
>using malloc(size,M_DEVBUF,waitflag). Is there better
>way to do this?
Not unless you can use mbufs. Don't depend on mallocing more
than a page or two (1024 bytes is OK). Don't call malloc()
from interrupt handlers except for network drivers. Be
careful about using the M_WAITOK flag - it allows malloc()
to sleep, so you probably wouldn't want to use it while
spl'ed. Don't manage a large pool of free buffers yourself.
One or two might be good.
>5) Are there any ipl restrictions on calling wakeup()?
No.
>6) Where does device ipl come from? I don't see it in the
>config file? How do I know what ipl my device interrupts
>at?
It is tty_imask for ttys etc, where ttys are the things
specified by the keyword `tty' in the config file and the
mask is the OR of the hardware masks for each tty device
together with a few software masks. This will change.
>7) xxintr(int unit). Which unit? How computed? I'm used
>to xxintr(int vec).
unit = intr_unit[vec]. intr_unit[] is initialized by
register_intr(), normally to the unit numbers specified in
the config file. This will change to xxintr(void *cookie)
where cookie is normally (void *)&xxdriverstuff[unit].
>8) I see that people often avoid having xxread/xxwrite routines
>for this situation. I did the opposite: I have xxread/xxwrite
>routines and require the stuff sent to be protocol packets.
>Is there any major drawback to this besides the possiblity
>of having some butthead do ``cat /etc/passwd /dev/mcc''?
No.
>Actual routine is:
>int mccread(dev_t dev, struct uio *uio, int ioflag)
>{
> mcc_t *mcc = MCC_DEV(dev); /* Private data for this channel */
> mcc_mblk_t *mp;
> int oldspl;
> /* Send first accumulated message, or wait if possible */
> again:
> oldspl = SPLINT(); /* Lock */
> mp = l_remove_head(&mcc->mcc_done); /* Get anything there */
> if (mp) { /* Return it */
> mc_primitives_union_t *mcp = MCC_MBLK_DATA(mp);
> if (mcp->header.mc_length > uio->uio_resid) {
> /*
> We refuse to copy less than a complete message,
> so we requeue this one!
> */
> l_add_head(&mcc->mcc_done,mp); /* Return it to head of list */
> splx(oldspl); /* Unlock */
> return EINVAL;
> } else {
> splx(oldspl); /* Unlock */
> uiomove(mcp, mcp->header.mc_length, uio);
^^^^^^^ check the return code - it can be EFAULT...
> free(mp,M_DEVBUF);
> return 0;
> }
> } else if (ioflag & IO_NDELAY) { /* Can't block, sorry */
> splx(oldspl); /* Unlock */
> return EWOULDBLOCK;
> } else { /* Otherwise try again */
> int error;
> mcc->mcc_blocked = 1; /* Mark ourselves blocked */
> error = tsleep(&mcc->mcc_done, PZERO | PCATCH, "mccin", 0);
> mcc->mcc_blocked = 0; /* Mark ourselves unblocked */
> splx(oldspl); /* Unlock */
> if (error && (error != ERESTART)) return error;
> goto again;
> }
>}
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199512041058.VAA03902>
