X-Git-Url: http://git.efficios.com/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fcommon%2Fdynamic-buffer.c;h=05d3022af19d0e4e8ef9d0527a6069394131eb6b;hp=f34ae8c492d6bba76818c7e47c004c6f72894bff;hb=df94ef0f8c4b890d961e5e69b9945035de03a05b;hpb=830630679a7fb4bc9b3c7679b5168ee6c03104f1 diff --git a/src/common/dynamic-buffer.c b/src/common/dynamic-buffer.c index f34ae8c49..05d3022af 100644 --- a/src/common/dynamic-buffer.c +++ b/src/common/dynamic-buffer.c @@ -20,6 +20,10 @@ #include #include +/* + * Round to (upper) power of two, val is returned if it already is a power of + * two. + */ static size_t round_to_power_of_2(size_t val) { @@ -55,6 +59,7 @@ int lttng_dynamic_buffer_append(struct lttng_dynamic_buffer *buffer, goto end; } + assert(buffer->capacity >= buffer->size); if (buffer->capacity < (len + buffer->size)) { ret = lttng_dynamic_buffer_set_capacity(buffer, buffer->capacity + @@ -100,10 +105,22 @@ int lttng_dynamic_buffer_set_size(struct lttng_dynamic_buffer *buffer, } if (new_size > buffer->capacity) { + size_t original_size = buffer->size; + size_t original_capacity = buffer->capacity; + ret = lttng_dynamic_buffer_set_capacity(buffer, new_size); if (ret) { goto end; } + + /* + * Zero-initialize the space that was left in the buffer at the + * before we increased its capacity (original capacity - original size). + * The newly acquired capacity (new capacity - original capacity) + * is zeroed by lttng_dynamic_buffer_set_capacity(). + */ + memset(buffer->data + original_size, 0, + original_capacity - original_size); } else if (new_size > buffer->size) { memset(buffer->data + buffer->size, 0, new_size - buffer->size); } else { @@ -123,48 +140,33 @@ end: } int lttng_dynamic_buffer_set_capacity(struct lttng_dynamic_buffer *buffer, - size_t new_capacity) + size_t demanded_capacity) { int ret = 0; - size_t rounded_capacity = round_to_power_of_2(new_capacity); + void *new_buf; + size_t new_capacity = round_to_power_of_2(demanded_capacity); - if (!buffer || new_capacity < buffer->size) { + if (!buffer || demanded_capacity < buffer->size) { + /* + * Shrinking a buffer's size by changing its capacity is + * unsupported. + */ ret = -1; goto end; } - if (rounded_capacity == buffer->capacity) { + if (new_capacity == buffer->capacity) { goto end; } - if (!buffer->data) { - buffer->data = zmalloc(rounded_capacity); - if (!buffer->data) { - ret = -1; - goto end; - } - } else { - void *new_buf; - - new_buf = realloc(buffer->data, rounded_capacity); - if (new_buf) { - if (rounded_capacity > buffer->capacity) { - memset(new_buf + buffer->capacity, 0, - rounded_capacity - buffer->capacity); - } - } else { - /* Realloc failed, try to acquire a new block. */ - new_buf = zmalloc(rounded_capacity); - if (!new_buf) { - ret = -1; - goto end; - } - memcpy(new_buf, buffer->data, buffer->size); - free(buffer->data); - } - buffer->data = new_buf; + /* Memory is initialized by the size increases. */ + new_buf = realloc(buffer->data, new_capacity); + if (!new_buf) { + ret = -1; + goto end; } - buffer->capacity = rounded_capacity; + buffer->data = new_buf; + buffer->capacity = new_capacity; end: return ret; }