-
Notifications
You must be signed in to change notification settings - Fork 8.2k
Description
There were multiple experiences and reports from different people that enabling debug logging affects the behavior of non-trivial (e.g. time-sensitive code). That's because debug logging happens via printk(), which (by default) uses polled UART output. For typical 115200 UART speed, that means 11.5KB/s throughput, and then even for 10 char output, 1ms is spent in polling, and most of logging messages are times longer. Overall, such logging affects real-time code noticeably, usually masking any concurrency and subtle-timing issues.
So, we'd need to implement some kind of buffered output to alleviate this issue. There're 2 approaches to this:
- Implement interrupt-driven UART for printk, so logging output hopefully takes negligible (for many uses) amount of CPU time.
- Implement an in-memory buffer for output, with some adhoc support for flushing to the underlying output device (usually still UART), e.g. on buffer becoming full or using an API call a user will need to sprinkle in the code at appropriate places to get the output.
Both approaches has benefits and drawbacks:
-
Requires interrupt-driven UART, which is not supported on all platforms. One big benefit is that the output is still "realtime" (immediately visible to the user). Of course, there's a concern that on buffer overflow it'll stop being so, but that can be handled by configuring buffer size (to an arbitrary value, include tens and hundreds of KBs). This method still has non-zero overhead, so might affect tight realtime code.
-
The output is not visible to the user by default, so it's "collect and stop the world" approach. As such, it'll be much harder to use. At the same time, it's more compatible and allows to achieve absolutely minimal overhead during the "collection" phase.