From mboxrd@z Thu Jan 1 00:00:00 1970 From: Robin Farine To: Peter Graf Cc: ecos-discuss@sources.redhat.com Subject: Re: [ECOS] sscanf() vs. fgetc() Date: Thu, 12 Jul 2001 03:28:00 -0000 Message-id: <86sng24g1c.fsf@halftrack.hq.acn-group.ch> References: <3.0.5.32.20010712104805.00914420@128.128.128.220> X-SW-Source: 2001-07/msg00344.html Hi Peter, Peter Graf 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