137790f57784ea1a12198a32164b1fd9f268d442
[lttng-tools.git] / src / bin / lttng-relayd / ctf-trace.c
1 /*
2 * Copyright (C) 2013 - Julien Desfossez <jdesfossez@efficios.com>
3 * David Goulet <dgoulet@efficios.com>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License, version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc., 51
16 * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19 #define _GNU_SOURCE
20 #include <assert.h>
21
22 #include <common/common.h>
23 #include <common/utils.h>
24
25 #include "ctf-trace.h"
26
27 static uint64_t last_relay_ctf_trace_id;
28
29 /*
30 * Try to destroy a ctf_trace object meaning that the refcount is decremented
31 * and checked if down to 0 which will free it.
32 */
33 void ctf_trace_try_destroy(struct ctf_trace *obj)
34 {
35 unsigned long ret_ref;
36
37 if (!obj) {
38 return;
39 }
40
41 ret_ref = uatomic_add_return(&obj->refcount, -1);
42 if (ret_ref == 0) {
43 DBG("Freeing ctf_trace %" PRIu64, obj->id);
44 free(obj);
45 }
46 }
47
48 /*
49 * Create and return an allocated ctf_trace object. NULL on error.
50 */
51 struct ctf_trace *ctf_trace_create(void)
52 {
53 struct ctf_trace *obj;
54
55 obj = zmalloc(sizeof(*obj));
56 if (!obj) {
57 PERROR("ctf_trace alloc");
58 goto error;
59 }
60
61 obj->id = ++last_relay_ctf_trace_id;
62 DBG("Created ctf_trace %" PRIu64, obj->id);
63
64 error:
65 return obj;
66 }
67
68 /*
69 * Check if we can assign the ctf_trace id and metadata stream to one or all
70 * the streams with the same path_name (our unique ID for ctf traces).
71 *
72 * The given stream MUST be new and NOT visible (in any hash table).
73 */
74 void ctf_trace_assign(struct lttng_ht *ht, struct relay_stream *stream)
75 {
76 struct lttng_ht_iter iter;
77 struct relay_stream *tmp_stream;
78
79 assert(ht);
80 assert(stream);
81
82 rcu_read_lock();
83 cds_lfht_for_each_entry_duplicate(ht->ht,
84 ht->hash_fct((void *) stream->path_name, lttng_ht_seed),
85 ht->match_fct, (void *) stream->path_name,
86 &iter.iter, tmp_stream, ctf_trace_node.node) {
87 if (stream->metadata_flag) {
88 /*
89 * The new stream is the metadata stream for this trace,
90 * assign the ctf_trace pointer to all the streams in
91 * this bucket.
92 */
93 pthread_mutex_lock(&tmp_stream->lock);
94 tmp_stream->ctf_trace = stream->ctf_trace;
95 uatomic_inc(&tmp_stream->ctf_trace->refcount);
96 pthread_mutex_unlock(&tmp_stream->lock);
97 DBG("Assigned ctf_trace %" PRIu64 " to stream %" PRIu64,
98 tmp_stream->ctf_trace->id, tmp_stream->stream_handle);
99 } else if (tmp_stream->ctf_trace) {
100 /*
101 * The ctf_trace already exists for this bucket,
102 * just assign the pointer to the new stream and exit.
103 */
104 stream->ctf_trace = tmp_stream->ctf_trace;
105 uatomic_inc(&stream->ctf_trace->refcount);
106 DBG("Assigned ctf_trace %" PRIu64 " to stream %" PRIu64,
107 tmp_stream->ctf_trace->id, tmp_stream->stream_handle);
108 goto end;
109 } else {
110 /*
111 * We don't know yet the ctf_trace ID (no metadata has been added),
112 * so leave it there until the metadata stream arrives.
113 */
114 goto end;
115 }
116 }
117
118 end:
119 rcu_read_unlock();
120 return;
121 }
122
This page took 0.031285 seconds and 4 git commands to generate.