dev: Fix incorrect terminal backlog handling
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>
This commit is contained in:
parent
67e93a5846
commit
6d74892b38
2 changed files with 20 additions and 8 deletions
|
@ -103,24 +103,36 @@ class CircleBuf
|
||||||
*/
|
*/
|
||||||
template <class OutputIterator>
|
template <class OutputIterator>
|
||||||
void peek(OutputIterator out, size_t len) const {
|
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");
|
"Trying to read past end of circular buffer.\n");
|
||||||
|
|
||||||
if (_start + len <= buf.size()) {
|
const off_t real_start((offset + _start) % buf.size());
|
||||||
std::copy(buf.begin() + _start,
|
if (real_start + len <= buf.size()) {
|
||||||
buf.begin() + _start + len,
|
std::copy(buf.begin() + real_start,
|
||||||
|
buf.begin() + real_start + len,
|
||||||
out);
|
out);
|
||||||
} else {
|
} 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);
|
const size_t tail_size(len - head_size);
|
||||||
std::copy(buf.begin() + _start, buf.end(),
|
std::copy(buf.begin() + real_start, buf.end(),
|
||||||
out);
|
out);
|
||||||
std::copy(buf.begin(), buf.begin() + tail_size,
|
std::copy(buf.begin(), buf.begin() + tail_size,
|
||||||
out + head_size);
|
out + head_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copy buffer contents and advance the read pointer
|
* Copy buffer contents and advance the read pointer
|
||||||
*
|
*
|
||||||
|
|
|
@ -204,7 +204,7 @@ Terminal::accept()
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
for (size_t i = 0; i < txbuf.size(); i += sizeof(buf)) {
|
for (size_t i = 0; i < txbuf.size(); i += sizeof(buf)) {
|
||||||
const size_t chunk_len(std::min(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);
|
write((const uint8_t *)buf, chunk_len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue