From: Gary Thomas <gthomas@cygnus.co.uk>
To: Mohammed Illyas Mansoor <mansoor@cdotb.ernet.in>
Cc: jskov@cynus.co.uk.cdotb.ernet.in, ecos-discuss@sourceware.cygnus.com
Subject: RE: [ECOS] probable bug in io/serial/common/serial.c!
Date: Wed, 05 Jan 2000 05:36:00 -0000 [thread overview]
Message-ID: <XFMail.000105063515.gthomas@cygnus.co.uk> (raw)
In-Reply-To: <3872E206.67E7B0E5@cdotb.ernet.in>
I don't think there is a chance for deadlock here since the affected
region [while (size > 0)] is protected by a "DSR lock". The call to
'cyg_drv_dsr_lock()' effectively says "don't allow DSRs to run while
executing the following code". Since it is only the DSR that can
signal the condition variable, this should be safe.
On 05-Jan-00 Mohammed Illyas Mansoor wrote:
> Hi,
> I was going through the common serial io code it seems to me
> that there probably is a bug in it, below is a snap shot of the code
> in question.
>
> <snap>
> static Cyg_ErrNo
> serial_write(cyg_io_handle_t handle, const void *_buf, cyg_uint32 *len)
> {
> cyg_devtab_entry_t *t = (cyg_devtab_entry_t *)handle;
> serial_channel *chan = (serial_channel *)t->priv;
> serial_funs *funs = chan->funs;
> cyg_int32 size = *len;
> cyg_uint8 *buf = (cyg_uint8 *)_buf;
> int next;
> cbuf_t *cbuf = &chan->out_cbuf;
> Cyg_ErrNo res = ENOERR;
>
> cbuf->abort = false;
> cyg_drv_mutex_lock(&cbuf->lock);
> if (cbuf->len == 0) {
> // Non interrupt driven (i.e. polled) operation
> while (size-- > 0) {
> while ((funs->putc)(chan, *buf) == false) ; // Ignore full,
> keep trying
> buf++;
> }
> } else {
> cyg_drv_dsr_lock(); // Avoid race condition testing pointers
> while (size > 0) {
> next = cbuf->put + 1;
> if (next == cbuf->len) next = 0;
> if (next == cbuf->get) {
> cbuf->waiting = true;
> // Buffer full - wait for space
> (funs->start_xmit)(chan); // Make sure xmit is running
> cbuf->pending += size; // Have this much more to send
> eventually]
> ***---->cyg_drv_cond_wait(&cbuf->wait);<-----***
> cbuf->pending -= size;
> if (cbuf->abort) {
> // Give up!
> cbuf->abort = false;
> cbuf->waiting = false;
> res = -EINTR;
> break;
> }
> } else {
> cbuf->data[cbuf->put++] = *buf++;
> cbuf->put = next;
> size--; // Only count if actually sent!
> }
> }
> cyg_drv_dsr_unlock();
> (funs->start_xmit)(chan); // Start output as necessary
> }
> cyg_drv_mutex_unlock(&cbuf->lock);
> return res;
> }
> </snap>
>
> In the line with ***--->cyg_drv_cond_wait(&cond_wait);<----***,
> will cause a deadlock, because before going for a wait on the condition
> variable
> start_xmt function is called which will trigger the transmitter to send
> the char's, if the call to xmt_char finds out that chan->waiting is true
>
> and wakes up the writer thread which was supposed to be waiting by now,
> he would also change the chan->waiting to false. Later, when the wait by
>
> the writer is called there will be no waking up of the writer by the
> driver
> (as it has been already done by the xmt_char() ), causing it to
> deadlock.
>
> The fix might be as below,
>
> if (next == cbuf->get) {
> cbuf->waiting = true;
> // Buffer full - wait for space
> (funs->start_xmit)(chan); // Make sure xmit is running
> cbuf->pending += size; // Have this much more to send
> [eventually]
> ++if ( cbuf->waiting == true)
> cyg_drv_cond_wait(&cbuf->wait);
>
>
> --With Regards,
>
> M. I. Mansoor.
>
next prev parent reply other threads:[~2000-01-05 5:36 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2000-01-04 22:17 Mohammed Illyas Mansoor
2000-01-05 5:36 ` Gary Thomas [this message]
2000-01-05 6:34 ` Mohammed Illyas Mansoor
2000-01-05 6:50 ` Gary Thomas
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=XFMail.000105063515.gthomas@cygnus.co.uk \
--to=gthomas@cygnus.co.uk \
--cc=ecos-discuss@sourceware.cygnus.com \
--cc=jskov@cynus.co.uk.cdotb.ernet.in \
--cc=mansoor@cdotb.ernet.in \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).