Force usage of assert() condition when NDEBUG is defined
[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
c90647fe 29LTTNG_HIDDEN
5966417e
JG
30void lttng_dynamic_buffer_init(struct lttng_dynamic_buffer *buffer)
31{
a0377dfe 32 LTTNG_ASSERT(buffer);
5966417e
JG
33 memset(buffer, 0, sizeof(*buffer));
34}
35
c90647fe 36LTTNG_HIDDEN
5966417e
JG
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
a0377dfe 52 LTTNG_ASSERT(buffer->_capacity >= buffer->size);
63557623 53 if (buffer->_capacity < (len + buffer->size)) {
5966417e 54 ret = lttng_dynamic_buffer_set_capacity(buffer,
63557623
JG
55 buffer->_capacity +
56 (len - (buffer->_capacity - buffer->size)));
5966417e
JG
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
c90647fe 68LTTNG_HIDDEN
5966417e 69int lttng_dynamic_buffer_append_buffer(struct lttng_dynamic_buffer *dst_buffer,
38b6c4f5 70 const struct lttng_dynamic_buffer *src_buffer)
5966417e
JG
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
fbd55aae
JG
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
c90647fe 102LTTNG_HIDDEN
5966417e
JG
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
63557623 116 if (new_size > buffer->_capacity) {
5966417e
JG
117 ret = lttng_dynamic_buffer_set_capacity(buffer, new_size);
118 if (ret) {
119 goto end;
120 }
1c6def05 121
6ee96b4d 122 memset(buffer->data + buffer->size, 0, new_size - buffer->size);
5966417e
JG
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 }
12aacdf6 136
5966417e
JG
137 buffer->size = new_size;
138end:
139 return ret;
140}
141
c90647fe 142LTTNG_HIDDEN
5966417e 143int lttng_dynamic_buffer_set_capacity(struct lttng_dynamic_buffer *buffer,
fc804d0f 144 size_t demanded_capacity)
5966417e
JG
145{
146 int ret = 0;
fc804d0f 147 void *new_buf;
e9347dad
JG
148 size_t new_capacity = demanded_capacity ?
149 round_to_power_of_2(demanded_capacity) : 0;
5966417e 150
fc804d0f
JG
151 if (!buffer || demanded_capacity < buffer->size) {
152 /*
153 * Shrinking a buffer's size by changing its capacity is
154 * unsupported.
155 */
5966417e
JG
156 ret = -1;
157 goto end;
158 }
159
63557623 160 if (new_capacity == buffer->_capacity) {
5966417e
JG
161 goto end;
162 }
163
fc804d0f
JG
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;
5966417e 169 }
12aacdf6 170
fc804d0f 171 buffer->data = new_buf;
63557623 172 buffer->_capacity = new_capacity;
5966417e
JG
173end:
174 return ret;
175}
176
177/* Release any memory used by the dynamic buffer. */
c90647fe 178LTTNG_HIDDEN
5966417e
JG
179void lttng_dynamic_buffer_reset(struct lttng_dynamic_buffer *buffer)
180{
181 if (!buffer) {
182 return;
183 }
12aacdf6 184
5966417e 185 buffer->size = 0;
63557623 186 buffer->_capacity = 0;
5966417e 187 free(buffer->data);
427d8469 188 buffer->data = NULL;
5966417e 189}
201bd415
JG
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 }
12aacdf6 198
201bd415
JG
199 return buffer->_capacity - buffer->size;
200}
This page took 0.046308 seconds and 4 git commands to generate.