|
|
|
#1 |
|
Messages: n/a
Hébergeur: |
Hi Everyone,
I had a query reg printf(). I heard that it can't be used in ISR's as it is non-re-enterant. I didn't get as to why printf is non-re-enterant and why non-re-enterant library can't be used in an ISR? Thanks in advance ! ! ! |
|
|
|
#2 |
|
Messages: n/a
Hébergeur: |
On 28 May 2008 at 12:27, Rahul wrote:
> I had a query reg printf(). I heard that it can't be used in ISR's as > it is non-re-enterant. I didn't get as to why printf is > non-re-enterant and why non-re-enterant library can't be used in an > ISR? I believe POSIX requires the functions that write to streams to be implemented in a re-entrant way (certainly this will be true if you're using threads)... In general I don't think the famous ANSI C Standard (praise be upon it!) insists on it. It's easy to imagine an implementation of printf() that used a static internal buffer to build up the string before sending it to stdout, for example. If you call a non-reentrant function from an ISR, what if the code you interrupted was another call to the same function? You'd likely corrupt both the interrupted function's data and the data in the function called by your ISR. In any case, calling printf() in an ISR is almost certainly a mistake, reentrant or not. Latency considerations mean that you really don't want to be calling big bloated functions like printf() inside an ISR - you would be blocking further interrupts for far too long. |
|
|
|
#3 |
|
Messages: n/a
Hébergeur: |
Antoninus Twink wrote:
> On 28 May 2008 at 12:27, Rahul wrote: >> I had a query reg printf(). I heard that it can't be used in ISR's as >> it is non-re-enterant. I didn't get as to why printf is >> non-re-enterant and why non-re-enterant library can't be used in an >> ISR? > > I believe POSIX requires the functions that write to streams to be > implemented in a re-entrant way <off-topic> You believe incorrectly. </off-topic> > (certainly this will be true if you're > using threads)... <off-topic> Wrong again. </off-topic> > In general I don't think the famous ANSI C Standard > (praise be upon it!) insists on it. In fact, there's an explicit warning to the contrary. > It's easy to imagine an > implementation of printf() that used a static internal buffer to build > up the string before sending it to stdout, for example. The buffer needn't be static; its mere existence is enough to doom re-entrancy. -- Eric Sosman esosman@ieee-dot-org.invalid |
|
|
|
#4 |
|
Messages: n/a
Hébergeur: |
>
> > It's easy to imagine an > > implementation of printf() that used a static internal buffer to build > > up the string before sending it to stdout, for example. > > The buffer needn't be static; its mere existence is > enough to doom re-entrancy. > What is the buffer is allocated on heap or declared as a local varaible? |
|
|
|
#5 |
|
Messages: n/a
Hébergeur: |
Rahul wrote:
>>> It's easy to imagine an >>> implementation of printf() that used a static internal buffer to build >>> up the string before sending it to stdout, for example. >> The buffer needn't be static; its mere existence is >> enough to doom re-entrancy. >> > > What is the buffer is allocated on heap or declared as a local > varaible? (I guess you mean "what if.") Wherever the buffer resides, characters destined for output must pass through it. If it's statically allocated or dynamically allocated, both the interrupted and the interrupting activity need to deposit characters in it, update a where-does-the-next-character-go indicator, and decide whether to flush the contents. Unless all that can be done uninterruptably, printf() is non-reentrant. I hadn't considered an `auto' buffer, because it would go out of existence when printf() returned to its caller. It's possible that a printf() implementation could use such a buffer, filling it during the call and draining it just before the return. If it did so -- and if all the machinery of draining the buffer to stdout was also re-entrant -- then the worst that would happen would be that the output from the interrupting printf() could appear in the middle of a bunch of output from the interrupted printf(): Helloinvalid sense word 0xbadd , world! But that's an uncomfortably long chain of "ifs" to rely on, especially since such a buffer is not the kind whose use is suggested by the setbuf() and setvbuf() functions. (The implementation need not "do anything" in response to those calls, but their existence hints at a buffering regime that uses longer-lived buffers.) -- Eric Sosman esosman@ieee-dot-org.invalid |
|
|
|
#6 |
|
Messages: n/a
Hébergeur: |
Rahul <sam_cit@yahoo.co.in> wrote:
> > > It's easy to imagine an > > > implementation of printf() that used a static internal buffer to build > > > up the string before sending it to stdout, for example. > > > > The buffer needn't be static; its mere existence is > > enough to doom re-entrancy. > > What is the buffer is allocated on heap or declared as a local > varaible? A non-static local variable shouldn't pose a problem. But static (even local) variables aren't safe. If a call of printf() gets interrupted by an ISR (or a signal or what- ever asynchronous events there could be) and the handler function itself uses printf() then a static buffer may get overwritten by this new call and left in a state so that it can't be used safely anymore by the original call of printf() to which the program finally will get back. But it's not only a problem with a static buffers. printf() also could call malloc() and when, during the execution of malloc() an asynchronous handler gets in- voked that also calls malloc() or some related function directly or indirectly, the whole memory allocation sys- tem can get into a random state. Strange and nearly im- possible to reproduce bugs would rather likely be the result. So better check each and every function you use in a handler for an asynchronous event that it is expli- citely documented to be safe to use under such circum- stances. That not means just thread-safety since in threads the implementors can employ locking schemes etc., you need functions that are safe for use in signal hand- lers. If a function isn't assume that it can't be used. Regards, Jens -- \ Jens Thoms Toerring ___ jt@toerring.de \__________________________ http://toerring.de |
|
|
|
#7 |
|
Messages: n/a
Hébergeur: |
On May 28, 6:52 pm, Eric Sosman <esos...@ieee-dot-org.invalid> wrote:
> Rahul wrote: > >>> It's easy to imagine an > >>> implementation of printf() that used a static internal buffer to build > >>> up the string before sending it to stdout, for example. > >> The buffer needn't be static; its mere existence is > >> enough to doom re-entrancy. > > > What is the buffer is allocated on heap or declared as a local > > varaible? > > (I guess you mean "what if.") > > Wherever the buffer resides, characters destined for > output must pass through it. If it's statically allocated > or dynamically allocated, both the interrupted and the > interrupting activity need to deposit characters in it, > update a where-does-the-next-character-go indicator, and > decide whether to flush the contents. Unless all that can > be done uninterruptably, printf() is non-reentrant. > > I hadn't considered an `auto' buffer, because it would > go out of existence when printf() returned to its caller. > It's possible that a printf() implementation could use such > a buffer, filling it during the call and draining it just > before the return. If it did so -- and if all the machinery > of draining the buffer to stdout was also re-entrant -- then > the worst that would happen would be that the output from > the interrupting printf() could appear in the middle of a > bunch of output from the interrupted printf(): > > Helloinvalid sense word 0xbadd > , world! > > But that's an uncomfortably long chain of "ifs" to rely on, > especially since such a buffer is not the kind whose use is > suggested by the setbuf() and setvbuf() functions. (The > implementation need not "do anything" in response to those > calls, but their existence hints at a buffering regime that > uses longer-lived buffers.) > > -- > Eric Sosman > esos...@ieee-dot-org.invalid If i'm correct, the ISR runs as a part of the operating system (kernel task) and other tasks might call printf function. Lets assume this version of printf uses a static buffer or a global buffer. In any case, wouldn't the printf get linked into both these tasks? Wouldn't both these tasks have their own version of the static or global variable? If so, then i don't see any reason for conflict, (yes, it might be a problem in multi-threaded task). Also that it wouldn't matter if printf is implemented as a static or dynamic library? Thanks in advance ! ! ! |
|
|
|
#8 |
|
Messages: n/a
Hébergeur: |
Rahul wrote:
> > If i'm correct, the ISR runs as a part of the operating system (kernel > task) and other tasks might call printf function. Lets assume this > version of printf uses a static buffer or a global buffer. In any > case, wouldn't the printf get linked into both these tasks? > Wouldn't both these tasks have their own version of the static or > global variable? The situation is far outside the scope of the C language. In C there is no such thing as an "ISR" and there is only one "task." Your questions aren't about C, but about specific environments in which C can be used. And the answers will be different[*] in different environments: An ISR in a Linux system will have different conventions and constraints than an ISR in Windows or in OS/390 or in your cell phone, even if all these ISRs are written in C. [*] Well, maybe not. I predict, with a confidence level exceeding ninety percent, that the answer to "Is it safe to call printf() in an ISR" will be "No," even though the reasons behind the "No" will differ. > If so, then i don't see any reason for conflict, (yes, it might be > a problem in multi-threaded task). Also that it wouldn't matter if > printf is implemented as a static or dynamic library? C has no notion of a static library or a dynamic library. All it knows about are functions and data, and about some kind of "linkage" that pulls a bunch of them together into a running program. If you need information about the details of how different systems accomplish this, you are asking not about C but about those systems. -- Eric.Sosman@sun.com |
|
![]() |
| Outils de la discussion | |
|
|