aboutsummaryrefslogtreecommitdiffstats
path: root/tools/console
diff options
context:
space:
mode:
authoremellor@leeni.uk.xensource.com <emellor@leeni.uk.xensource.com>2005-12-06 17:10:59 +0000
committeremellor@leeni.uk.xensource.com <emellor@leeni.uk.xensource.com>2005-12-06 17:10:59 +0000
commitef1a53c4e0b7a90a2923f4349e0fbc519faf5a54 (patch)
treee4a7e3b5b007b20e63ebd696a415865d70590e73 /tools/console
parentb978d1410ab951e54b8b12738ca917d6dd3d7507 (diff)
downloadxen-ef1a53c4e0b7a90a2923f4349e0fbc519faf5a54.tar.gz
xen-ef1a53c4e0b7a90a2923f4349e0fbc519faf5a54.tar.bz2
xen-ef1a53c4e0b7a90a2923f4349e0fbc519faf5a54.zip
Add a "consumed" parameter to the buffer declaration, and use this to advance
through the buffer when the data are read by console clients. This avoids a costly memmove with every read from the console. Signed-off-by: Ewan Mellor <ewan@xensource.com>
Diffstat (limited to 'tools/console')
-rw-r--r--tools/console/daemon/io.c35
1 files changed, 24 insertions, 11 deletions
diff --git a/tools/console/daemon/io.c b/tools/console/daemon/io.c
index 1b49f20c23..5819bcf647 100644
--- a/tools/console/daemon/io.c
+++ b/tools/console/daemon/io.c
@@ -48,6 +48,7 @@
struct buffer
{
char *data;
+ size_t consumed;
size_t size;
size_t capacity;
size_t max_capacity;
@@ -109,12 +110,17 @@ static void buffer_append(struct domain *dom)
if (buffer->max_capacity &&
buffer->size > buffer->max_capacity) {
- memmove(buffer->data + (buffer->size -
- buffer->max_capacity),
- buffer->data, buffer->max_capacity);
- buffer->data = realloc(buffer->data,
- buffer->max_capacity);
+ /* Discard the middle of the data. */
+
+ size_t over = buffer->size - buffer->max_capacity;
+ char *maxpos = buffer->data + buffer->max_capacity;
+
+ memmove(maxpos - over, maxpos, over);
+ buffer->data = realloc(buffer->data, buffer->max_capacity);
buffer->size = buffer->capacity = buffer->max_capacity;
+
+ if (buffer->consumed > buffer->max_capacity - over)
+ buffer->consumed = buffer->max_capacity - over;
}
}
@@ -123,11 +129,13 @@ static bool buffer_empty(struct buffer *buffer)
return buffer->size == 0;
}
-static void buffer_advance(struct buffer *buffer, size_t size)
+static void buffer_advance(struct buffer *buffer, size_t len)
{
- size = MIN(size, buffer->size);
- memmove(buffer->data, buffer + size, buffer->size - size);
- buffer->size -= size;
+ buffer->consumed += len;
+ if (buffer->consumed == buffer->size) {
+ buffer->consumed = 0;
+ buffer->size = 0;
+ }
}
static bool domain_is_valid(int domid)
@@ -327,6 +335,7 @@ static struct domain *create_domain(int domid)
dom->tty_fd = -1;
dom->is_dead = false;
dom->buffer.data = 0;
+ dom->buffer.consumed = 0;
dom->buffer.size = 0;
dom->buffer.capacity = 0;
dom->buffer.max_capacity = 0;
@@ -474,8 +483,12 @@ static void handle_tty_write(struct domain *dom)
{
ssize_t len;
- len = write(dom->tty_fd, dom->buffer.data, dom->buffer.size);
- if (len < 1) {
+ len = write(dom->tty_fd, dom->buffer.data + dom->buffer.consumed,
+ dom->buffer.size - dom->buffer.consumed);
+ if (len < 1) {
+ dolog(LOG_DEBUG, "Write failed on domain %d: %d, %d\n",
+ dom->domid, len, errno);
+
close(dom->tty_fd);
dom->tty_fd = -1;