2 * SPDX-License-Identifier: MIT
4 * Copyright 2019 Philippe Proulx <pproulx@efficios.com>
9 #include <babeltrace2/babeltrace.h>
11 #include "common/common.h"
12 #include "common/assert.h"
13 #include "compat/glib.h"
17 #include "obj-lifetime-mgmt.h"
20 void trace_class_destruction_listener(const bt_trace_class
*tc
, void *data
)
22 struct details_comp
*details_comp
= data
;
24 BT_ASSERT(details_comp
);
25 BT_ASSERT(details_comp
->meta
);
27 /* Remove from hash table, which also destroys the value */
28 g_hash_table_remove(details_comp
->meta
, tc
);
32 struct details_trace_class_meta
*borrow_trace_class_meta(
33 struct details_write_ctx
*ctx
, const bt_trace_class
*tc
)
35 struct details_trace_class_meta
*details_tc_meta
;
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
) {
47 /* Register trace class destruction listener */
48 if (bt_trace_class_add_destruction_listener(tc
,
49 trace_class_destruction_listener
,
51 &details_tc_meta
->tc_destruction_listener_id
)) {
55 /* Insert into hash table (becomes the owner) */
56 g_hash_table_insert(ctx
->details_comp
->meta
, (void *) tc
,
63 details_destroy_details_trace_class_meta(details_tc_meta
);
64 details_tc_meta
= NULL
;
67 return details_tc_meta
;
71 bool details_need_to_write_meta_object(struct details_write_ctx
*ctx
,
72 const bt_trace_class
*tc
, const void *obj
)
75 struct details_trace_class_meta
*details_tc_meta
;
77 if (!ctx
->details_comp
->cfg
.with_meta
) {
78 need_to_write
= false;
82 BT_ASSERT_DBG(ctx
->details_comp
->meta
);
83 details_tc_meta
= g_hash_table_lookup(ctx
->details_comp
->meta
, tc
);
84 BT_ASSERT_DBG(details_tc_meta
);
86 !g_hash_table_lookup(details_tc_meta
->objects
, obj
);
93 void details_did_write_meta_object(struct details_write_ctx
*ctx
,
94 const bt_trace_class
*tc
, const void *obj
)
96 struct details_trace_class_meta
*details_tc_meta
;
98 BT_ASSERT(ctx
->details_comp
->cfg
.with_meta
);
99 details_tc_meta
= borrow_trace_class_meta(ctx
, tc
);
100 BT_ASSERT(details_tc_meta
);
101 g_hash_table_insert(details_tc_meta
->objects
, (gpointer
) obj
,
102 GUINT_TO_POINTER(1));
106 bool details_need_to_write_trace_class(struct details_write_ctx
*ctx
,
107 const bt_trace_class
*tc
)
109 struct details_trace_class_meta
*details_tc_meta
;
112 if (!ctx
->details_comp
->cfg
.with_meta
) {
113 need_to_write
= false;
117 BT_ASSERT_DBG(ctx
->details_comp
->meta
);
118 details_tc_meta
= g_hash_table_lookup(ctx
->details_comp
->meta
, tc
);
119 need_to_write
= !details_tc_meta
;
122 return need_to_write
;
126 int details_did_write_trace_class(struct details_write_ctx
*ctx
,
127 const bt_trace_class
*tc
)
130 struct details_trace_class_meta
*details_tc_meta
;
132 BT_ASSERT(ctx
->details_comp
->cfg
.with_meta
);
134 /* borrow_trace_class_meta() creates an entry if none exists */
135 details_tc_meta
= borrow_trace_class_meta(ctx
, tc
);
136 if (!details_tc_meta
) {
144 void trace_destruction_listener(const bt_trace
*trace
, void *data
)
146 struct details_comp
*details_comp
= data
;
148 BT_ASSERT(details_comp
);
149 BT_ASSERT(details_comp
->traces
);
151 /* Remove from hash table, which also destroys the value */
152 g_hash_table_remove(details_comp
->traces
, trace
);
156 struct details_trace
*create_details_trace(uint64_t unique_id
)
158 struct details_trace
*details_trace
= g_new0(struct details_trace
, 1);
160 if (!details_trace
) {
164 details_trace
->unique_id
= unique_id
;
165 details_trace
->trace_destruction_listener_id
= UINT64_C(-1);
168 return details_trace
;
173 int details_trace_unique_id(struct details_write_ctx
*ctx
,
174 const bt_trace
*trace
, uint64_t *unique_id
)
177 struct details_trace
*details_trace
= NULL
;
179 BT_ASSERT_DBG(unique_id
);
180 BT_ASSERT_DBG(ctx
->details_comp
->traces
);
181 if (!bt_g_hash_table_contains(ctx
->details_comp
->traces
,
183 /* Not found: create one */
184 *unique_id
= ctx
->details_comp
->next_unique_trace_id
;
185 details_trace
= create_details_trace(*unique_id
);
186 if (!details_trace
) {
190 ctx
->details_comp
->next_unique_trace_id
++;
192 /* Register trace destruction listener if there's none */
193 if (bt_trace_add_destruction_listener(trace
,
194 trace_destruction_listener
,
196 &details_trace
->trace_destruction_listener_id
)) {
200 BT_ASSERT(details_trace
->trace_destruction_listener_id
!=
203 /* Move to hash table */
204 g_hash_table_insert(ctx
->details_comp
->traces
, (gpointer
) trace
,
206 details_trace
= NULL
;
209 details_trace
= g_hash_table_lookup(
210 ctx
->details_comp
->traces
, trace
);
211 *unique_id
= details_trace
->unique_id
;
212 details_trace
= NULL
;
221 g_free(details_trace
);