1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-04-19 03:58:05 -05:00

Rework bufchain code to allow for variable-sized granules.

bufchain_add() now allocates at most one new granule.  Granules still 
have a minimum size, so small adds still get coalesced.

The main practical consequence of this is that PSCP and PSFTP now 
generate 4K SSH packets rather than 512-byte ones.  Also, the compiled 
code (on my Ubuntu box) is fractionally smaller.

[originally from svn r9602]
This commit is contained in:
Ben Harris 2012-08-11 09:10:31 +00:00
parent 37ea0f4541
commit b599e77ada

50
misc.c
View File

@ -364,12 +364,11 @@ void base64_encode_atom(unsigned char *data, int n, char *out)
* - return the current size of the buffer chain in bytes * - return the current size of the buffer chain in bytes
*/ */
#define BUFFER_GRANULE 512 #define BUFFER_MIN_GRANULE 512
struct bufchain_granule { struct bufchain_granule {
struct bufchain_granule *next; struct bufchain_granule *next;
int buflen, bufpos; char *bufpos, *bufend, *bufmax;
char buf[BUFFER_GRANULE];
}; };
void bufchain_init(bufchain *ch) void bufchain_init(bufchain *ch)
@ -403,29 +402,30 @@ void bufchain_add(bufchain *ch, const void *data, int len)
ch->buffersize += len; ch->buffersize += len;
if (ch->tail && ch->tail->buflen < BUFFER_GRANULE) { while (len > 0) {
int copylen = min(len, BUFFER_GRANULE - ch->tail->buflen); if (ch->tail && ch->tail->bufend < ch->tail->bufmax) {
memcpy(ch->tail->buf + ch->tail->buflen, buf, copylen); int copylen = min(len, ch->tail->bufmax - ch->tail->bufend);
memcpy(ch->tail->bufend, buf, copylen);
buf += copylen; buf += copylen;
len -= copylen; len -= copylen;
ch->tail->buflen += copylen; ch->tail->bufend += copylen;
} }
while (len > 0) { if (len > 0) {
int grainlen = min(len, BUFFER_GRANULE); int grainlen =
max(sizeof(struct bufchain_granule) + len, BUFFER_MIN_GRANULE);
struct bufchain_granule *newbuf; struct bufchain_granule *newbuf;
newbuf = snew(struct bufchain_granule); newbuf = smalloc(grainlen);
newbuf->bufpos = 0; newbuf->bufpos = newbuf->bufend =
newbuf->buflen = grainlen; (char *)newbuf + sizeof(struct bufchain_granule);
memcpy(newbuf->buf, buf, grainlen); newbuf->bufmax = (char *)newbuf + grainlen;
buf += grainlen; newbuf->next = NULL;
len -= grainlen;
if (ch->tail) if (ch->tail)
ch->tail->next = newbuf; ch->tail->next = newbuf;
else else
ch->head = ch->tail = newbuf; ch->head = newbuf;
newbuf->next = NULL;
ch->tail = newbuf; ch->tail = newbuf;
} }
}
} }
void bufchain_consume(bufchain *ch, int len) void bufchain_consume(bufchain *ch, int len)
@ -436,13 +436,13 @@ void bufchain_consume(bufchain *ch, int len)
while (len > 0) { while (len > 0) {
int remlen = len; int remlen = len;
assert(ch->head != NULL); assert(ch->head != NULL);
if (remlen >= ch->head->buflen - ch->head->bufpos) { if (remlen >= ch->head->bufend - ch->head->bufpos) {
remlen = ch->head->buflen - ch->head->bufpos; remlen = ch->head->bufend - ch->head->bufpos;
tmp = ch->head; tmp = ch->head;
ch->head = tmp->next; ch->head = tmp->next;
sfree(tmp);
if (!ch->head) if (!ch->head)
ch->tail = NULL; ch->tail = NULL;
sfree(tmp);
} else } else
ch->head->bufpos += remlen; ch->head->bufpos += remlen;
ch->buffersize -= remlen; ch->buffersize -= remlen;
@ -452,8 +452,8 @@ void bufchain_consume(bufchain *ch, int len)
void bufchain_prefix(bufchain *ch, void **data, int *len) void bufchain_prefix(bufchain *ch, void **data, int *len)
{ {
*len = ch->head->buflen - ch->head->bufpos; *len = ch->head->bufend - ch->head->bufpos;
*data = ch->head->buf + ch->head->bufpos; *data = ch->head->bufpos;
} }
void bufchain_fetch(bufchain *ch, void *data, int len) void bufchain_fetch(bufchain *ch, void *data, int len)
@ -468,9 +468,9 @@ void bufchain_fetch(bufchain *ch, void *data, int len)
int remlen = len; int remlen = len;
assert(tmp != NULL); assert(tmp != NULL);
if (remlen >= tmp->buflen - tmp->bufpos) if (remlen >= tmp->bufend - tmp->bufpos)
remlen = tmp->buflen - tmp->bufpos; remlen = tmp->bufend - tmp->bufpos;
memcpy(data_c, tmp->buf + tmp->bufpos, remlen); memcpy(data_c, tmp->bufpos, remlen);
tmp = tmp->next; tmp = tmp->next;
len -= remlen; len -= remlen;