[PATCH v5 08/11] libio: Convert __vasprintf_internal to buffers
Florian Weimer
fweimer@redhat.com
Fri Dec 16 18:22:19 GMT 2022
* Adhemerval Zanella Netto:
> On 12/12/22 12:23, Florian Weimer via Libc-alpha wrote:
>> The buffer resizing algorithm is slightly different. The initial
>> buffer is on the stack, and small buffers are directly allocated
>> on the heap using the exact required size. The overhead of the
>> additional copy is compensated by the lowered setup cost for buffers
>> compared to libio streams.
>
> Patch look good, some comments below.
Thanks.
>> +struct __printf_buffer_asprintf
>> +{
>> + /* base.write_base points either to a heap-allocated buffer, or to
>> + the direct array below. */
>> + struct __printf_buffer base;
>> +
>> + /* Initial allocation. 200 should be large enough to copy almost
>> + all asprintf usages with just a single (final, correctly sized)
>> + heap allocation. */
>> + char direct[200];
>> +};
>
> There are couple or more buffer sizes scattered in this patchset, maybe it
> would be better to consolidate them in one place so it can be easily tuned.
I see what I can do.
> For instance, since it is used with memcpy below, maybe it would be better
> to use a size that compiler can inline (it would be arch-dependent, but
> using a size that most usual architecture inline is a net gain).
It would need additional optimization hints for GCC, I believe.
>> +void
>> +__printf_buffer_flush_asprintf (struct __printf_buffer_asprintf *buf)
>> +{
>> + size_t current_pos = buf->base.write_ptr - buf->base.write_base;
>> + if (current_pos >= INT_MAX)
>
> Shouldn't it be SSIZE_MAX?
Nope, asprintf has the same incorrect return type as printf. 8-(
>
>> + {
>> + /* The result is not representable. No need to continue. */
>> + __set_errno (EOVERFLOW);
>> + __printf_buffer_mark_failed (&buf->base);
>> + return;
>> + }
>> +
>> + size_t current_size = buf->base.write_end - buf->base.write_base;
>> + /* Implement an exponentiatial sizing policy. Keep the size
>
> s/exponentiatial/exponential
Fixed.
>> + congruent 8 (mod 16), to account for the footer in glibc
>> + malloc. */
>> + size_t new_size = ((current_size + current_size / 2) & -15) | 8;
>
> Maybe use ALIGN_UP ((current_size + current_size / 2), 16) here?
Changed.
Thanks,
Florian
More information about the Libc-alpha
mailing list