Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C printf() in interrupt handler?

I heard printf() in C is not supposed to be used in ISR. Is it because it's a blocking call, or is it because it's not re-entrant?

If printf() is not re-entrant, then wouldn't it means that it can not be used for multi-thread program as well, unless it's 'synchronized' in some way?

Thanks,

like image 802
user1559625 Avatar asked Oct 03 '12 07:10

user1559625


3 Answers

It shouldn't be in an ISR because it is not re-entrant nor thread-safe, but mainly because it is an extremely huge function which will lock up the whole program if you call it from an ISR, creating extreme interrupt jitter and instantly killing every hint of real-time performance in your program.

Huge, bombastic functions should not be in ISRs, no matter if they are thread-safe or not!

like image 125
Lundin Avatar answered Sep 29 '22 16:09

Lundin


I heard printf() in C is not supposed to be used in ISR. Is it because it's a blocking call, or is it because it's not re-entrant?

More precisely because printf() is not a async-signal-safe function. See the list of async-signal-safe at the bottom of Signal Concepts.

like image 31
Maxim Egorushkin Avatar answered Sep 29 '22 16:09

Maxim Egorushkin


I'm going to assume that you mean interrupts, even though interrupt handlers in kernels usually have much more special limitations. The same argument applies to signal handlers, but it's usually simpler than the special restrictions on interrupt handlers. In case my assumption is wrong just replace "interrupt" with "signal" in the answer and it will apply.

Functions can be thread-safe without being signal/interrupt safe. If the function protects its internal state with a lock and then holds that lock when getting an interrupt there is no way for the interrupt handler to acquire that lock since the execution path that holds the lock is blocked by the interrupt. To release the lock you'd have to exit from the interrupt handler, resume execution of the thread until the lock is released and then go back to the interrupt handler. This is typically not really doable unless your kernel has implemented interrupt handlers as threads that can yield execution when waiting for locks.

A normal way to make a function both interrupt and thread safe is to block interrupts while holding the lock, but this is quite expensive and isn't done unless it's very necessary.

like image 43
Art Avatar answered Sep 29 '22 16:09

Art