Use the logging queue to buffer logs

This reduces context switches and mutex contention a lot, which reduces
roboRIO CPU usage significantly.

Change-Id: I21c0f7c127df36bf877133c626cff3d56b93b230
diff --git a/aos/common/logging/BUILD b/aos/common/logging/BUILD
index adddb4b..d4d3ca5 100644
--- a/aos/common/logging/BUILD
+++ b/aos/common/logging/BUILD
@@ -52,6 +52,7 @@
     '//aos/common:die',
     ':binary_log_file',
     '//aos/common:queue_types',
+    '//aos/common:time',
   ],
 )
 
diff --git a/aos/common/logging/binary_log_writer.cc b/aos/common/logging/binary_log_writer.cc
index 56949b5..10641fb 100644
--- a/aos/common/logging/binary_log_writer.cc
+++ b/aos/common/logging/binary_log_writer.cc
@@ -21,6 +21,7 @@
 #include "aos/linux_code/ipc_lib/queue.h"
 #include "aos/common/queue_types.h"
 #include "aos/common/die.h"
+#include "aos/common/time.h"
 
 namespace aos {
 namespace logging {
@@ -206,8 +207,16 @@
 
   while (true) {
     const LogMessage *const msg =
-        static_cast<const LogMessage *>(queue->ReadMessage(RawQueue::kBlock));
-    if (msg == NULL) continue;
+        static_cast<const LogMessage *>(queue->ReadMessage(RawQueue::kNonBlock));
+    if (msg == NULL) {
+      // If we've emptied the queue, then wait for a bit before starting to read
+      // again so the queue can buffer up some logs. This avoids lots of context
+      // switches and mutex contention which happens if we're constantly reading
+      // new messages as they come in.
+      static constexpr auto kSleepTime = ::aos::time::Time::InSeconds(0.1);
+      ::aos::time::SleepFor(kSleepTime);
+      continue;
+    }
 
     const size_t raw_output_length =
         sizeof(LogFileMessageHeader) + msg->name_length + msg->message_length;
diff --git a/aos/common/logging/log_streamer.cc b/aos/common/logging/log_streamer.cc
index f214d99..ab37e02 100644
--- a/aos/common/logging/log_streamer.cc
+++ b/aos/common/logging/log_streamer.cc
@@ -31,13 +31,15 @@
          now.sec(), now.nsec());
 
   while (true) {
-    const LogMessage *const msg =
-        static_cast<const LogMessage *>(queue->ReadMessage(RawQueue::kBlock));
-    if (msg == NULL) continue;
+    const LogMessage *const msg = static_cast<const LogMessage *>(
+        queue->ReadMessage(RawQueue::kNonBlock));
+    if (msg == NULL) {
+      ::aos::time::SleepFor(::aos::time::Time::InSeconds(0.1));
+    } else {
+      internal::PrintMessage(stdout, *msg);
 
-    internal::PrintMessage(stdout, *msg);
-
-    queue->FreeMessage(msg);
+      queue->FreeMessage(msg);
+    }
   }
 
   Cleanup();