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
;
70 bool details_need_to_write_meta_object(struct details_write_ctx
*ctx
,
71 const bt_trace_class
*tc
, const void *obj
)
74 struct details_trace_class_meta
*details_tc_meta
;
76 if (!ctx
->details_comp
->cfg
.with_meta
) {
77 need_to_write
= false;
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
);
85 !g_hash_table_lookup(details_tc_meta
->objects
, obj
);
91 void details_did_write_meta_object(struct details_write_ctx
*ctx
,
92 const bt_trace_class
*tc
, const void *obj
)
94 struct details_trace_class_meta
*details_tc_meta
;
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));
103 bool details_need_to_write_trace_class(struct details_write_ctx
*ctx
,
104 const bt_trace_class
*tc
)
106 struct details_trace_class_meta
*details_tc_meta
;
109 if (!ctx
->details_comp
->cfg
.with_meta
) {
110 need_to_write
= false;
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
;
119 return need_to_write
;
122 int details_did_write_trace_class(struct details_write_ctx
*ctx
,
123 const bt_trace_class
*tc
)
126 struct details_trace_class_meta
*details_tc_meta
;
128 BT_ASSERT(ctx
->details_comp
->cfg
.with_meta
);
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
) {
140 void trace_destruction_listener(const bt_trace
*trace
, void *data
)
142 struct details_comp
*details_comp
= data
;
144 BT_ASSERT(details_comp
);
145 BT_ASSERT(details_comp
->traces
);
147 /* Remove from hash table, which also destroys the value */
148 g_hash_table_remove(details_comp
->traces
, trace
);
152 struct details_trace
*create_details_trace(uint64_t unique_id
)
154 struct details_trace
*details_trace
= g_new0(struct details_trace
, 1);
156 if (!details_trace
) {
160 details_trace
->unique_id
= unique_id
;
161 details_trace
->trace_destruction_listener_id
= UINT64_C(-1);
164 return details_trace
;
168 int details_trace_unique_id(struct details_write_ctx
*ctx
,
169 const bt_trace
*trace
, uint64_t *unique_id
)
172 struct details_trace
*details_trace
= NULL
;
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
,
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
) {
185 ctx
->details_comp
->next_unique_trace_id
++;
187 /* Register trace destruction listener if there's none */
188 if (bt_trace_add_destruction_listener(trace
,
189 trace_destruction_listener
,
191 &details_trace
->trace_destruction_listener_id
)) {
195 BT_ASSERT(details_trace
->trace_destruction_listener_id
!=
198 /* Move to hash table */
199 g_hash_table_insert(ctx
->details_comp
->traces
, (gpointer
) trace
,
201 details_trace
= NULL
;
204 details_trace
= g_hash_table_lookup(
205 ctx
->details_comp
->traces
, trace
);
206 *unique_id
= details_trace
->unique_id
;
207 details_trace
= NULL
;
216 g_free(details_trace
);