Revert "Fix: typo: DECLARE_URCU_TLS_IE -> DEFINE_URCU_TLS_IE"
[lttng-ust.git] / liblttng-ust-java-agent / jni / common / lttng_ust_context.c
index 8cc4087f07548585f37254a3d79cf1d3146b6ffb..e9b6da282db3bfbc5ec075a8ea64178c6f9ef851 100644 (file)
 #include <lttng/ust-events.h>
 #include <lttng/ringbuffer-config.h>
 #include <lttng/ust-context-provider.h>
+#include <urcu/tls-compat.h>
 
 #include "helper.h"
 #include "lttng_ust_context.h"
 
-#define LTTNG_UST_JNI_CONTEXT_NAME_LEN         256
-/* TODO: the value should be variable length. */
-#define LTTNG_UST_JNI_VALUE_LEN                        256
-
 enum lttng_ust_jni_type {
        JNI_TYPE_NULL = 0,
        JNI_TYPE_INTEGER = 1,
@@ -44,8 +41,8 @@ enum lttng_ust_jni_type {
        JNI_TYPE_STRING = 8,
 };
 
-struct lttng_ust_jni_ctx {
-       char context_name[LTTNG_UST_JNI_CONTEXT_NAME_LEN];
+struct lttng_ust_jni_ctx_entry {
+       int32_t context_name_offset;
        char type;      /* enum lttng_ust_jni_type */
        union {
                int32_t _integer;
@@ -55,33 +52,47 @@ struct lttng_ust_jni_ctx {
                signed char _byte;
                int16_t _short;
                signed char _boolean;
-               char _string[LTTNG_UST_JNI_VALUE_LEN];
+               int32_t _string_offset;
        } value;
 } __attribute__((packed));
 
 /* TLS passing context info from JNI to callbacks. */
-__thread struct lttng_ust_jni_tls lttng_ust_context_info_tls;
+DECLARE_URCU_TLS_IE(struct lttng_ust_jni_tls, lttng_ust_context_info_tls);
+
+static const char *get_ctx_string_at_offset(int32_t offset)
+{
+       signed char *ctx_strings_array = lttng_ust_context_info_tls.ctx_strings;
+
+       if (offset < 0 || offset >= lttng_ust_context_info_tls.ctx_strings_len) {
+               return NULL;
+       }
+       return (const char *) (ctx_strings_array + offset);
+}
 
-static struct lttng_ust_jni_ctx *lookup_ctx_by_name(const char *ctx_name)
+static struct lttng_ust_jni_ctx_entry *lookup_ctx_by_name(const char *ctx_name)
 {
-       struct lttng_ust_jni_ctx *ctx_array = lttng_ust_context_info_tls.ctx;
-       int i, len = lttng_ust_context_info_tls.len / sizeof(struct lttng_ust_jni_ctx);
+       struct lttng_ust_jni_ctx_entry *ctx_entries_array = lttng_ust_context_info_tls.ctx_entries;
+       int i, len = lttng_ust_context_info_tls.ctx_entries_len / sizeof(struct lttng_ust_jni_ctx_entry);
 
        for (i = 0; i < len; i++) {
-               if (strcmp(ctx_array[i].context_name, ctx_name) == 0)
-                       return &ctx_array[i];
+               int32_t offset = ctx_entries_array[i].context_name_offset;
+               const char *string = get_ctx_string_at_offset(offset);
+
+               if (string && strcmp(string, ctx_name) == 0) {
+                       return &ctx_entries_array[i];
+               }
        }
        return NULL;
-
 }
 
 static size_t get_size_cb(struct lttng_ctx_field *field, size_t offset)
 {
-       struct lttng_ust_jni_ctx *jctx;
+       struct lttng_ust_jni_ctx_entry *jctx;
        size_t size = 0;
        const char *ctx_name = field->event_field.name;
        enum lttng_ust_jni_type jni_type;
 
+
        size += lib_ring_buffer_align(offset, lttng_alignof(char));
        size += sizeof(char);           /* tag */
        jctx = lookup_ctx_by_name(ctx_name);
@@ -119,8 +130,16 @@ static size_t get_size_cb(struct lttng_ctx_field *field, size_t offset)
                size += sizeof(char);           /* variant */
                break;
        case JNI_TYPE_STRING:
-               size += strlen(jctx->value._string) + 1;
+       {
+               /* The value is an offset, the string is in the "strings" array */
+               int32_t string_offset = jctx->value._string_offset;
+               const char *string = get_ctx_string_at_offset(string_offset);
+
+               if (string) {
+                       size += strlen(string) + 1;
+               }
                break;
+       }
        default:
                abort();
        }
@@ -132,7 +151,7 @@ static void record_cb(struct lttng_ctx_field *field,
                 struct lttng_ust_lib_ring_buffer_ctx *ctx,
                 struct lttng_channel *chan)
 {
-       struct lttng_ust_jni_ctx *jctx;
+       struct lttng_ust_jni_ctx_entry *jctx;
        const char *ctx_name = field->event_field.name;
        enum lttng_ust_jni_type jni_type;
        char sel_char;
@@ -229,12 +248,19 @@ static void record_cb(struct lttng_ctx_field *field,
        }
        case JNI_TYPE_STRING:
        {
-                       const char *str = jctx->value._string;
-
-                       sel_char = LTTNG_UST_DYNAMIC_TYPE_STRING;
+                       int32_t offset = jctx->value._string_offset;
+                       const char *str = get_ctx_string_at_offset(offset);
+
+                       if (str) {
+                               sel_char = LTTNG_UST_DYNAMIC_TYPE_STRING;
+                       } else {
+                               sel_char = LTTNG_UST_DYNAMIC_TYPE_NONE;
+                       }
                        lib_ring_buffer_align_ctx(ctx, lttng_alignof(char));
                        chan->ops->event_write(ctx, &sel_char, sizeof(sel_char));
-                       chan->ops->event_write(ctx, str, strlen(str) + 1);
+                       if (str) {
+                               chan->ops->event_write(ctx, str, strlen(str) + 1);
+                       }
                        break;
        }
        default:
@@ -245,7 +271,7 @@ static void record_cb(struct lttng_ctx_field *field,
 static void get_value_cb(struct lttng_ctx_field *field,
                struct lttng_ctx_value *value)
 {
-       struct lttng_ust_jni_ctx *jctx;
+       struct lttng_ust_jni_ctx_entry *jctx;
        const char *ctx_name = field->event_field.name;
        enum lttng_ust_jni_type jni_type;
 
@@ -289,9 +315,18 @@ static void get_value_cb(struct lttng_ctx_field *field,
                value->u.s64 = (int64_t) jctx->value._boolean;
                break;
        case JNI_TYPE_STRING:
-               value->sel = LTTNG_UST_DYNAMIC_TYPE_STRING;
-               value->u.str = jctx->value._string;
+       {
+               int32_t offset = jctx->value._string_offset;
+               const char *str = get_ctx_string_at_offset(offset);
+
+               if (str) {
+                       value->sel = LTTNG_UST_DYNAMIC_TYPE_STRING;
+                       value->u.str = str;
+               } else {
+                       value->sel = LTTNG_UST_DYNAMIC_TYPE_NONE;
+               }
                break;
+       }
        default:
                abort();
        }
@@ -340,7 +375,7 @@ JNIEXPORT jlong JNICALL Java_org_lttng_ust_agent_context_LttngContextApi_registe
                goto error_register;
        }
 
-       provider_ref = (jlong) provider;
+       provider_ref = (jlong) (long) provider;
        return provider_ref;
 
        /* Error handling. */
This page took 0.025145 seconds and 4 git commands to generate.