2 * Copyright (C) 2017 - Jérémie Galarneau <jeremie.galarneau@efficios.com>
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License, version 2.1 only,
6 * as published by the Free Software Foundation.
8 * This program is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program; if not, write to the Free Software Foundation,
15 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 #include <common/dynamic-buffer.h>
19 #include <common/macros.h>
20 #include <common/utils.h>
24 * Round to (upper) power of two, val is returned if it already is a power of
28 size_t round_to_power_of_2(size_t val
)
33 order
= utils_get_count_order_u64(val
);
35 rounded
= (1ULL << order
);
36 assert(rounded
>= val
);
41 void lttng_dynamic_buffer_init(struct lttng_dynamic_buffer
*buffer
)
44 memset(buffer
, 0, sizeof(*buffer
));
47 int lttng_dynamic_buffer_append(struct lttng_dynamic_buffer
*buffer
,
48 const void *buf
, size_t len
)
52 if (!buffer
|| (!buf
&& len
)) {
58 /* Not an error, no-op. */
62 assert(buffer
->_capacity
>= buffer
->size
);
63 if (buffer
->_capacity
< (len
+ buffer
->size
)) {
64 ret
= lttng_dynamic_buffer_set_capacity(buffer
,
66 (len
- (buffer
->_capacity
- buffer
->size
)));
72 memcpy(buffer
->data
+ buffer
->size
, buf
, len
);
78 int lttng_dynamic_buffer_append_buffer(struct lttng_dynamic_buffer
*dst_buffer
,
79 struct lttng_dynamic_buffer
*src_buffer
)
83 if (!dst_buffer
|| !src_buffer
) {
88 ret
= lttng_dynamic_buffer_append(dst_buffer
, src_buffer
->data
,
94 int lttng_dynamic_buffer_set_size(struct lttng_dynamic_buffer
*buffer
,
103 if (new_size
== buffer
->size
) {
107 if (new_size
> buffer
->_capacity
) {
108 size_t original_size
= buffer
->size
;
109 size_t original_capacity
= buffer
->_capacity
;
111 ret
= lttng_dynamic_buffer_set_capacity(buffer
, new_size
);
117 * Zero-initialize the space that was left in the buffer at the
118 * before we increased its capacity (original capacity - original size).
119 * The newly acquired capacity (new capacity - original capacity)
120 * is zeroed by lttng_dynamic_buffer_set_capacity().
122 memset(buffer
->data
+ original_size
, 0,
123 original_capacity
- original_size
);
124 } else if (new_size
> buffer
->size
) {
125 memset(buffer
->data
+ buffer
->size
, 0, new_size
- buffer
->size
);
128 * Shrinking size. There is no need to zero-out the newly
129 * released memory as it will either be:
130 * - overwritten by lttng_dynamic_buffer_append,
131 * - expanded later, which will zero-out the memory
133 * Users of external APIs are encouraged to set the buffer's
134 * size _before_ making such calls.
137 buffer
->size
= new_size
;
142 int lttng_dynamic_buffer_set_capacity(struct lttng_dynamic_buffer
*buffer
,
143 size_t demanded_capacity
)
147 size_t new_capacity
= round_to_power_of_2(demanded_capacity
);
149 if (!buffer
|| demanded_capacity
< buffer
->size
) {
151 * Shrinking a buffer's size by changing its capacity is
158 if (new_capacity
== buffer
->_capacity
) {
162 /* Memory is initialized by the size increases. */
163 new_buf
= realloc(buffer
->data
, new_capacity
);
168 buffer
->data
= new_buf
;
169 buffer
->_capacity
= new_capacity
;
174 /* Release any memory used by the dynamic buffer. */
175 void lttng_dynamic_buffer_reset(struct lttng_dynamic_buffer
*buffer
)
181 buffer
->_capacity
= 0;
This page took 0.033084 seconds and 4 git commands to generate.