cleanup: explicitly mark unused parameters (-Wunused-parameter)
[lttng-ust.git] / liblttng-ust-java-agent / jni / common / lttng_ust_context.c
CommitLineData
8ab5c06b 1/*
c0c0989a 2 * SPDX-License-Identifier: LGPL-2.1-only
8ab5c06b 3 *
c0c0989a
MJ
4 * Copyright (C) 2016 EfficiOS Inc.
5 * Copyright (C) 2016 Alexandre Montplaisir <alexmonthy@efficios.com>
6 * Copyright (C) 2016 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
8ab5c06b
AM
7 */
8
9#include "org_lttng_ust_agent_context_LttngContextApi.h"
10
11#include <string.h>
12#include <inttypes.h>
13#include <lttng/ust-events.h>
ef6ae9f9 14#include <lttng/ringbuffer-context.h>
ae4b659d 15#include <ust-context-provider.h>
8ab5c06b 16
864a1eda 17#include "ust-helper.h"
8ab5c06b
AM
18#include "lttng_ust_context.h"
19
8ab5c06b
AM
20enum lttng_ust_jni_type {
21 JNI_TYPE_NULL = 0,
22 JNI_TYPE_INTEGER = 1,
23 JNI_TYPE_LONG = 2,
24 JNI_TYPE_DOUBLE = 3,
25 JNI_TYPE_FLOAT = 4,
26 JNI_TYPE_BYTE = 5,
27 JNI_TYPE_SHORT = 6,
28 JNI_TYPE_BOOLEAN = 7,
29 JNI_TYPE_STRING = 8,
30};
31
b1ca4c5f
AM
32struct lttng_ust_jni_ctx_entry {
33 int32_t context_name_offset;
8ab5c06b
AM
34 char type; /* enum lttng_ust_jni_type */
35 union {
36 int32_t _integer;
37 int64_t _long;
38 double _double;
39 float _float;
40 signed char _byte;
41 int16_t _short;
42 signed char _boolean;
b1ca4c5f 43 int32_t _string_offset;
8ab5c06b
AM
44 } value;
45} __attribute__((packed));
46
47/* TLS passing context info from JNI to callbacks. */
16adecf1 48__thread struct lttng_ust_jni_tls lttng_ust_context_info_tls;
8ab5c06b 49
b1ca4c5f
AM
50static const char *get_ctx_string_at_offset(int32_t offset)
51{
52 signed char *ctx_strings_array = lttng_ust_context_info_tls.ctx_strings;
53
54 if (offset < 0 || offset >= lttng_ust_context_info_tls.ctx_strings_len) {
55 return NULL;
56 }
57 return (const char *) (ctx_strings_array + offset);
58}
59
60static struct lttng_ust_jni_ctx_entry *lookup_ctx_by_name(const char *ctx_name)
8ab5c06b 61{
b1ca4c5f
AM
62 struct lttng_ust_jni_ctx_entry *ctx_entries_array = lttng_ust_context_info_tls.ctx_entries;
63 int i, len = lttng_ust_context_info_tls.ctx_entries_len / sizeof(struct lttng_ust_jni_ctx_entry);
8ab5c06b
AM
64
65 for (i = 0; i < len; i++) {
b1ca4c5f
AM
66 int32_t offset = ctx_entries_array[i].context_name_offset;
67 const char *string = get_ctx_string_at_offset(offset);
68
69 if (string && strcmp(string, ctx_name) == 0) {
70 return &ctx_entries_array[i];
71 }
8ab5c06b
AM
72 }
73 return NULL;
8ab5c06b
AM
74}
75
daacdbfc 76static size_t get_size_cb(struct lttng_ust_ctx_field *field, size_t offset)
8ab5c06b 77{
b1ca4c5f 78 struct lttng_ust_jni_ctx_entry *jctx;
8ab5c06b 79 size_t size = 0;
3d66e98c 80 const char *ctx_name = field->event_field->name;
8ab5c06b
AM
81 enum lttng_ust_jni_type jni_type;
82
b1ca4c5f 83
dc325c1d 84 size += lttng_ust_lib_ring_buffer_align(offset, lttng_ust_rb_alignof(char));
8ab5c06b
AM
85 size += sizeof(char); /* tag */
86 jctx = lookup_ctx_by_name(ctx_name);
87 if (!jctx) {
88 jni_type = JNI_TYPE_NULL;
89 } else {
90 jni_type = jctx->type;
91 }
92 switch (jni_type) {
93 case JNI_TYPE_NULL:
94 break;
95 case JNI_TYPE_INTEGER:
dc325c1d 96 size += lttng_ust_lib_ring_buffer_align(offset, lttng_ust_rb_alignof(int32_t));
8ab5c06b
AM
97 size += sizeof(int32_t); /* variant */
98 break;
99 case JNI_TYPE_LONG:
dc325c1d 100 size += lttng_ust_lib_ring_buffer_align(offset, lttng_ust_rb_alignof(int64_t));
8ab5c06b
AM
101 size += sizeof(int64_t); /* variant */
102 break;
103 case JNI_TYPE_DOUBLE:
dc325c1d 104 size += lttng_ust_lib_ring_buffer_align(offset, lttng_ust_rb_alignof(double));
8ab5c06b
AM
105 size += sizeof(double); /* variant */
106 break;
107 case JNI_TYPE_FLOAT:
dc325c1d 108 size += lttng_ust_lib_ring_buffer_align(offset, lttng_ust_rb_alignof(float));
8ab5c06b
AM
109 size += sizeof(float); /* variant */
110 break;
111 case JNI_TYPE_SHORT:
dc325c1d 112 size += lttng_ust_lib_ring_buffer_align(offset, lttng_ust_rb_alignof(int16_t));
8ab5c06b
AM
113 size += sizeof(int16_t); /* variant */
114 break;
115 case JNI_TYPE_BYTE: /* Fall-through. */
116 case JNI_TYPE_BOOLEAN:
dc325c1d 117 size += lttng_ust_lib_ring_buffer_align(offset, lttng_ust_rb_alignof(char));
8ab5c06b
AM
118 size += sizeof(char); /* variant */
119 break;
120 case JNI_TYPE_STRING:
b1ca4c5f
AM
121 {
122 /* The value is an offset, the string is in the "strings" array */
123 int32_t string_offset = jctx->value._string_offset;
124 const char *string = get_ctx_string_at_offset(string_offset);
125
126 if (string) {
127 size += strlen(string) + 1;
128 }
8ab5c06b 129 break;
b1ca4c5f 130 }
8ab5c06b
AM
131 default:
132 abort();
133 }
134 return size;
135
136}
137
daacdbfc 138static void record_cb(struct lttng_ust_ctx_field *field,
8ab5c06b 139 struct lttng_ust_lib_ring_buffer_ctx *ctx,
e016c06a 140 struct lttng_ust_channel_buffer *lttng_chan_buf)
8ab5c06b 141{
b1ca4c5f 142 struct lttng_ust_jni_ctx_entry *jctx;
3d66e98c 143 const char *ctx_name = field->event_field->name;
8ab5c06b
AM
144 enum lttng_ust_jni_type jni_type;
145 char sel_char;
146
147 jctx = lookup_ctx_by_name(ctx_name);
148 if (!jctx) {
149 jni_type = JNI_TYPE_NULL;
150 } else {
151 jni_type = jctx->type;
152 }
153
154 switch (jni_type) {
155 case JNI_TYPE_NULL:
156 sel_char = LTTNG_UST_DYNAMIC_TYPE_NONE;
8936b6c0 157 lttng_chan_buf->ops->event_write(ctx, &sel_char, sizeof(sel_char), lttng_ust_rb_alignof(char));
8ab5c06b
AM
158 break;
159 case JNI_TYPE_INTEGER:
160 {
161 int32_t v = jctx->value._integer;
162
163 sel_char = LTTNG_UST_DYNAMIC_TYPE_S32;
8936b6c0
MD
164 lttng_chan_buf->ops->event_write(ctx, &sel_char, sizeof(sel_char), lttng_ust_rb_alignof(char));
165 lttng_chan_buf->ops->event_write(ctx, &v, sizeof(v), lttng_ust_rb_alignof(v));
8ab5c06b
AM
166 break;
167 }
168 case JNI_TYPE_LONG:
169 {
170 int64_t v = jctx->value._long;
171
172 sel_char = LTTNG_UST_DYNAMIC_TYPE_S64;
8936b6c0
MD
173 lttng_chan_buf->ops->event_write(ctx, &sel_char, sizeof(sel_char), lttng_ust_rb_alignof(char));
174 lttng_chan_buf->ops->event_write(ctx, &v, sizeof(v), lttng_ust_rb_alignof(v));
8ab5c06b
AM
175 break;
176 }
177 case JNI_TYPE_DOUBLE:
178 {
179 double v = jctx->value._double;
180
181 sel_char = LTTNG_UST_DYNAMIC_TYPE_DOUBLE;
8936b6c0
MD
182 lttng_chan_buf->ops->event_write(ctx, &sel_char, sizeof(sel_char), lttng_ust_rb_alignof(char));
183 lttng_chan_buf->ops->event_write(ctx, &v, sizeof(v), lttng_ust_rb_alignof(v));
8ab5c06b
AM
184 break;
185 }
186 case JNI_TYPE_FLOAT:
187 {
188 float v = jctx->value._float;
189
190 sel_char = LTTNG_UST_DYNAMIC_TYPE_FLOAT;
8936b6c0
MD
191 lttng_chan_buf->ops->event_write(ctx, &sel_char, sizeof(sel_char), lttng_ust_rb_alignof(char));
192 lttng_chan_buf->ops->event_write(ctx, &v, sizeof(v), lttng_ust_rb_alignof(v));
8ab5c06b
AM
193 break;
194 }
195 case JNI_TYPE_SHORT:
196 {
197 int16_t v = jctx->value._short;
198
199 sel_char = LTTNG_UST_DYNAMIC_TYPE_S16;
8936b6c0
MD
200 lttng_chan_buf->ops->event_write(ctx, &sel_char, sizeof(sel_char), lttng_ust_rb_alignof(char));
201 lttng_chan_buf->ops->event_write(ctx, &v, sizeof(v), lttng_ust_rb_alignof(v));
8ab5c06b
AM
202 break;
203 }
204 case JNI_TYPE_BYTE:
205 {
206 char v = jctx->value._byte;
207
208 sel_char = LTTNG_UST_DYNAMIC_TYPE_S8;
8936b6c0
MD
209 lttng_chan_buf->ops->event_write(ctx, &sel_char, sizeof(sel_char), lttng_ust_rb_alignof(char));
210 lttng_chan_buf->ops->event_write(ctx, &v, sizeof(v), lttng_ust_rb_alignof(v));
8ab5c06b
AM
211 break;
212 }
213 case JNI_TYPE_BOOLEAN:
214 {
215 char v = jctx->value._boolean;
216
217 sel_char = LTTNG_UST_DYNAMIC_TYPE_S8;
8936b6c0
MD
218 lttng_chan_buf->ops->event_write(ctx, &sel_char, sizeof(sel_char), lttng_ust_rb_alignof(char));
219 lttng_chan_buf->ops->event_write(ctx, &v, sizeof(v), lttng_ust_rb_alignof(v));
8ab5c06b
AM
220 break;
221 }
222 case JNI_TYPE_STRING:
223 {
b1ca4c5f
AM
224 int32_t offset = jctx->value._string_offset;
225 const char *str = get_ctx_string_at_offset(offset);
8ab5c06b 226
b1ca4c5f
AM
227 if (str) {
228 sel_char = LTTNG_UST_DYNAMIC_TYPE_STRING;
229 } else {
230 sel_char = LTTNG_UST_DYNAMIC_TYPE_NONE;
231 }
8936b6c0 232 lttng_chan_buf->ops->event_write(ctx, &sel_char, sizeof(sel_char), lttng_ust_rb_alignof(char));
b1ca4c5f 233 if (str) {
8936b6c0 234 lttng_chan_buf->ops->event_write(ctx, str, strlen(str) + 1, 1);
b1ca4c5f 235 }
8ab5c06b
AM
236 break;
237 }
238 default:
239 abort();
240 }
241}
242
daacdbfc
MD
243static void get_value_cb(struct lttng_ust_ctx_field *field,
244 struct lttng_ust_ctx_value *value)
8ab5c06b 245{
b1ca4c5f 246 struct lttng_ust_jni_ctx_entry *jctx;
3d66e98c 247 const char *ctx_name = field->event_field->name;
8ab5c06b
AM
248 enum lttng_ust_jni_type jni_type;
249
250 jctx = lookup_ctx_by_name(ctx_name);
251 if (!jctx) {
252 jni_type = JNI_TYPE_NULL;
253 } else {
254 jni_type = jctx->type;
255 }
256
257 switch (jni_type) {
258 case JNI_TYPE_NULL:
259 value->sel = LTTNG_UST_DYNAMIC_TYPE_NONE;
260 break;
261 case JNI_TYPE_INTEGER:
262 value->sel = LTTNG_UST_DYNAMIC_TYPE_S64;
263 value->u.s64 = (int64_t) jctx->value._integer;
264 break;
265 case JNI_TYPE_LONG:
266 value->sel = LTTNG_UST_DYNAMIC_TYPE_S64;
267 value->u.s64 = jctx->value._long;
268 break;
269 case JNI_TYPE_DOUBLE:
270 value->sel = LTTNG_UST_DYNAMIC_TYPE_DOUBLE;
271 value->u.d = jctx->value._double;
272 break;
273 case JNI_TYPE_FLOAT:
274 value->sel = LTTNG_UST_DYNAMIC_TYPE_DOUBLE;
275 value->u.d = (double) jctx->value._float;
276 break;
277 case JNI_TYPE_SHORT:
278 value->sel = LTTNG_UST_DYNAMIC_TYPE_S64;
279 value->u.s64 = (int64_t) jctx->value._short;
280 break;
281 case JNI_TYPE_BYTE:
282 value->sel = LTTNG_UST_DYNAMIC_TYPE_S64;
283 value->u.s64 = (int64_t) jctx->value._byte;
284 break;
285 case JNI_TYPE_BOOLEAN:
286 value->sel = LTTNG_UST_DYNAMIC_TYPE_S64;
287 value->u.s64 = (int64_t) jctx->value._boolean;
288 break;
289 case JNI_TYPE_STRING:
b1ca4c5f
AM
290 {
291 int32_t offset = jctx->value._string_offset;
292 const char *str = get_ctx_string_at_offset(offset);
293
294 if (str) {
295 value->sel = LTTNG_UST_DYNAMIC_TYPE_STRING;
296 value->u.str = str;
297 } else {
298 value->sel = LTTNG_UST_DYNAMIC_TYPE_NONE;
299 }
8ab5c06b 300 break;
b1ca4c5f 301 }
8ab5c06b
AM
302 default:
303 abort();
304 }
305}
306
307/*
308 * Register a context provider to UST.
309 *
310 * Called from the Java side when an application registers a context retriever,
311 * so we create and register a corresponding provider on the C side.
312 */
313JNIEXPORT jlong JNICALL Java_org_lttng_ust_agent_context_LttngContextApi_registerProvider(JNIEnv *env,
2208d8b5 314 jobject jobj __attribute__((unused)),
8ab5c06b
AM
315 jstring provider_name)
316{
317 jboolean iscopy;
318 const char *provider_name_jstr;
319 char *provider_name_cstr;
320 struct lttng_ust_context_provider *provider;
321 /*
322 * Note: a "jlong" is 8 bytes on all architectures, whereas a
323 * C "long" varies.
324 */
325 jlong provider_ref;
326
327 provider_name_jstr = (*env)->GetStringUTFChars(env, provider_name, &iscopy);
328 if (!provider_name_jstr) {
329 goto error_jstr;
330 }
331 /* Keep our own copy of the string so UST can use it. */
332 provider_name_cstr = strdup(provider_name_jstr);
333 (*env)->ReleaseStringUTFChars(env, provider_name, provider_name_jstr);
334 if (!provider_name_cstr) {
335 goto error_strdup;
336 }
337 provider = zmalloc(sizeof(*provider));
338 if (!provider) {
339 goto error_provider;
340 }
daacdbfc 341 provider->struct_size = sizeof(*provider);
8ab5c06b
AM
342 provider->name = provider_name_cstr;
343 provider->get_size = get_size_cb;
344 provider->record = record_cb;
345 provider->get_value = get_value_cb;
346
347 if (lttng_ust_context_provider_register(provider)) {
348 goto error_register;
349 }
350
74687dca 351 provider_ref = (jlong) (long) provider;
8ab5c06b
AM
352 return provider_ref;
353
354 /* Error handling. */
355error_register:
356 free(provider);
357error_provider:
358 free(provider_name_cstr);
359error_strdup:
360error_jstr:
361 return 0;
362}
363
364/*
365 * Unregister a previously-registered context provider.
366 *
367 * Called from the Java side when an application unregisters a context retriever,
368 * so we unregister and delete the corresponding provider on the C side.
369 */
2208d8b5
MJ
370JNIEXPORT void JNICALL Java_org_lttng_ust_agent_context_LttngContextApi_unregisterProvider(JNIEnv *env __attribute__((unused)),
371 jobject jobj __attribute__((unused)),
8ab5c06b
AM
372 jlong provider_ref)
373{
374 struct lttng_ust_context_provider *provider =
375 (struct lttng_ust_context_provider*) (unsigned long) provider_ref;
376
377 if (!provider) {
378 return;
379 }
380
381 lttng_ust_context_provider_unregister(provider);
382
383 free(provider->name);
384 free(provider);
385}
This page took 0.044514 seconds and 4 git commands to generate.