This is the mail archive of the ecos-discuss@sources.redhat.com mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: sscanf() vs. fgetc()


Hi Peter,

Peter Graf <p.graf@itknet.de> writes:

> Hi,
> 
> after problems in a large context, I have cut things down to a short
> example for a phenomenon I can't explain myself.
> 
> I create and resume a new thread which uses fgetc() on a serial port, in an
> infinite loop. 
> This new thread has a higher priority than the old one.
> If no characters are received, fgetc blocks and the old thread continues.
> 
> So far so good.
> 
> But when I use sscanf() in the old thread, it hangs.
> Even if the new process completes fgetc(), because characters are received,
> the old process won't get any further.

I suppose that only one thread at a time can read characters from a serial
port. When a thread wants to read, it probably has to obtain a mutex, then it
checks a condition such as input buffer not empty or waits on a condition
variable bound to this condition. When some characters come in, the condition
variable gets signalled and the thread with the higher priority runs and
consumes the available characters. Therefore, another thread with a lower
priority will never get a chance to see a non-empty buffer, or in one word:
starvation.

> My first explanation was, that fgetc() might poll and doesn't allow to
> schedule lower priority threads. Obviously, this was wrong, because the old
> thread runs fine, as long as it doesn't use sscanf(), even if it calls C
> Library functions like sprintf().
> 
> My second explanation was that there might be a resource conflict between
> fgetc() and sscanf(). (I have no idea why there should be such a conflict!)
> So I placed a scheduler lock around sscanf(). It still hangs. (And the
> higher priority task as well.)
> 
> I found two ways to keep sscanf() from hanging, which is giving the fgetc()
> thread a lower priority, or add a cyg_thread_delay() after the fgetc().

This confirms the hypothesis above.

Robin


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]