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