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