dev: Fix incorrect terminal backlog handling
authorAndreas Sandberg <andreas.sandberg@arm.com>
Wed, 27 Apr 2016 14:33:58 +0000 (15:33 +0100)
committerAndreas Sandberg <andreas.sandberg@arm.com>
Wed, 27 Apr 2016 14:33:58 +0000 (15:33 +0100)
The Terminal device currently uses the peek functionality in gem5's
circular buffer implementation to send existing buffered content on
the terminal when a new client attaches. This functionallity is
however not implemented correctly and re-sends the same block multiple
time.

Add the required functionality to peek with an offset into the
circular buffer and change the Terminal::accept() implementation to
send the buffered contents.

Signed-off-by: Andreas Sandberg <andreas.sandberg@arm.com>
Reviewed-by: Radhika Jagtap <radhika.jagtap@arm.com>
Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
src/base/circlebuf.hh
src/dev/terminal.cc

index eca293669308139e6e7c36efcc9720c85d452376..2ab14e269baafdc87e88e8e029b4bee3e9a8ae51 100644 (file)
@@ -103,24 +103,36 @@ class CircleBuf
      */
     template <class OutputIterator>
     void peek(OutputIterator out, size_t len) const {
-        panic_if(len > size(),
+        peek(out, 0, len);
+    }
+
+    /**
+     * Copy buffer contents without advancing the read pointer
+     *
+     * @param out Output iterator/pointer
+     * @param offset Offset into the ring buffer
+     * @param len Number of elements to copy
+     */
+    template <class OutputIterator>
+    void peek(OutputIterator out, off_t offset, size_t len) const {
+        panic_if(offset + len > size(),
                  "Trying to read past end of circular buffer.\n");
 
-        if (_start + len <= buf.size()) {
-            std::copy(buf.begin() + _start,
-                      buf.begin() + _start + len,
+        const off_t real_start((offset + _start) % buf.size());
+        if (real_start + len <= buf.size()) {
+            std::copy(buf.begin() + real_start,
+                      buf.begin() + real_start + len,
                       out);
         } else {
-            const size_t head_size(buf.size() - _start);
+            const size_t head_size(buf.size() - real_start);
             const size_t tail_size(len - head_size);
-            std::copy(buf.begin() + _start, buf.end(),
+            std::copy(buf.begin() + real_start, buf.end(),
                       out);
             std::copy(buf.begin(), buf.begin() + tail_size,
                       out + head_size);
         }
     }
 
-
     /**
      * Copy buffer contents and advance the read pointer
      *
index 53e593f85ea1671cbc644a3e2dbae609ee01582f..9f0ea5ea301fb524e2b375207c3826de81f98327 100644 (file)
@@ -204,7 +204,7 @@ Terminal::accept()
     char buf[1024];
     for (size_t i = 0; i < txbuf.size(); i += sizeof(buf)) {
         const size_t chunk_len(std::min(txbuf.size() - i, sizeof(buf)));
-        txbuf.peek(buf, chunk_len);
+        txbuf.peek(buf, i, chunk_len);
         write((const uint8_t *)buf, chunk_len);
     }
 }