osc: grow OSC buffer exponentially instead of by fixed increments of 128

With fixed increments of 128 bytes, an OSC 52 copy operation could end
up doing thousands or tens of thousands of realloc(3) calls just to
copy a few MB.
This commit is contained in:
Craig Barnes 2022-03-02 01:55:25 +00:00
parent 7d647c08ff
commit a3c5e8927d

16
osc.c
View file

@ -902,11 +902,20 @@ osc_dispatch(struct terminal *term)
bool
osc_ensure_size(struct terminal *term, size_t required_size)
{
if (required_size <= term->vt.osc.size)
if (likely(required_size <= term->vt.osc.size))
return true;
size_t new_size = (required_size + 127) / 128 * 128;
xassert(new_size > 0);
const size_t pow2_max = ~(SIZE_MAX >> 1);
if (unlikely(required_size > pow2_max)) {
LOG_ERR("required OSC buffer size (%zu) exceeds limit (%zu)",
required_size, pow2_max);
return false;
}
size_t new_size = max(term->vt.osc.size, 4096);
while (new_size < required_size) {
new_size <<= 1;
}
uint8_t *new_data = realloc(term->vt.osc.data, new_size);
if (new_data == NULL) {
@ -914,6 +923,7 @@ osc_ensure_size(struct terminal *term, size_t required_size)
return false;
}
LOG_DBG("resized OSC buffer: %zu", new_size);
term->vt.osc.data = new_data;
term->vt.osc.size = new_size;
return true;