From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 7404 invoked by alias); 21 Sep 2006 16:12:46 -0000 Received: (qmail 7394 invoked by uid 22791); 21 Sep 2006 16:12:45 -0000 X-Spam-Check-By: sourceware.org Received: from nevyn.them.org (HELO nevyn.them.org) (66.93.172.17) by sourceware.org (qpsmtpd/0.31.1) with ESMTP; Thu, 21 Sep 2006 16:12:41 +0000 Received: from drow by nevyn.them.org with local (Exim 4.54) id 1GQRAF-0007CL-BX for gdb-patches@sourceware.org; Thu, 21 Sep 2006 12:12:39 -0400 Date: Thu, 21 Sep 2006 16:12:00 -0000 From: Daniel Jacobowitz To: gdb-patches@sourceware.org Subject: [commit] Run length encoding for gdbserver Message-ID: <20060921161239.GA27629@nevyn.them.org> Mail-Followup-To: gdb-patches@sourceware.org MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.13 (2006-08-11) X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2006-09/txt/msg00129.txt.bz2 The remote protocol supports a simple run length encoding mechanism (in only one direction - from the stub to the client). This patch implements it in gdbserver. It doesn't make a huge difference to overall performance, but can reduce the amount of data sent in some cases by 50%. I realize I didn't leave any room for the equivalent operation in the new binary transfer packets in the direction from the client to the stub, e.g. for downloading. I don't think this is a big deal. Tested x86_64-pc-linux-gnu and checked in. -- Daniel Jacobowitz CodeSourcery 2006-09-21 Daniel Jacobowitz * remote-utils.c (try_rle): New function. (putpkt_binary): Use it. --- gdb/gdbserver/remote-utils.c | 52 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 47 insertions(+), 5 deletions(-) Index: gdb-trunk/gdb/gdbserver/remote-utils.c =================================================================== --- gdb-trunk.orig/gdb/gdbserver/remote-utils.c 2006-08-29 09:22:38.000000000 -0400 +++ gdb-trunk/gdb/gdbserver/remote-utils.c 2006-08-29 09:22:49.000000000 -0400 @@ -406,6 +406,50 @@ remote_unescape_input (const gdb_byte *b return output_index; } +/* Look for a sequence of characters which can be run-length encoded. + If there are any, update *CSUM and *P. Otherwise, output the + single character. Return the number of characters consumed. */ + +static int +try_rle (char *buf, int remaining, unsigned char *csum, char **p) +{ + int n; + + /* Always output the character. */ + *csum += buf[0]; + *(*p)++ = buf[0]; + + /* Don't go past '~'. */ + if (remaining > 97) + remaining = 97; + + for (n = 1; n < remaining; n++) + if (buf[n] != buf[0]) + break; + + /* N is the index of the first character not the same as buf[0]. + buf[0] is counted twice, so by decrementing N, we get the number + of characters the RLE sequence will replace. */ + n--; + + if (n < 3) + return 1; + + /* Skip the frame characters. The manual says to skip '+' and '-' + also, but there's no reason to. Unfortunately these two unusable + characters double the encoded length of a four byte zero + value. */ + while (n + 29 == '$' || n + 29 == '#') + n--; + + *csum += '*'; + *(*p)++ = '*'; + *csum += n + 29; + *(*p)++ = n + 29; + + return n + 1; +} + /* Send a packet to the remote machine, with error checking. The data of the packet is in BUF, and the length of the packet is in CNT. Returns >= 0 on success, -1 otherwise. */ @@ -427,11 +471,9 @@ putpkt_binary (char *buf, int cnt) p = buf2; *p++ = '$'; - for (i = 0; i < cnt; i++) - { - csum += buf[i]; - *p++ = buf[i]; - } + for (i = 0; i < cnt;) + i += try_rle (buf + i, cnt - i, &csum, &p); + *p++ = '#'; *p++ = tohex ((csum >> 4) & 0xf); *p++ = tohex (csum & 0xf);