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,

I have tried your program on my SA-1110 based target. I had to add a delay in
the first for loop (and fix both of them ;-)) so that the reader thread calls
fgetc() before the main thread calls sscanf(). It fails on my target as well.

However, there exists a link between fgetc() and sscanf() due to the
implementation of sscanf(). sscanf() uses a Cyg_StdioStream() that tries to
flush all the other streams at the beginning of its refill_read_buffer()
operation. In my case, this seems to cause the main thread to loop endlessly in
cyg_libc_stdio_flush_all_but() because stream->trylock_me() always fails.

The problem comes from the conjunction of Cyg_StdioStream::refill_read_buffer()
and cyg_libc_stdio_flush_all_but(). The former routine locks '*this' and calls
cyg_stdio_read() which finally blocks on a condition variable, waiting for
characters coming from the underlying device. Then, another thread with a higher
priority (lower value) calls sscanf() => cyg_libc_stdio_flush_all_but() which
spins trying to flush the other (locked) stream and thus does not give the CPU
back to the lower priority thread in order to unlock the stream (provided the
stream has some characters to consume).

Not a very clear picture but I hope it will help more than my first message on
this subject.

Robin


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