Remove unnecessary circular buffer code.
authorTim Newsome <tim@sifive.com>
Tue, 7 Feb 2017 04:15:34 +0000 (20:15 -0800)
committerTim Newsome <tim@sifive.com>
Tue, 7 Feb 2017 04:15:34 +0000 (20:15 -0800)
riscv/remote_bitbang.cc
riscv/remote_bitbang.h

index acfd216f83f801c23107db6854da91df4c7149a6..54bc6d7e5aa1912fd9c3d99424d5ffb244177948 100644 (file)
 #  define D(x)
 #endif
 
-/////////// Circular buffer
-
-template <typename T>
-unsigned int circular_buffer_t<T>::size() const
-{
-  if (end >= start)
-    return end - start;
-  else
-    return end + capacity - start;
-}
-
-template <typename T>
-void circular_buffer_t<T>::consume(unsigned int bytes)
-{
-  start = (start + bytes) % capacity;
-}
-
-template <typename T>
-unsigned int circular_buffer_t<T>::contiguous_empty_size() const
-{
-  if (end >= start)
-    if (start == 0)
-      return capacity - end - 1;
-    else
-      return capacity - end;
-  else
-    return start - end - 1;
-}
-
-template <typename T>
-unsigned int circular_buffer_t<T>::contiguous_data_size() const
-{
-  if (end >= start)
-    return end - start;
-  else
-    return capacity - start;
-}
-
-template <typename T>
-void circular_buffer_t<T>::data_added(unsigned int bytes)
-{
-  end += bytes;
-  assert(end <= capacity);
-  if (end == capacity)
-    end = 0;
-}
-
-template <typename T>
-void circular_buffer_t<T>::reset()
-{
-  start = 0;
-  end = 0;
-}
-
-template <typename T>
-void circular_buffer_t<T>::append(const T *src, unsigned int count)
-{
-  unsigned int copy = std::min(count, contiguous_empty_size());
-  memcpy(contiguous_empty(), src, copy * sizeof(T));
-  data_added(copy);
-  count -= copy;
-  if (count > 0) {
-    assert(count < contiguous_empty_size());
-    memcpy(contiguous_empty(), src+copy, count * sizeof(T));
-    data_added(count);
-  }
-}
-
-template <typename T>
-void circular_buffer_t<T>::append(T value)
-{
-  append(&value, 1);
-}
-
 /////////// remote_bitbang_t
 
 remote_bitbang_t::remote_bitbang_t(uint16_t port, jtag_dtm_t *tap) :
   tap(tap),
   socket_fd(0),
-  client_fd(0),
-  recv_buf(64 * 1024),
-  send_buf(64 * 1024)
+  client_fd(0)
 {
   socket_fd = socket(AF_INET, SOCK_STREAM, 0);
   if (socket_fd == -1) {
@@ -151,98 +75,74 @@ void remote_bitbang_t::accept()
   }
 }
 
-void remote_bitbang_t::read()
-{
-  // Reading from a non-blocking socket still blocks if there is no data
-  // available.
-
-  size_t count = recv_buf.contiguous_empty_size();
-  ssize_t bytes = ::read(client_fd, recv_buf.contiguous_empty(), count);
-  if (bytes == -1) {
-    if (errno == EAGAIN) {
-      // We'll try again the next call.
-    } else {
-      fprintf(stderr, "failed to read on socket: %s (%d)\n", strerror(errno), errno);
-      abort();
-    }
-  } else if (bytes == 0) {
-    // The remote disconnected.
-    client_fd = 0;
-    recv_buf.reset();
-    send_buf.reset();
-  } else {
-    recv_buf.data_added(bytes);
-    D(fprintf(stderr, "receive buffer: "));
-    for (unsigned i = 0; i < recv_buf.size(); i++) {
-      D(fprintf(stderr, "%c", recv_buf[i]));
-    }
-    D(fprintf(stderr, "\n"));
-  }
-}
-
-void remote_bitbang_t::write()
-{
-  if (send_buf.empty())
-    return;
-
-  while (!send_buf.empty()) {
-    unsigned int count = send_buf.contiguous_data_size();
-    assert(count > 0);
-    ssize_t bytes = ::write(client_fd, send_buf.contiguous_data(), count);
-    if (bytes == -1) {
-      fprintf(stderr, "failed to write to socket: %s (%d)\n", strerror(errno), errno);
-      abort();
-    } else if (bytes == 0) {
-      // Client can't take any more data right now.
-      break;
-    } else {
-      D(fprintf(stderr, "wrote %zd bytes: ", bytes));
-      for (int i = 0; i < bytes; i++) {
-        D(fprintf(stderr, "%c", send_buf[i]));
-      }
-      D(fprintf(stderr, "\n"));
-      send_buf.consume(bytes);
-    }
-  }
-}
-
 void remote_bitbang_t::tick()
 {
   if (client_fd > 0) {
-    this->read();
-    process_input();
-    this->write();
+    execute_commands();
   } else {
     this->accept();
   }
 }
 
-void remote_bitbang_t::process_input()
+void remote_bitbang_t::execute_commands()
 {
-  // TODO: get rid of the circular buffers, and just read/write here with
-  // simple local buffers.
-  // Each message is a single character, so there's never any need to keep a
-  // partially transmitted message around.
+  const unsigned buf_size = 64 * 1024;
+  char recv_buf[buf_size];
+  char send_buf[buf_size];
+  unsigned total_received = 0;
+  ssize_t bytes = read(client_fd, recv_buf, buf_size);
+  while (bytes > 0) {
+    total_received += bytes;
+    unsigned send_offset = 0;
+    for (unsigned i = 0; i < bytes; i++) {
+      uint8_t command = recv_buf[i];
+
+      switch (command) {
+        case 'B': fprintf(stderr, "*BLINK*\n"); break;
+        case 'b': fprintf(stderr, "_______\n"); break;
+        case 'r': tap->reset(); break;
+        case '0': tap->set_pins(0, 0, 0); break;
+        case '1': tap->set_pins(0, 0, 1); break;
+        case '2': tap->set_pins(0, 1, 0); break;
+        case '3': tap->set_pins(0, 1, 1); break;
+        case '4': tap->set_pins(1, 0, 0); break;
+        case '5': tap->set_pins(1, 0, 1); break;
+        case '6': tap->set_pins(1, 1, 0); break;
+        case '7': tap->set_pins(1, 1, 1); break;
+        case 'R': send_buf[send_offset++] = tap->tdo() ? '1' : '0'; break;
+        default:
+                  fprintf(stderr, "remote_bitbang got unsupported command '%c'\n",
+                      command);
+      }
+    }
+    unsigned sent = 0;
+    while (sent < send_offset) {
+      bytes = write(client_fd, send_buf + sent, send_offset);
+      if (bytes == -1) {
+        fprintf(stderr, "failed to write to socket: %s (%d)\n", strerror(errno), errno);
+        abort();
+      }
+      sent += bytes;
+    }
 
-  for (unsigned i = 0; i < recv_buf.size(); i++) {
-    uint8_t command = recv_buf[i];
+    if (total_received > buf_size) {
+      // Don't go forever, because that could starve the main simulation.
+      break;
+    }
+    bytes = read(client_fd, recv_buf, buf_size);
+  }
 
-    switch (command) {
-      case 'B': fprintf(stderr, "*BLINK*\n"); break;
-      case 'b': fprintf(stderr, "_______\n"); break;
-      case 'r': tap->reset(); break;
-      case '0': tap->set_pins(0, 0, 0); break;
-      case '1': tap->set_pins(0, 0, 1); break;
-      case '2': tap->set_pins(0, 1, 0); break;
-      case '3': tap->set_pins(0, 1, 1); break;
-      case '4': tap->set_pins(1, 0, 0); break;
-      case '5': tap->set_pins(1, 0, 1); break;
-      case '6': tap->set_pins(1, 1, 0); break;
-      case '7': tap->set_pins(1, 1, 1); break;
-      case 'R': send_buf.append(tap->tdo() ? '1' : '0'); break;
-      default:
-        fprintf(stderr, "remote_bitbang got unsupported command '%c'\n", command);
+  if (bytes == -1) {
+    if (errno == EAGAIN) {
+      // We'll try again the next call.
+    } else {
+      fprintf(stderr, "remote_bitbang failed to read on socket: %s (%d)\n",
+          strerror(errno), errno);
+      abort();
     }
+  } else if (bytes == 0) {
+    // The remote disconnected.
+    close(client_fd);
+    client_fd = 0;
   }
-  recv_buf.reset();
 }
index c0aa7e040ff3909a1097b644b20dfb2808366348..289fbb3e2f6f327a7720d6703bb24ebece51a1c7 100644 (file)
@@ -5,45 +5,6 @@
 
 #include "jtag_dtm.h"
 
-template <typename T>
-class circular_buffer_t
-{
-public:
-  // The buffer can store capacity-1 data elements.
-  circular_buffer_t(unsigned int capacity) : data(new T[capacity]),
-      start(0), end(0), capacity(capacity) {}
-  circular_buffer_t() : start(0), end(0), capacity(0) {}
-  ~circular_buffer_t() { delete[] data; }
-
-  T *data;
-  unsigned int start;   // Data start, inclusive.
-  unsigned int end;     // Data end, exclusive.
-  unsigned int capacity;    // Size of the buffer.
-  unsigned int size() const;
-  bool empty() const { return start == end; }
-  bool full() const { return ((end+1) % capacity) == start; }
-  T entry(unsigned index) { return data[(start + index) % capacity]; }
-
-  // Return size and address of the block of RAM where more data can be copied
-  // to be added to the buffer.
-  unsigned int contiguous_empty_size() const;
-  T *contiguous_empty() { return data + end; }
-  void data_added(unsigned int bytes);
-
-  unsigned int contiguous_data_size() const;
-  T *contiguous_data() { return data + start; }
-  // Tell the buffer that some bytes were consumed from the start of the
-  // buffer.
-  void consume(unsigned int bytes);
-
-  void reset();
-
-  T operator[](unsigned int i) const { return data[(start + i) % capacity]; }
-
-  void append(const T *src, unsigned int count);
-  void append(T value);
-};
-
 class remote_bitbang_t
 {
 public:
@@ -59,18 +20,11 @@ private:
 
   int socket_fd;
   int client_fd;
-  circular_buffer_t<uint8_t> recv_buf;
-  circular_buffer_t<uint8_t> send_buf;
 
   // Check for a client connecting, and accept if there is one.
   void accept();
-  // Read as much into recv_buf as possible.
-  void read();
-  // Write as much of send_buf as possible.
-  void write();
-
-  // Process the input buffer.
-  void process_input();
+  // Execute any commands the client has for us.
+  void execute_commands();
 };
 
 #endif