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:
parent
37ea0f4541
commit
b599e77ada
50
misc.c
50
misc.c
@ -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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user