[Mesa-dev] [PATCH 3/3] u_dynarray: turn util_dynarray_{grow, resize} into element-oriented macros
Haehnle, Nicolai
Nicolai.Haehnle at amd.com
Mon May 13 14:28:08 UTC 2019
On 04.05.19 17:55, Gustaw Smolarczyk wrote:
> sob., 4 maj 2019 o 15:25 Nicolai Hähnle <nhaehnle at gmail.com> napisał(a):
>> static inline void
>> util_dynarray_clone(struct util_dynarray *buf, void *mem_ctx,
>> struct util_dynarray *from_buf)
>> {
>> util_dynarray_init(buf, mem_ctx);
>> - util_dynarray_resize(buf, from_buf->size);
>> + util_dynarray_resize_bytes(buf, 1, from_buf->size);
>
> Just a nit: couldn't you swap the arguments to resize_bytes? The
> compiler will probably figure it out, but you are performing the
> following operation in the resize_bytes function:
>
> if (unlikely(1 > UINT_MAX / from_buf->size))
>
> which is a division of a constant by a variable. With the arguments
> swapped it would be:
>
> if (unlikely(from_buf->size > UINT_MAX / 1))
>
> which should be easier to optimize away (also in non-optimized
> version). This way, the eltsize parameter will probably always be a
> constant too.
Good catch, I've fixed that locally.
Cheers,
Nicolai
>
> Regards,
> Gustaw Smolarczyk
>
>> memcpy(buf->data, from_buf->data, from_buf->size);
>> }
>>
>> static inline void *
>> -util_dynarray_grow(struct util_dynarray *buf, int diff)
>> +util_dynarray_grow_bytes(struct util_dynarray *buf, unsigned ngrow, size_t eltsize)
>> {
>> - return util_dynarray_resize(buf, buf->size + diff);
>> + unsigned growbytes = ngrow * eltsize;
>> +
>> + if (unlikely(ngrow > (UINT_MAX / eltsize) ||
>> + growbytes > UINT_MAX - buf->size)) {
>> + util_dynarray_fini(buf);
>> + return 0;
>> + }
>> +
>> + unsigned newsize = buf->size + growbytes;
>> + void *p = util_dynarray_ensure_cap(buf, newsize);
>> + buf->size = newsize;
>> +
>> + return p;
>> }
>>
>> static inline void
>> util_dynarray_trim(struct util_dynarray *buf)
>> {
>> if (buf->size != buf->capacity) {
>> if (buf->size) {
>> if (buf->mem_ctx) {
>> buf->data = reralloc_size(buf->mem_ctx, buf->data, buf->size);
>> } else {
>> @@ -146,21 +159,24 @@ util_dynarray_trim(struct util_dynarray *buf)
>> ralloc_free(buf->data);
>> } else {
>> free(buf->data);
>> }
>> buf->data = NULL;
>> buf->capacity = 0;
>> }
>> }
>> }
>>
>> -#define util_dynarray_append(buf, type, v) do {type __v = (v); memcpy(util_dynarray_grow((buf), sizeof(type)), &__v, sizeof(type));} while(0)
>> +#define util_dynarray_append(buf, type, v) do {type __v = (v); memcpy(util_dynarray_grow_bytes((buf), 1, sizeof(type)), &__v, sizeof(type));} while(0)
>> +/* Returns a pointer to the space of the first new element (in case of growth) or NULL on failure. */
>> +#define util_dynarray_resize(buf, type, nelts) util_dynarray_resize_bytes(buf, (nelts), sizeof(type))
>> +#define util_dynarray_grow(buf, type, ngrow) util_dynarray_grow_bytes(buf, (ngrow), sizeof(type))
>> #define util_dynarray_top_ptr(buf, type) (type*)((char*)(buf)->data + (buf)->size - sizeof(type))
>> #define util_dynarray_top(buf, type) *util_dynarray_top_ptr(buf, type)
>> #define util_dynarray_pop_ptr(buf, type) (type*)((char*)(buf)->data + ((buf)->size -= sizeof(type)))
>> #define util_dynarray_pop(buf, type) *util_dynarray_pop_ptr(buf, type)
>> #define util_dynarray_contains(buf, type) ((buf)->size >= sizeof(type))
>> #define util_dynarray_element(buf, type, idx) ((type*)(buf)->data + (idx))
>> #define util_dynarray_begin(buf) ((buf)->data)
>> #define util_dynarray_end(buf) ((void*)util_dynarray_element((buf), char, (buf)->size))
>> #define util_dynarray_num_elements(buf, type) ((buf)->size / sizeof(type))
>>
>> --
>> 2.20.1
>>
>> _______________________________________________
>> mesa-dev mailing list
>> mesa-dev at lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
More information about the mesa-dev
mailing list