2 * Copyright (C) 2017 - Jérémie Galarneau <jeremie.galarneau@efficios.com>
4 * This library 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 library 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 library; 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 size_t round_to_power_of_2(size_t val
)
29 order
= utils_get_count_order_u64(val
);
31 rounded
= (1ULL << order
);
32 assert(rounded
>= val
);
37 void lttng_dynamic_buffer_init(struct lttng_dynamic_buffer
*buffer
)
40 memset(buffer
, 0, sizeof(*buffer
));
43 int lttng_dynamic_buffer_append(struct lttng_dynamic_buffer
*buffer
,
44 const void *buf
, size_t len
)
48 if (!buffer
|| (!buf
&& len
)) {
54 /* Not an error, no-op. */
58 if ((buffer
->capacity
- buffer
->size
) < len
) {
59 ret
= lttng_dynamic_buffer_set_capacity(buffer
,
61 (len
- (buffer
->capacity
- buffer
->size
)));
67 memcpy(buffer
->data
+ buffer
->size
, buf
, len
);
73 int lttng_dynamic_buffer_set_size(struct lttng_dynamic_buffer
*buffer
,
82 if (new_size
== buffer
->size
) {
86 if (new_size
> buffer
->capacity
) {
87 ret
= lttng_dynamic_buffer_set_capacity(buffer
, new_size
);
91 } else if (new_size
> buffer
->size
) {
92 memset(buffer
->data
+ buffer
->size
, 0, new_size
- buffer
->size
);
93 buffer
->size
= new_size
;
96 * Shrinking size. There is no need to zero-out the newly
97 * released memory as it will either be:
98 * - overwritten by lttng_dynamic_buffer_append,
99 * - expanded later, which will zero-out the memory
101 * Users of external APIs are encouraged to set the buffer's
102 * size _before_ making such calls.
105 buffer
->size
= new_size
;
110 int lttng_dynamic_buffer_set_capacity(struct lttng_dynamic_buffer
*buffer
,
114 size_t rounded_capacity
= round_to_power_of_2(new_capacity
);
116 if (!buffer
|| new_capacity
< buffer
->size
) {
121 if (rounded_capacity
== buffer
->capacity
) {
126 buffer
->data
= zmalloc(rounded_capacity
);
134 new_buf
= realloc(buffer
->data
, rounded_capacity
);
136 if (rounded_capacity
> buffer
->capacity
) {
137 memset(new_buf
+ buffer
->capacity
, 0,
138 rounded_capacity
- buffer
->capacity
);
141 /* Realloc failed, try to acquire a new block. */
142 new_buf
= zmalloc(rounded_capacity
);
147 memcpy(new_buf
, buffer
->data
, buffer
->size
);
150 buffer
->data
= new_buf
;
152 buffer
->capacity
= rounded_capacity
;
157 /* Release any memory used by the dynamic buffer. */
158 void lttng_dynamic_buffer_reset(struct lttng_dynamic_buffer
*buffer
)
164 buffer
->capacity
= 0;
This page took 0.03269 seconds and 5 git commands to generate.