quarks::service::Logger now takes a Semaphore during the call to LoggerImpl::send() so that log messages from different tasks don't get mixed together. Class LoggerImpl is much simplified in that all formatting, severity level filtering and synchronization are done elsewhere.
Logger().aboveThreshold(severity-level) will return true
if messages of level severity-level are being logged. This allows you to skip debug-printout code that's more complex than a simple series of logging calls.
Class quarks::service::LogMessage may be used to assemble a log message a piece at a time instead of all in one logging call. The accumulated message is sent when the LogMessage instance being used is destroyed. This may happen at the end of a statement (temporary instance) or at the end of a code block (named instance).
In a module's main function construct an instance of quarks::service::InitLogging on the stack instead of calling Logging::initLogging() directly. When the function exits then logging will be gracefully shut down. An example of Resource Allocation Is Initialization (RAII).
These are tools and data structures used in aid of thread-safe programming. The first class added is CriticalSection, whose constructor takes a given Semaphore and whose destructor gives that semaphore, thereby creating a critical section that lasts as long as the instance does. Another example of RAII.
These are non-concurrent data structures. BitSet is a classic powerset defined in an unsigned int (32 bits). BitPq is a priority queue that returns in ascending order the bit positions of all the bits set in a Bitset.
A new version of quarks.pdf is attached to the Petacache Documentation page in Confluence.