lttng_ust_init_thread: initialise cached context values
[lttng-ust.git] / src / lib / lttng-ust / lttng-context-provider.c
CommitLineData
53569322 1/*
c0c0989a 2 * SPDX-License-Identifier: LGPL-2.1-only
53569322
MD
3 *
4 * Copyright (C) 2016 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
5 *
c0c0989a 6 * LTTng UST application context provider.
53569322
MD
7 */
8
3fbec7dc 9#define _LGPL_SOURCE
b4051ad8 10#include <stddef.h>
fb31eb73 11#include <stdint.h>
53569322
MD
12#include <sys/types.h>
13#include <unistd.h>
fb31eb73 14
9d315d6d 15#include <common/ust-context-provider.h>
d8d2416d 16
fc80554e 17#include "context-internal.h"
53569322 18#include "lttng-tracer-core.h"
e58e5ad5 19#include "common/jhash.h"
d8d2416d 20#include "context-provider-internal.h"
9d315d6d 21#include "common/macros.h"
8cd08025 22#include "common/tracer.h"
53569322 23
4e48b5d2
MD
24struct lttng_ust_registered_context_provider {
25 const struct lttng_ust_context_provider *provider;
26
27 struct cds_hlist_node node;
28};
29
53569322
MD
30#define CONTEXT_PROVIDER_HT_BITS 12
31#define CONTEXT_PROVIDER_HT_SIZE (1U << CONTEXT_PROVIDER_HT_BITS)
32struct context_provider_ht {
33 struct cds_hlist_head table[CONTEXT_PROVIDER_HT_SIZE];
34};
35
36static struct context_provider_ht context_provider_ht;
37
4e48b5d2 38static const struct lttng_ust_context_provider *
53569322
MD
39 lookup_provider_by_name(const char *name)
40{
41 struct cds_hlist_head *head;
42 struct cds_hlist_node *node;
4e48b5d2 43 struct lttng_ust_registered_context_provider *reg_provider;
53569322
MD
44 uint32_t hash;
45 const char *end;
46 size_t len;
47
48 /* Lookup using everything before first ':' as key. */
49 end = strchr(name, ':');
50 if (end)
51 len = end - name;
52 else
53 len = strlen(name);
54 hash = jhash(name, len, 0);
55 head = &context_provider_ht.table[hash & (CONTEXT_PROVIDER_HT_SIZE - 1)];
4e48b5d2
MD
56 cds_hlist_for_each_entry(reg_provider, node, head, node) {
57 if (!strncmp(reg_provider->provider->name, name, len))
58 return reg_provider->provider;
53569322
MD
59 }
60 return NULL;
61}
62
4e48b5d2 63struct lttng_ust_registered_context_provider *lttng_ust_context_provider_register(struct lttng_ust_context_provider *provider)
53569322 64{
4e48b5d2 65 struct lttng_ust_registered_context_provider *reg_provider = NULL;
53569322
MD
66 struct cds_hlist_head *head;
67 size_t name_len = strlen(provider->name);
68 uint32_t hash;
53569322 69
c246521d 70 lttng_ust_common_init_thread(0);
c362addf 71
53569322 72 /* Provider name starts with "$app.". */
fe94775b 73 if (strncmp("$app.", provider->name, strlen("$app.")) != 0)
4e48b5d2 74 return NULL;
8b05d0d4 75 /* Provider name cannot contain a colon character. */
53569322 76 if (strchr(provider->name, ':'))
4e48b5d2
MD
77 return NULL;
78 if (ust_lock())
53569322 79 goto end;
4e48b5d2 80 if (lookup_provider_by_name(provider->name))
53569322 81 goto end;
4e48b5d2
MD
82 reg_provider = zmalloc(sizeof(struct lttng_ust_registered_context_provider));
83 if (!reg_provider)
84 goto end;
85 reg_provider->provider = provider;
53569322
MD
86 hash = jhash(provider->name, name_len, 0);
87 head = &context_provider_ht.table[hash & (CONTEXT_PROVIDER_HT_SIZE - 1)];
4e48b5d2 88 cds_hlist_add_head(&reg_provider->node, head);
d8d2416d 89
53569322
MD
90 lttng_ust_context_set_session_provider(provider->name,
91 provider->get_size, provider->record,
a5d437c5 92 provider->get_value);
d8d2416d
FD
93
94 lttng_ust_context_set_event_notifier_group_provider(provider->name,
95 provider->get_size, provider->record,
a5d437c5 96 provider->get_value);
53569322
MD
97end:
98 ust_unlock();
4e48b5d2 99 return reg_provider;
53569322
MD
100}
101
4e48b5d2 102void lttng_ust_context_provider_unregister(struct lttng_ust_registered_context_provider *reg_provider)
53569322 103{
c246521d 104 lttng_ust_common_init_thread(0);
c362addf 105
53569322
MD
106 if (ust_lock())
107 goto end;
4e48b5d2 108 lttng_ust_context_set_session_provider(reg_provider->provider->name,
ce7352a2 109 lttng_ust_dummy_get_size, lttng_ust_dummy_record,
a5d437c5 110 lttng_ust_dummy_get_value);
d8d2416d 111
4e48b5d2 112 lttng_ust_context_set_event_notifier_group_provider(reg_provider->provider->name,
d8d2416d 113 lttng_ust_dummy_get_size, lttng_ust_dummy_record,
a5d437c5 114 lttng_ust_dummy_get_value);
d8d2416d 115
4e48b5d2 116 cds_hlist_del(&reg_provider->node);
53569322
MD
117end:
118 ust_unlock();
4e48b5d2 119 free(reg_provider);
53569322
MD
120}
121
a5d437c5
MD
122static
123void app_context_destroy(void *priv)
124{
125 struct lttng_ust_app_context *app_ctx = (struct lttng_ust_app_context *) priv;
126
127 free(app_ctx->ctx_name);
128 free(app_ctx->event_field);
129}
130
131static
132const struct lttng_ust_type_common app_ctx_type = {
133 .type = lttng_ust_type_dynamic,
134};
135
53569322
MD
136/*
137 * Called with ust mutex held.
138 * Add application context to array of context, even if the application
139 * context is not currently loaded by application. It will then use the
140 * dummy callbacks in that case.
141 * Always performed before tracing is started, since it modifies
142 * metadata describing the context.
143 */
144int lttng_ust_add_app_context_to_ctx_rcu(const char *name,
daacdbfc 145 struct lttng_ust_ctx **ctx)
53569322 146{
4e48b5d2 147 const struct lttng_ust_context_provider *provider;
f26f2f9b 148 struct lttng_ust_ctx_field new_field = { 0 };
4e48b5d2 149 struct lttng_ust_event_field *event_field = NULL;
a5d437c5 150 struct lttng_ust_app_context *app_ctx = NULL;
f26f2f9b 151 char *ctx_name;
53569322
MD
152 int ret;
153
154 if (*ctx && lttng_find_context(*ctx, name))
155 return -EEXIST;
4e48b5d2
MD
156 event_field = zmalloc(sizeof(struct lttng_ust_event_field));
157 if (!event_field) {
daacdbfc
MD
158 ret = -ENOMEM;
159 goto error_event_field_alloc;
160 }
f26f2f9b
MD
161 ctx_name = strdup(name);
162 if (!ctx_name) {
daacdbfc
MD
163 ret = -ENOMEM;
164 goto error_field_name_alloc;
165 }
a5d437c5
MD
166 app_ctx = zmalloc(sizeof(struct lttng_ust_app_context));
167 if (!app_ctx) {
a084756d 168 ret = -ENOMEM;
a5d437c5 169 goto error_app_ctx_alloc;
a084756d 170 }
a5d437c5
MD
171 app_ctx->struct_size = sizeof(struct lttng_ust_app_context);
172 app_ctx->event_field = event_field;
173 app_ctx->ctx_name = ctx_name;
174
f26f2f9b 175 event_field->name = ctx_name;
a5d437c5 176 event_field->type = &app_ctx_type;
f26f2f9b 177 new_field.event_field = event_field;
53569322
MD
178 /*
179 * If provider is not found, we add the context anyway, but
180 * it will provide a dummy context.
181 */
182 provider = lookup_provider_by_name(name);
183 if (provider) {
f26f2f9b
MD
184 new_field.get_size = provider->get_size;
185 new_field.record = provider->record;
186 new_field.get_value = provider->get_value;
53569322 187 } else {
f26f2f9b
MD
188 new_field.get_size = lttng_ust_dummy_get_size;
189 new_field.record = lttng_ust_dummy_record;
190 new_field.get_value = lttng_ust_dummy_get_value;
53569322 191 }
a5d437c5
MD
192 new_field.priv = app_ctx;
193 new_field.destroy = app_context_destroy;
daacdbfc
MD
194 /*
195 * For application context, add it by expanding
f26f2f9b 196 * ctx array.
daacdbfc 197 */
f26f2f9b 198 ret = lttng_ust_context_append_rcu(ctx, &new_field);
53569322 199 if (ret) {
239128ca 200 goto error_append;
53569322
MD
201 }
202 return 0;
daacdbfc 203
239128ca 204error_append:
a5d437c5
MD
205 free(app_ctx);
206error_app_ctx_alloc:
f26f2f9b 207 free(ctx_name);
daacdbfc 208error_field_name_alloc:
4e48b5d2 209 free(event_field);
daacdbfc 210error_event_field_alloc:
daacdbfc 211 return ret;
53569322 212}
This page took 0.044095 seconds and 4 git commands to generate.