cut down the number of readable_.Broadcast()s

It's not hard to keep track of whether there are waiters, and there
usually aren't for most queues, so it helps performance a lot to not
make all those unnecessary syscalls.
diff --git a/aos/linux_code/ipc_lib/queue.cc b/aos/linux_code/ipc_lib/queue.cc
index 8513e32..9943b85 100644
--- a/aos/linux_code/ipc_lib/queue.cc
+++ b/aos/linux_code/ipc_lib/queue.cc
@@ -215,6 +215,8 @@
     }
   }
 
+  readable_waiting_ = false;
+
   if (kFetchDebug) {
     printf("made queue %s\n", name);
   }
@@ -315,10 +317,15 @@
     ++messages_;
     data_end_ = new_end;
 
-    if (kWriteDebug) {
-      printf("queue: broadcasting to readable_ of %p\n", this);
+    if (readable_waiting_) {
+      if (kWriteDebug) {
+        printf("queue: broadcasting to readable_ of %p\n", this);
+      }
+      readable_waiting_ = false;
+      readable_.Broadcast();
+    } else if (kWriteDebug) {
+      printf("queue: skipping broadcast to readable_ of %p\n", this);
     }
-    readable_.Broadcast();
 
     // If we got a signal on writable_ here and it's still writable, then we
     // need to signal the next person in line (if any).
@@ -357,6 +364,7 @@
       if (kReadDebug) {
         printf("queue: going to wait for readable_ of %p\n", this);
       }
+      readable_waiting_ = true;
       // Wait for a message to become readable.
       readable_.Wait();
       if (kReadDebug) {