worked more on testing/commenting/etc

I added some more tests, some more prints to verify test coverage, and
some more asserts to make sure things aren't broken.
diff --git a/aos/linux_code/ipc_lib/queue.cc b/aos/linux_code/ipc_lib/queue.cc
index e02df30..8103b6e 100644
--- a/aos/linux_code/ipc_lib/queue.cc
+++ b/aos/linux_code/ipc_lib/queue.cc
@@ -63,6 +63,7 @@
 // TODO(brians) maybe do this with atomic integer instructions so it doesn't
 //   have to lock/unlock pool_lock_
 void RawQueue::DecrementMessageReferenceCount(const void *msg) {
+  // TODO(brians): Test this function.
   MutexLocker locker(&pool_lock_);
   MessageHeader *header = MessageHeader::Get(msg);
   --header->ref_count;
@@ -227,6 +228,7 @@
 }
 
 bool RawQueue::WriteMessage(void *msg, int options) {
+  // TODO(brians): Test this function.
   if (kWriteDebug) {
     printf("queue: %p->WriteMessage(%p, %x)\n", this, msg, options);
   }
@@ -327,9 +329,10 @@
   }
   return true;
 }
-void *RawQueue::ReadPeek(int options, int start) {
+void *RawQueue::ReadPeek(int options, int start) const {
   void *ret;
   if (options & kFromEnd) {
+    // TODO(brians): Test this block with ReadMessageIndex.
     int pos = data_end_ - 1;
     if (pos < 0) {  // if it needs to wrap
       pos = data_length_ - 1;
@@ -339,6 +342,7 @@
     }
     ret = data_[pos];
   } else {
+    assert(start != -1);
     if (kReadDebug) {
       printf("queue: %p reading from line %d: %d\n", this, __LINE__, start);
     }
@@ -352,6 +356,7 @@
   return ret;
 }
 const void *RawQueue::ReadMessage(int options) {
+  // TODO(brians): Test this function.
   if (kReadDebug) {
     printf("queue: %p->ReadMessage(%x)\n", this, options);
   }
@@ -425,48 +430,55 @@
   // Where we're going to start reading.
   int my_start;
 
-  const int unread_messages = messages_ - *index;
-  assert(unread_messages > 0);
-  int current_messages = data_end_ - data_start_;
-  if (current_messages < 0) current_messages += data_length_;
-  if (kReadIndexDebug) {
-    printf("queue: %p start=%d end=%d current=%d\n",
-           this, data_start_, data_end_, current_messages);
-  }
-  assert(current_messages > 0);
-  // If we're behind the available messages.
-  if (unread_messages > current_messages) {
-    // Catch index up to the last available message.
-    *index = messages_ - current_messages;
-    // And that's the one we're going to read.
-    my_start = data_start_;
-    if (kReadIndexDebug) {
-      printf("queue: %p jumping ahead to message %d (have %d) (at %d)\n",
-             this, *index, messages_, data_start_);
-    }
+  if (options & kFromEnd) {
+    my_start = -1;
   } else {
-    // Just start reading at the first available message that we haven't yet
-    // read.
-    my_start = data_end_ - unread_messages;
+    const int unread_messages = messages_ - *index;
+    assert(unread_messages > 0);
+    int current_messages = data_end_ - data_start_;
+    if (current_messages < 0) current_messages += data_length_;
     if (kReadIndexDebug) {
-      printf("queue: %p original read from %d\n", this, my_start);
+      printf("queue: %p start=%d end=%d current=%d\n",
+             this, data_start_, data_end_, current_messages);
     }
-    if (data_start_ < data_end_) {
-      assert(my_start >= data_start_);
+    assert(current_messages > 0);
+    // If we're behind the available messages.
+    if (unread_messages > current_messages) {
+      // Catch index up to the last available message.
+      *index = messages_ - current_messages;
+      // And that's the one we're going to read.
+      my_start = data_start_;
+      if (kReadIndexDebug) {
+        printf("queue: %p jumping ahead to message %d (have %d) (at %d)\n",
+               this, *index, messages_, data_start_);
+      }
     } else {
-      if (my_start < 0) my_start += data_length_;
+      // Just start reading at the first available message that we haven't yet
+      // read.
+      my_start = data_end_ - unread_messages;
+      if (kReadIndexDebug) {
+        printf("queue: %p original read from %d\n", this, my_start);
+      }
+      if (data_start_ < data_end_) {
+        assert(my_start >= data_start_);
+      } else {
+        if (my_start < 0) my_start += data_length_;
+      }
     }
   }
 
-  // TODO(brians): Test kPeek and kFromEnd.
   if (options & kPeek) {
     msg = ReadPeek(options, my_start);
   } else {
     if (options & kFromEnd) {
+      // TODO(brians): Test this block.
       if (kReadDebug) {
         printf("queue: %p start of c1\n", this);
       }
       int pos = data_end_ - 1;
+      if (kReadIndexDebug) {
+        printf("queue: %p end pos start %d\n", this, pos);
+      }
       if (pos < 0) {  // If it wrapped.
         pos = data_length_ - 1;  // Unwrap it.
       }
@@ -483,6 +495,8 @@
       // not between them (if the queue is wrapped around).
       assert((my_start >= data_start_ && my_start < data_end_) ||
              ((my_start >= data_start_) == (my_start > data_end_)));
+      // More sanity checking.
+      assert((my_start >= 0) && (my_start < data_length_));
       msg = data_[my_start];
       ++(*index);
     }
@@ -497,6 +511,7 @@
 }
 
 void *RawQueue::GetMessage() {
+  // TODO(brians): Test this function.
   MutexLocker locker(&pool_lock_);
   MessageHeader *header;
   if (pool_length_ - messages_used_ > 0) {
diff --git a/aos/linux_code/ipc_lib/queue.h b/aos/linux_code/ipc_lib/queue.h
index 937cb07..e7737e1 100644
--- a/aos/linux_code/ipc_lib/queue.h
+++ b/aos/linux_code/ipc_lib/queue.h
@@ -55,22 +55,22 @@
   // Constants for passing to options arguments.
   // The non-conflicting ones can be combined with bitwise-or.
 
-  // Causes the returned message to be left in the queue.
-  // NOTE: When used with ReadMessageIndex, this means the index will not be
-  // updated.
+  // Doesn't update the currently read index (the read messages in the queue or
+  // the index). This means the returned message (and any others skipped with
+  // kFromEnd) will be left in the queue.
   // For reading only.
   static const int kPeek = 0x0001;
   // Reads the last message in the queue instead of just the next one.
   // NOTE: This removes all of the messages until the last one from the queue
-  // (which means that nobody else will read them). However, PEEK means to not
-  // remove any from the queue, including the ones that are skipped.
+  // (which means that nobody else will read them).
   // For reading only.
   static const int kFromEnd = 0x0002;
   // Causes reads to return NULL and writes to fail instead of waiting.
   // For reading and writing.
   static const int kNonBlock = 0x0004;
   // Causes things to block.
-  // IMPORTANT: Has a value of 0 so that it is the default. This has to stay.
+  // IMPORTANT: Has a value of 0 so that it is the default. This has to stay
+  // this way.
   // For reading and writing.
   static const int kBlock = 0x0000;
   // Causes writes to overwrite the oldest message in the queue instead of
@@ -113,6 +113,10 @@
     if (msg != NULL) DecrementMessageReferenceCount(msg);
   }
 
+  // Returns the number of messages from this queue that are currently used (in
+  // the queue and/or given out as references).
+  int messages_used() const { return messages_used_; }
+
  private:
   struct MessageHeader;
   struct ReadData;
@@ -153,16 +157,17 @@
   // Calls DoFreeMessage if appropriate.
   void DecrementMessageReferenceCount(const void *msg);
 
-  // Should be called with data_lock_ locked.
+  // Must be called with data_lock_ locked.
   // *read_data will be initialized.
   // Returns with a readable message in data_ or false.
   bool ReadCommonStart(int options, int *index, ReadData *read_data);
   // Deals with setting/unsetting readable_ and writable_.
-  // Should be called after data_lock_ has been unlocked.
+  // Must be called after data_lock_ has been unlocked.
   // read_data should be the same thing that was passed in to ReadCommonStart.
   void ReadCommonEnd(ReadData *read_data);
   // Handles reading with kPeek.
-  void *ReadPeek(int options, int start);
+  // start can be -1 if options has kFromEnd set.
+  void *ReadPeek(int options, int start) const;
 
   // Gets called by Fetch when necessary (with placement new).
   RawQueue(const char *name, size_t length, int hash, int queue_length);
diff --git a/aos/linux_code/ipc_lib/raw_queue_test.cc b/aos/linux_code/ipc_lib/raw_queue_test.cc
index 2172fc1..0c0308a 100644
--- a/aos/linux_code/ipc_lib/raw_queue_test.cc
+++ b/aos/linux_code/ipc_lib/raw_queue_test.cc
@@ -470,50 +470,78 @@
 
 TEST_F(RawQueueTest, ReadIndexNotFull) {
   RawQueue *const queue = RawQueue::Fetch("Queue", sizeof(TestMessage), 1, 2);
-  const TestMessage *message;
+  const TestMessage *message, *peek_message;
 
+  EXPECT_EQ(0, queue->messages_used());
   PushMessage(queue, 971);
+  EXPECT_EQ(1, queue->messages_used());
 
   int index = 0;
+  peek_message = static_cast<const TestMessage *>(
+      queue->ReadMessageIndex(RawQueue::kNonBlock | RawQueue::kPeek, &index));
   message = static_cast<const TestMessage *>(
       queue->ReadMessageIndex(RawQueue::kNonBlock, &index));
   ASSERT_NE(nullptr, message);
+  EXPECT_EQ(message, peek_message);
   EXPECT_EQ(971, message->data);
   EXPECT_EQ(1, index);
+  queue->FreeMessage(message);
+  queue->FreeMessage(peek_message);
 
   PushMessage(queue, 1768);
+  EXPECT_EQ(2, queue->messages_used());
+  peek_message = static_cast<const TestMessage *>(
+      queue->ReadMessageIndex(RawQueue::kNonBlock | RawQueue::kPeek, &index));
   message = static_cast<const TestMessage *>(
       queue->ReadMessageIndex(RawQueue::kNonBlock, &index));
   ASSERT_NE(nullptr, message);
+  EXPECT_EQ(message, peek_message);
   EXPECT_EQ(1768, message->data);
   EXPECT_EQ(2, index);
+  queue->FreeMessage(message);
+  queue->FreeMessage(peek_message);
 
   PushMessage(queue, 254);
+  peek_message = static_cast<const TestMessage *>(
+      queue->ReadMessageIndex(RawQueue::kNonBlock | RawQueue::kPeek, &index));
   message = static_cast<const TestMessage *>(
       queue->ReadMessageIndex(RawQueue::kNonBlock, &index));
   ASSERT_NE(nullptr, message);
+  EXPECT_EQ(message, peek_message);
   EXPECT_EQ(254, message->data);
   EXPECT_EQ(3, index);
+  queue->FreeMessage(message);
+  queue->FreeMessage(peek_message);
+
+  EXPECT_EQ(2, queue->messages_used());
 }
 
 TEST_F(RawQueueTest, ReadIndexNotBehind) {
   RawQueue *const queue = RawQueue::Fetch("Queue", sizeof(TestMessage), 1, 2);
-  const TestMessage *message;
+  const TestMessage *message, *peek_message;
 
+  EXPECT_EQ(0, queue->messages_used());
   PushMessage(queue, 971);
+  EXPECT_EQ(1, queue->messages_used());
   PushMessage(queue, 1768);
+  EXPECT_EQ(2, queue->messages_used());
 
   int index = 0;
+  peek_message = static_cast<const TestMessage *>(
+      queue->ReadMessageIndex(RawQueue::kNonBlock | RawQueue::kPeek, &index));
   message = static_cast<const TestMessage *>(
       queue->ReadMessageIndex(RawQueue::kNonBlock, &index));
   ASSERT_NE(nullptr, message);
+  EXPECT_EQ(message, peek_message);
   EXPECT_EQ(971, message->data);
   EXPECT_EQ(1, index);
+  queue->FreeMessage(message);
+  queue->FreeMessage(peek_message);
 }
 
 TEST_F(RawQueueTest, ReadIndexLittleBehindNotFull) {
   RawQueue *const queue = RawQueue::Fetch("Queue", sizeof(TestMessage), 1, 2);
-  const TestMessage *message;
+  const TestMessage *message, *peek_message;
 
   PushMessage(queue, 971);
   PushMessage(queue, 1768);
@@ -521,16 +549,22 @@
 
   int index = 0;
 
+  peek_message = static_cast<const TestMessage *>(
+      queue->ReadMessageIndex(RawQueue::kNonBlock | RawQueue::kPeek, &index));
   message = static_cast<const TestMessage *>(
       queue->ReadMessageIndex(RawQueue::kNonBlock, &index));
   ASSERT_NE(nullptr, message);
+  EXPECT_EQ(message, peek_message);
   EXPECT_EQ(1768, message->data);
   EXPECT_EQ(2, index);
+  queue->FreeMessage(message);
+  queue->FreeMessage(peek_message);
+
 }
 
 TEST_F(RawQueueTest, ReadIndexMoreBehind) {
   RawQueue *const queue = RawQueue::Fetch("Queue", sizeof(TestMessage), 1, 2);
-  const TestMessage *message;
+  const TestMessage *message, *peek_message;
 
   PushMessage(queue, 971);
   PushMessage(queue, 1768);
@@ -539,21 +573,32 @@
 
   int index = 0;
 
+  peek_message = static_cast<const TestMessage *>(
+      queue->ReadMessageIndex(RawQueue::kNonBlock | RawQueue::kPeek, &index));
   message = static_cast<const TestMessage *>(
       queue->ReadMessageIndex(RawQueue::kNonBlock, &index));
   ASSERT_NE(nullptr, message);
+  EXPECT_EQ(message, peek_message);
   EXPECT_EQ(1768, message->data);
   EXPECT_EQ(2, index);
+  queue->FreeMessage(message);
+  queue->FreeMessage(peek_message);
+
+  peek_message = static_cast<const TestMessage *>(
+      queue->ReadMessageIndex(RawQueue::kNonBlock | RawQueue::kPeek, &index));
   message = static_cast<const TestMessage *>(
       queue->ReadMessageIndex(RawQueue::kNonBlock, &index));
   ASSERT_NE(nullptr, message);
+  EXPECT_EQ(message, peek_message);
   EXPECT_EQ(254, message->data);
   EXPECT_EQ(3, index);
+  queue->FreeMessage(message);
+  queue->FreeMessage(peek_message);
 }
 
 TEST_F(RawQueueTest, ReadIndexMoreBehindNotFull) {
   RawQueue *const queue = RawQueue::Fetch("Queue", sizeof(TestMessage), 1, 2);
-  const TestMessage *message;
+  const TestMessage *message, *peek_message;
 
   PushMessage(queue, 971);
   PushMessage(queue, 1768);
@@ -563,41 +608,67 @@
 
   int index = 0;
 
+  peek_message = static_cast<const TestMessage *>(
+      queue->ReadMessageIndex(RawQueue::kNonBlock | RawQueue::kPeek, &index));
   message = static_cast<const TestMessage *>(
       queue->ReadMessageIndex(RawQueue::kNonBlock, &index));
   ASSERT_NE(nullptr, message);
+  EXPECT_EQ(message, peek_message);
   EXPECT_EQ(254, message->data);
   EXPECT_EQ(3, index);
+  queue->FreeMessage(message);
+  queue->FreeMessage(peek_message);
 }
 
 TEST_F(RawQueueTest, ReadIndexLotBehind) {
   RawQueue *const queue = RawQueue::Fetch("Queue", sizeof(TestMessage), 1, 2);
-  const TestMessage *message;
+  const TestMessage *message, *peek_message;
 
   PushMessage(queue, 971);
   PushMessage(queue, 1768);
-  ASSERT_NE(nullptr, queue->ReadMessage(RawQueue::kNonBlock));
-  PushMessage(queue, 254);
-  ASSERT_NE(nullptr, queue->ReadMessage(RawQueue::kNonBlock));
-  PushMessage(queue, 973);
+  {
+    const void *message1, *message2;
+    message1 = queue->ReadMessage(RawQueue::kNonBlock);
+    ASSERT_NE(nullptr, message1);
+    PushMessage(queue, 254);
+    message2 = queue->ReadMessage(RawQueue::kNonBlock);
+    ASSERT_NE(nullptr, message2);
+    PushMessage(queue, 973);
+    EXPECT_EQ(4, queue->messages_used());
+    queue->FreeMessage(message1);
+    EXPECT_EQ(3, queue->messages_used());
+    queue->FreeMessage(message2);
+    EXPECT_EQ(2, queue->messages_used());
+  }
 
   int index = 0;
 
+  peek_message = static_cast<const TestMessage *>(
+      queue->ReadMessageIndex(RawQueue::kNonBlock | RawQueue::kPeek, &index));
   message = static_cast<const TestMessage *>(
       queue->ReadMessageIndex(RawQueue::kNonBlock, &index));
   ASSERT_NE(nullptr, message);
+  EXPECT_EQ(message, peek_message);
   EXPECT_EQ(254, message->data);
   EXPECT_EQ(3, index);
+  queue->FreeMessage(message);
+  queue->FreeMessage(peek_message);
+
+  peek_message = static_cast<const TestMessage *>(
+      queue->ReadMessageIndex(RawQueue::kNonBlock | RawQueue::kPeek, &index));
   message = static_cast<const TestMessage *>(
       queue->ReadMessageIndex(RawQueue::kNonBlock, &index));
   ASSERT_NE(nullptr, message);
+  EXPECT_EQ(message, peek_message);
   EXPECT_EQ(973, message->data);
   EXPECT_EQ(4, index);
+  queue->FreeMessage(message);
+  queue->FreeMessage(peek_message);
 }
 
 TEST_F(RawQueueTest, ReadIndexLotBehindNotFull) {
   RawQueue *const queue = RawQueue::Fetch("Queue", sizeof(TestMessage), 1, 2);
-  const TestMessage *message;
+  const TestMessage *message, *peek_message;
 
   PushMessage(queue, 971);
   PushMessage(queue, 1768);
@@ -609,16 +680,21 @@
 
   int index = 0;
 
+  peek_message = static_cast<const TestMessage *>(
+      queue->ReadMessageIndex(RawQueue::kNonBlock | RawQueue::kPeek, &index));
   message = static_cast<const TestMessage *>(
       queue->ReadMessageIndex(RawQueue::kNonBlock, &index));
   ASSERT_NE(nullptr, message);
+  EXPECT_EQ(message, peek_message);
   EXPECT_EQ(973, message->data);
   EXPECT_EQ(4, index);
+  queue->FreeMessage(message);
+  queue->FreeMessage(peek_message);
 }
 
 TEST_F(RawQueueTest, ReadIndexEvenMoreBehind) {
   RawQueue *const queue = RawQueue::Fetch("Queue", sizeof(TestMessage), 1, 2);
-  const TestMessage *message;
+  const TestMessage *message, *peek_message;
 
   PushMessage(queue, 971);
   PushMessage(queue, 1768);
@@ -631,21 +707,32 @@
 
   int index = 0;
 
+  peek_message = static_cast<const TestMessage *>(
+      queue->ReadMessageIndex(RawQueue::kNonBlock | RawQueue::kPeek, &index));
   message = static_cast<const TestMessage *>(
       queue->ReadMessageIndex(RawQueue::kNonBlock, &index));
   ASSERT_NE(nullptr, message);
+  EXPECT_EQ(message, peek_message);
   EXPECT_EQ(973, message->data);
   EXPECT_EQ(4, index);
+  queue->FreeMessage(message);
+  queue->FreeMessage(peek_message);
+
+  peek_message = static_cast<const TestMessage *>(
+      queue->ReadMessageIndex(RawQueue::kNonBlock | RawQueue::kPeek, &index));
   message = static_cast<const TestMessage *>(
       queue->ReadMessageIndex(RawQueue::kNonBlock, &index));
   ASSERT_NE(nullptr, message);
+  EXPECT_EQ(message, peek_message);
   EXPECT_EQ(1114, message->data);
   EXPECT_EQ(5, index);
+  queue->FreeMessage(message);
+  queue->FreeMessage(peek_message);
 }
 
 TEST_F(RawQueueTest, ReadIndexEvenMoreBehindNotFull) {
   RawQueue *const queue = RawQueue::Fetch("Queue", sizeof(TestMessage), 1, 2);
-  const TestMessage *message;
+  const TestMessage *message, *peek_message;
 
   PushMessage(queue, 971);
   PushMessage(queue, 1768);
@@ -659,11 +746,16 @@
 
   int index = 0;
 
+  peek_message = static_cast<const TestMessage *>(
+      queue->ReadMessageIndex(RawQueue::kNonBlock | RawQueue::kPeek, &index));
   message = static_cast<const TestMessage *>(
       queue->ReadMessageIndex(RawQueue::kNonBlock, &index));
   ASSERT_NE(nullptr, message);
+  EXPECT_EQ(message, peek_message);
   EXPECT_EQ(1114, message->data);
   EXPECT_EQ(5, index);
+  queue->FreeMessage(message);
+  queue->FreeMessage(peek_message);
 }
 
 }  // namespace testing