cpp-common/bt2c/fmt.hpp: use `wise_enum::string_type` in `EnableIfIsWiseEnum` definition
[babeltrace.git] / src / plugins / text / details / obj-lifetime-mgmt.c
1 /*
2 * SPDX-License-Identifier: MIT
3 *
4 * Copyright 2019 Philippe Proulx <pproulx@efficios.com>
5 */
6
7 #include <stdbool.h>
8
9 #include <babeltrace2/babeltrace.h>
10
11 #include "common/common.h"
12 #include "common/assert.h"
13 #include "compat/glib.h"
14
15 #include "details.h"
16 #include "write.h"
17 #include "obj-lifetime-mgmt.h"
18
19 static
20 void trace_class_destruction_listener(const bt_trace_class *tc, void *data)
21 {
22 struct details_comp *details_comp = data;
23
24 BT_ASSERT(details_comp);
25 BT_ASSERT(details_comp->meta);
26
27 /* Remove from hash table, which also destroys the value */
28 g_hash_table_remove(details_comp->meta, tc);
29 }
30
31 static
32 struct details_trace_class_meta *borrow_trace_class_meta(
33 struct details_write_ctx *ctx, const bt_trace_class *tc)
34 {
35 struct details_trace_class_meta *details_tc_meta;
36
37 BT_ASSERT_DBG(ctx->details_comp->cfg.with_meta);
38 BT_ASSERT_DBG(ctx->details_comp->meta);
39 details_tc_meta = g_hash_table_lookup(ctx->details_comp->meta, tc);
40 if (!details_tc_meta) {
41 /* Not found: create one */
42 details_tc_meta = details_create_details_trace_class_meta();
43 if (!details_tc_meta) {
44 goto error;
45 }
46
47 /* Register trace class destruction listener */
48 if (bt_trace_class_add_destruction_listener(tc,
49 trace_class_destruction_listener,
50 ctx->details_comp,
51 &details_tc_meta->tc_destruction_listener_id)) {
52 goto error;
53 }
54
55 /* Insert into hash table (becomes the owner) */
56 g_hash_table_insert(ctx->details_comp->meta, (void *) tc,
57 details_tc_meta);
58 }
59
60 goto end;
61
62 error:
63 details_destroy_details_trace_class_meta(details_tc_meta);
64 details_tc_meta = NULL;
65
66 end:
67 return details_tc_meta;
68 }
69
70 bool details_need_to_write_meta_object(struct details_write_ctx *ctx,
71 const bt_trace_class *tc, const void *obj)
72 {
73 bool need_to_write;
74 struct details_trace_class_meta *details_tc_meta;
75
76 if (!ctx->details_comp->cfg.with_meta) {
77 need_to_write = false;
78 goto end;
79 }
80
81 BT_ASSERT_DBG(ctx->details_comp->meta);
82 details_tc_meta = g_hash_table_lookup(ctx->details_comp->meta, tc);
83 BT_ASSERT_DBG(details_tc_meta);
84 need_to_write =
85 !g_hash_table_lookup(details_tc_meta->objects, obj);
86
87 end:
88 return need_to_write;
89 }
90
91 void details_did_write_meta_object(struct details_write_ctx *ctx,
92 const bt_trace_class *tc, const void *obj)
93 {
94 struct details_trace_class_meta *details_tc_meta;
95
96 BT_ASSERT(ctx->details_comp->cfg.with_meta);
97 details_tc_meta = borrow_trace_class_meta(ctx, tc);
98 BT_ASSERT(details_tc_meta);
99 g_hash_table_insert(details_tc_meta->objects, (gpointer) obj,
100 GUINT_TO_POINTER(1));
101 }
102
103 bool details_need_to_write_trace_class(struct details_write_ctx *ctx,
104 const bt_trace_class *tc)
105 {
106 struct details_trace_class_meta *details_tc_meta;
107 bool need_to_write;
108
109 if (!ctx->details_comp->cfg.with_meta) {
110 need_to_write = false;
111 goto end;
112 }
113
114 BT_ASSERT_DBG(ctx->details_comp->meta);
115 details_tc_meta = g_hash_table_lookup(ctx->details_comp->meta, tc);
116 need_to_write = !details_tc_meta;
117
118 end:
119 return need_to_write;
120 }
121
122 int details_did_write_trace_class(struct details_write_ctx *ctx,
123 const bt_trace_class *tc)
124 {
125 int ret = 0;
126 struct details_trace_class_meta *details_tc_meta;
127
128 BT_ASSERT(ctx->details_comp->cfg.with_meta);
129
130 /* borrow_trace_class_meta() creates an entry if none exists */
131 details_tc_meta = borrow_trace_class_meta(ctx, tc);
132 if (!details_tc_meta) {
133 ret = -1;
134 }
135
136 return ret;
137 }
138
139 static
140 void trace_destruction_listener(const bt_trace *trace, void *data)
141 {
142 struct details_comp *details_comp = data;
143
144 BT_ASSERT(details_comp);
145 BT_ASSERT(details_comp->traces);
146
147 /* Remove from hash table, which also destroys the value */
148 g_hash_table_remove(details_comp->traces, trace);
149 }
150
151 static
152 struct details_trace *create_details_trace(uint64_t unique_id)
153 {
154 struct details_trace *details_trace = g_new0(struct details_trace, 1);
155
156 if (!details_trace) {
157 goto end;
158 }
159
160 details_trace->unique_id = unique_id;
161 details_trace->trace_destruction_listener_id = UINT64_C(-1);
162
163 end:
164 return details_trace;
165 }
166
167
168 int details_trace_unique_id(struct details_write_ctx *ctx,
169 const bt_trace *trace, uint64_t *unique_id)
170 {
171 int ret = 0;
172 struct details_trace *details_trace = NULL;
173
174 BT_ASSERT_DBG(unique_id);
175 BT_ASSERT_DBG(ctx->details_comp->traces);
176 if (!bt_g_hash_table_contains(ctx->details_comp->traces,
177 trace)) {
178 /* Not found: create one */
179 *unique_id = ctx->details_comp->next_unique_trace_id;
180 details_trace = create_details_trace(*unique_id);
181 if (!details_trace) {
182 goto error;
183 }
184
185 ctx->details_comp->next_unique_trace_id++;
186
187 /* Register trace destruction listener if there's none */
188 if (bt_trace_add_destruction_listener(trace,
189 trace_destruction_listener,
190 ctx->details_comp,
191 &details_trace->trace_destruction_listener_id)) {
192 goto error;
193 }
194
195 BT_ASSERT(details_trace->trace_destruction_listener_id !=
196 UINT64_C(-1));
197
198 /* Move to hash table */
199 g_hash_table_insert(ctx->details_comp->traces, (gpointer) trace,
200 details_trace);
201 details_trace = NULL;
202 } else {
203 /* Found */
204 details_trace = g_hash_table_lookup(
205 ctx->details_comp->traces, trace);
206 *unique_id = details_trace->unique_id;
207 details_trace = NULL;
208 }
209
210 goto end;
211
212 error:
213 ret = -1;
214
215 end:
216 g_free(details_trace);
217
218 return ret;
219 }
This page took 0.033955 seconds and 4 git commands to generate.