4 * LTTng UST trace/channel/event context management.
6 * Copyright (C) 2011 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; only
11 * version 2.1 of the License.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 #include <lttng/ust-events.h>
25 #include <lttng/ust-tracer.h>
26 #include <lttng/ust-context-provider.h>
27 #include <urcu-pointer.h>
28 #include <usterr-signal-safe.h>
34 * The filter implementation requires that two consecutive "get" for the
35 * same context performed by the same thread return the same result.
38 int lttng_find_context(struct lttng_ctx
*ctx
, const char *name
)
43 if (strncmp(name
, "$ctx.", strlen("$ctx.")) == 0) {
44 subname
= name
+ strlen("$ctx.");
48 for (i
= 0; i
< ctx
->nr_fields
; i
++) {
49 /* Skip allocated (but non-initialized) contexts */
50 if (!ctx
->fields
[i
].event_field
.name
)
52 if (!strcmp(ctx
->fields
[i
].event_field
.name
, subname
))
58 int lttng_get_context_index(struct lttng_ctx
*ctx
, const char *name
)
65 if (strncmp(name
, "$ctx.", strlen("$ctx.")) == 0) {
66 subname
= name
+ strlen("$ctx.");
70 for (i
= 0; i
< ctx
->nr_fields
; i
++) {
71 /* Skip allocated (but non-initialized) contexts */
72 if (!ctx
->fields
[i
].event_field
.name
)
74 if (!strcmp(ctx
->fields
[i
].event_field
.name
, subname
))
80 static int lttng_find_context_provider(struct lttng_ctx
*ctx
, const char *name
)
84 for (i
= 0; i
< ctx
->nr_fields
; i
++) {
85 /* Skip allocated (but non-initialized) contexts */
86 if (!ctx
->fields
[i
].event_field
.name
)
88 if (!strncmp(ctx
->fields
[i
].event_field
.name
, name
,
96 * Note: as we append context information, the pointer location may change.
98 struct lttng_ctx_field
*lttng_append_context(struct lttng_ctx
**ctx_p
)
100 struct lttng_ctx_field
*field
;
101 struct lttng_ctx
*ctx
;
104 *ctx_p
= zmalloc(sizeof(struct lttng_ctx
));
107 (*ctx_p
)->largest_align
= 1;
110 if (ctx
->nr_fields
+ 1 > ctx
->allocated_fields
) {
111 struct lttng_ctx_field
*new_fields
;
113 ctx
->allocated_fields
= max_t(size_t, 1, 2 * ctx
->allocated_fields
);
114 new_fields
= zmalloc(ctx
->allocated_fields
* sizeof(struct lttng_ctx_field
));
118 memcpy(new_fields
, ctx
->fields
, sizeof(*ctx
->fields
) * ctx
->nr_fields
);
120 ctx
->fields
= new_fields
;
122 field
= &ctx
->fields
[ctx
->nr_fields
];
127 int lttng_context_add_rcu(struct lttng_ctx
**ctx_p
,
128 const struct lttng_ctx_field
*f
)
130 struct lttng_ctx
*old_ctx
= *ctx_p
, *new_ctx
= NULL
;
131 struct lttng_ctx_field
*new_fields
= NULL
;
132 struct lttng_ctx_field
*nf
;
135 new_ctx
= zmalloc(sizeof(struct lttng_ctx
));
139 new_fields
= zmalloc(new_ctx
->allocated_fields
140 * sizeof(struct lttng_ctx_field
));
145 memcpy(new_fields
, old_ctx
->fields
,
146 sizeof(*old_ctx
->fields
) * old_ctx
->nr_fields
);
147 new_ctx
->fields
= new_fields
;
149 nf
= lttng_append_context(&new_ctx
);
156 lttng_context_update(new_ctx
);
157 rcu_assign_pointer(*ctx_p
, new_ctx
);
160 free(old_ctx
->fields
);
167 * lttng_context_update() should be called at least once between context
168 * modification and trace start.
170 void lttng_context_update(struct lttng_ctx
*ctx
)
173 size_t largest_align
= 8; /* in bits */
175 for (i
= 0; i
< ctx
->nr_fields
; i
++) {
176 struct lttng_type
*type
;
177 size_t field_align
= 8;
179 type
= &ctx
->fields
[i
].event_field
.type
;
180 switch (type
->atype
) {
182 field_align
= type
->u
.basic
.integer
.alignment
;
186 struct lttng_basic_type
*btype
;
188 btype
= &type
->u
.array
.elem_type
;
189 switch (btype
->atype
) {
191 field_align
= btype
->u
.basic
.integer
.alignment
;
206 struct lttng_basic_type
*btype
;
208 btype
= &type
->u
.sequence
.length_type
;
209 switch (btype
->atype
) {
211 field_align
= btype
->u
.basic
.integer
.alignment
;
222 btype
= &type
->u
.sequence
.elem_type
;
223 switch (btype
->atype
) {
225 field_align
= max_t(size_t,
227 btype
->u
.basic
.integer
.alignment
);
250 largest_align
= max_t(size_t, largest_align
, field_align
);
252 ctx
->largest_align
= largest_align
>> 3; /* bits to bytes */
256 * Remove last context field.
258 void lttng_remove_context_field(struct lttng_ctx
**ctx_p
,
259 struct lttng_ctx_field
*field
)
261 struct lttng_ctx
*ctx
;
265 assert(&ctx
->fields
[ctx
->nr_fields
] == field
);
266 assert(field
->field_name
== NULL
);
267 memset(&ctx
->fields
[ctx
->nr_fields
], 0, sizeof(struct lttng_ctx_field
));
270 void lttng_destroy_context(struct lttng_ctx
*ctx
)
276 for (i
= 0; i
< ctx
->nr_fields
; i
++) {
277 if (ctx
->fields
[i
].destroy
)
278 ctx
->fields
[i
].destroy(&ctx
->fields
[i
]);
279 free(ctx
->fields
[i
].field_name
);
286 * Can be safely performed concurrently with tracing using the struct
287 * lttng_ctx. Using RCU update. Needs to match RCU read-side handling of
290 * This does not allow adding, removing, or changing typing of the
291 * contexts, since this needs to stay invariant for metadata. However,
292 * it allows updating the handlers associated with all contexts matching
293 * a provider (by name) while tracing is using it, in a way that ensures
294 * a single RCU read-side critical section see either all old, or all
297 int lttng_ust_context_set_provider_rcu(struct lttng_ctx
**_ctx
,
299 size_t (*get_size
)(struct lttng_ctx_field
*field
, size_t offset
),
300 void (*record
)(struct lttng_ctx_field
*field
,
301 struct lttng_ust_lib_ring_buffer_ctx
*ctx
,
302 struct lttng_channel
*chan
),
303 void (*get_value
)(struct lttng_ctx_field
*field
,
304 struct lttng_ctx_value
*value
))
307 struct lttng_ctx
*ctx
= *_ctx
, *new_ctx
;
308 struct lttng_ctx_field
*new_fields
;
310 if (!ctx
|| !lttng_find_context_provider(ctx
, name
))
313 * We have at least one instance of context for the provider.
315 new_ctx
= zmalloc(sizeof(*new_ctx
));
319 new_fields
= zmalloc(sizeof(*new_fields
) * ctx
->allocated_fields
);
324 memcpy(new_fields
, ctx
->fields
,
325 sizeof(*new_fields
) * ctx
->allocated_fields
);
326 for (i
= 0; i
< ctx
->nr_fields
; i
++) {
327 if (strncmp(new_fields
[i
].event_field
.name
,
328 name
, strlen(name
)) != 0)
330 new_fields
[i
].get_size
= get_size
;
331 new_fields
[i
].record
= record
;
332 new_fields
[i
].get_value
= get_value
;
334 new_ctx
->fields
= new_fields
;
335 rcu_assign_pointer(*_ctx
, new_ctx
);
346 int lttng_session_context_init(struct lttng_ctx
**ctx
)
350 ret
= lttng_add_pthread_id_to_ctx(ctx
);
352 WARN("Cannot add context lttng_add_pthread_id_to_ctx");
355 ret
= lttng_add_vtid_to_ctx(ctx
);
357 WARN("Cannot add context lttng_add_vtid_to_ctx");
360 ret
= lttng_add_vpid_to_ctx(ctx
);
362 WARN("Cannot add context lttng_add_vpid_to_ctx");
365 ret
= lttng_add_procname_to_ctx(ctx
);
367 WARN("Cannot add context lttng_add_procname_to_ctx");
370 ret
= lttng_add_cpu_id_to_ctx(ctx
);
372 WARN("Cannot add context lttng_add_cpu_id_to_ctx");
375 lttng_context_update(*ctx
);
379 lttng_destroy_context(*ctx
);
383 /* For backward compatibility. Leave those exported symbols in place. */
384 struct lttng_ctx
*lttng_static_ctx
;
386 void lttng_context_init(void)
390 void lttng_context_exit(void)