[Debug] implement logging to a memory-mapped log file
When setting the environment variable EMPER_LOG_FILE=<logfile>
EMPER
will write its log messages to <logfile>
instead of stderr.
This removes the need for the mutex protecting std::cerr
as well as
multiple write calls to flush std:cerr
.
To efficiently write log messages to the log file the algorithm uses three memory mapped views into to store the log messages. One buffer is active, one is new, and one is old. The next buffer ensures that threads can write log messages even if the active buffer would overflows. The old buffer allows slower threads to still write safely while everyone else uses the active buffer. When a thread changes from the active buffer to the new buffer it is responsible to renew the current old buffer and changing the semantic of the buffers:
- active -> old
- next -> active
- old -> next
This buffer scheme allows wait-free logging. But the approach is NOT sound because delayed thread may still use the old buffer which gets renewed by the first thread touching the next buffer. But the likeliness for this situation decreases with bigger sizes of the buffers.
ATTENTION: Using SCHED_IDLE for the completer may break this likeliness assumption.