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