liblttng-ctl: use export list to define exported symbols
[lttng-tools.git] / src / common / dynamic-buffer.c
CommitLineData
5966417e 1/*
ab5be9fa 2 * Copyright (C) 2017 Jérémie Galarneau <jeremie.galarneau@efficios.com>
5966417e 3 *
ab5be9fa 4 * SPDX-License-Identifier: LGPL-2.1-only
5966417e 5 *
5966417e
JG
6 */
7
8#include <common/dynamic-buffer.h>
fbd55aae 9#include <common/buffer-view.h>
5966417e 10#include <common/utils.h>
5966417e 11
df94ef0f
JG
12/*
13 * Round to (upper) power of two, val is returned if it already is a power of
14 * two.
15 */
5966417e
JG
16static
17size_t round_to_power_of_2(size_t val)
18{
5966417e 19 size_t rounded;
12aacdf6 20 const int order = utils_get_count_order_u64(val);
5966417e 21
a0377dfe 22 LTTNG_ASSERT(order >= 0);
5966417e 23 rounded = (1ULL << order);
a0377dfe 24 LTTNG_ASSERT(rounded >= val);
5966417e
JG
25
26 return rounded;
27}
28
29void lttng_dynamic_buffer_init(struct lttng_dynamic_buffer *buffer)
30{
a0377dfe 31 LTTNG_ASSERT(buffer);
5966417e
JG
32 memset(buffer, 0, sizeof(*buffer));
33}
34
35int lttng_dynamic_buffer_append(struct lttng_dynamic_buffer *buffer,
36 const void *buf, size_t len)
37{
38 int ret = 0;
39
40 if (!buffer || (!buf && len)) {
41 ret = -1;
42 goto end;
43 }
44
45 if (len == 0) {
46 /* Not an error, no-op. */
47 goto end;
48 }
49
a0377dfe 50 LTTNG_ASSERT(buffer->_capacity >= buffer->size);
63557623 51 if (buffer->_capacity < (len + buffer->size)) {
5966417e 52 ret = lttng_dynamic_buffer_set_capacity(buffer,
63557623
JG
53 buffer->_capacity +
54 (len - (buffer->_capacity - buffer->size)));
5966417e
JG
55 if (ret) {
56 goto end;
57 }
58 }
59
60 memcpy(buffer->data + buffer->size, buf, len);
61 buffer->size += len;
62end:
63 return ret;
64}
65
66int lttng_dynamic_buffer_append_buffer(struct lttng_dynamic_buffer *dst_buffer,
38b6c4f5 67 const struct lttng_dynamic_buffer *src_buffer)
5966417e
JG
68{
69 int ret;
70
71 if (!dst_buffer || !src_buffer) {
72 ret = -1;
73 goto end;
74 }
75
76 ret = lttng_dynamic_buffer_append(dst_buffer, src_buffer->data,
77 src_buffer->size);
78end:
79 return ret;
80}
81
fbd55aae
JG
82int lttng_dynamic_buffer_append_view(struct lttng_dynamic_buffer *buffer,
83 const struct lttng_buffer_view *src)
84{
85 int ret;
86
87 if (!buffer || !src) {
88 ret = -1;
89 goto end;
90 }
91
92 ret = lttng_dynamic_buffer_append(buffer, src->data,
93 src->size);
94end:
95 return ret;
96}
97
5966417e
JG
98int lttng_dynamic_buffer_set_size(struct lttng_dynamic_buffer *buffer,
99 size_t new_size)
100{
101 int ret = 0;
102
103 if (!buffer) {
104 goto end;
105 }
106
107 if (new_size == buffer->size) {
108 goto end;
109 }
110
63557623 111 if (new_size > buffer->_capacity) {
5966417e
JG
112 ret = lttng_dynamic_buffer_set_capacity(buffer, new_size);
113 if (ret) {
114 goto end;
115 }
1c6def05 116
6ee96b4d 117 memset(buffer->data + buffer->size, 0, new_size - buffer->size);
5966417e
JG
118 } else if (new_size > buffer->size) {
119 memset(buffer->data + buffer->size, 0, new_size - buffer->size);
120 } else {
121 /*
122 * Shrinking size. There is no need to zero-out the newly
123 * released memory as it will either be:
124 * - overwritten by lttng_dynamic_buffer_append,
125 * - expanded later, which will zero-out the memory
126 *
127 * Users of external APIs are encouraged to set the buffer's
128 * size _before_ making such calls.
129 */
130 }
12aacdf6 131
5966417e
JG
132 buffer->size = new_size;
133end:
134 return ret;
135}
136
137int lttng_dynamic_buffer_set_capacity(struct lttng_dynamic_buffer *buffer,
fc804d0f 138 size_t demanded_capacity)
5966417e
JG
139{
140 int ret = 0;
fc804d0f 141 void *new_buf;
e9347dad
JG
142 size_t new_capacity = demanded_capacity ?
143 round_to_power_of_2(demanded_capacity) : 0;
5966417e 144
fc804d0f
JG
145 if (!buffer || demanded_capacity < buffer->size) {
146 /*
147 * Shrinking a buffer's size by changing its capacity is
148 * unsupported.
149 */
5966417e
JG
150 ret = -1;
151 goto end;
152 }
153
63557623 154 if (new_capacity == buffer->_capacity) {
5966417e
JG
155 goto end;
156 }
157
fc804d0f
JG
158 /* Memory is initialized by the size increases. */
159 new_buf = realloc(buffer->data, new_capacity);
160 if (!new_buf) {
161 ret = -1;
162 goto end;
5966417e 163 }
12aacdf6 164
fc804d0f 165 buffer->data = new_buf;
63557623 166 buffer->_capacity = new_capacity;
5966417e
JG
167end:
168 return ret;
169}
170
171/* Release any memory used by the dynamic buffer. */
172void lttng_dynamic_buffer_reset(struct lttng_dynamic_buffer *buffer)
173{
174 if (!buffer) {
175 return;
176 }
12aacdf6 177
5966417e 178 buffer->size = 0;
63557623 179 buffer->_capacity = 0;
5966417e 180 free(buffer->data);
427d8469 181 buffer->data = NULL;
5966417e 182}
201bd415 183
201bd415
JG
184size_t lttng_dynamic_buffer_get_capacity_left(
185 struct lttng_dynamic_buffer *buffer)
186{
187 if (!buffer) {
188 return 0;
189 }
12aacdf6 190
201bd415
JG
191 return buffer->_capacity - buffer->size;
192}
This page took 0.044821 seconds and 4 git commands to generate.