From 1f65ba49ea665ceed2774a1a62ac32076e4d3025 Mon Sep 17 00:00:00 2001 From: Tim Newsome Date: Mon, 6 Feb 2017 20:15:34 -0800 Subject: [PATCH] Remove unnecessary circular buffer code. --- riscv/remote_bitbang.cc | 216 +++++++++++----------------------------- riscv/remote_bitbang.h | 50 +--------- 2 files changed, 60 insertions(+), 206 deletions(-) diff --git a/riscv/remote_bitbang.cc b/riscv/remote_bitbang.cc index acfd216..54bc6d7 100644 --- a/riscv/remote_bitbang.cc +++ b/riscv/remote_bitbang.cc @@ -17,88 +17,12 @@ # define D(x) #endif -/////////// Circular buffer - -template -unsigned int circular_buffer_t::size() const -{ - if (end >= start) - return end - start; - else - return end + capacity - start; -} - -template -void circular_buffer_t::consume(unsigned int bytes) -{ - start = (start + bytes) % capacity; -} - -template -unsigned int circular_buffer_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 -unsigned int circular_buffer_t::contiguous_data_size() const -{ - if (end >= start) - return end - start; - else - return capacity - start; -} - -template -void circular_buffer_t::data_added(unsigned int bytes) -{ - end += bytes; - assert(end <= capacity); - if (end == capacity) - end = 0; -} - -template -void circular_buffer_t::reset() -{ - start = 0; - end = 0; -} - -template -void circular_buffer_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 -void circular_buffer_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(); } diff --git a/riscv/remote_bitbang.h b/riscv/remote_bitbang.h index c0aa7e0..289fbb3 100644 --- a/riscv/remote_bitbang.h +++ b/riscv/remote_bitbang.h @@ -5,45 +5,6 @@ #include "jtag_dtm.h" -template -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 recv_buf; - circular_buffer_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 -- 2.30.2