micromegas_tracing/spans/
block.rs1use super::{
2 BeginAsyncDynNamedSpanEvent, BeginAsyncNamedSpanEvent, BeginAsyncSpanEvent,
3 BeginThreadDynNamedSpanEvent, BeginThreadNamedSpanEvent, BeginThreadSpanEvent,
4 EndAsyncDynNamedSpanEvent, EndAsyncNamedSpanEvent, EndAsyncSpanEvent,
5 EndThreadDynNamedSpanEvent, EndThreadNamedSpanEvent, EndThreadSpanEvent, SpanLocation,
6 SpanLocationRecord, SpanMetadata, SpanRecord,
7};
8use crate::{
9 dyn_deps::DynDeps,
10 event::{EventBlock, EventStream, ExtractDeps},
11 property_set::StringDepsQueue,
12 string_id::{DynStringId, StringId},
13};
14use micromegas_transit::{StaticStringDependency, Utf8StaticStringDependency, prelude::*};
15use std::collections::HashSet;
16
17declare_queue_struct!(
18 struct ThreadEventQueue<
19 BeginThreadSpanEvent,
20 EndThreadSpanEvent,
21 BeginThreadNamedSpanEvent,
22 EndThreadNamedSpanEvent,
23 BeginAsyncSpanEvent,
24 EndAsyncSpanEvent,
25 BeginAsyncNamedSpanEvent,
26 EndAsyncNamedSpanEvent,
27 BeginThreadDynNamedSpanEvent,
28 EndThreadDynNamedSpanEvent,
29 BeginAsyncDynNamedSpanEvent,
30 EndAsyncDynNamedSpanEvent,
31 > {}
32);
33
34declare_queue_struct!(
35 struct ThreadDepsQueue<
36 SpanRecord,
37 SpanLocationRecord,
38 Utf8StaticStringDependency,
39 StaticStringDependency,
40 > {}
41);
42
43impl StringDepsQueue for ThreadDepsQueue {
44 fn push_string(&mut self, dep: StaticStringDependency) {
45 self.push(dep);
46 }
47}
48
49fn record_scope_event_dependencies(
50 thread_span_desc: &'static SpanMetadata,
51 recorded_deps: &mut HashSet<u64>,
52 deps: &mut ThreadDepsQueue,
53) {
54 let thread_span_ptr = thread_span_desc as *const _ as u64;
55 if recorded_deps.insert(thread_span_ptr) {
56 let name = Utf8StaticStringDependency::from(thread_span_desc.name);
57 if recorded_deps.insert(name.ptr as u64) {
58 deps.push(name);
59 }
60 let target = Utf8StaticStringDependency::from(thread_span_desc.location.target);
61 if recorded_deps.insert(target.ptr as u64) {
62 deps.push(target);
63 }
64 let module_path = Utf8StaticStringDependency::from(thread_span_desc.location.module_path);
65 if recorded_deps.insert(module_path.ptr as u64) {
66 deps.push(module_path);
67 }
68 let file = Utf8StaticStringDependency::from(thread_span_desc.location.file);
69 if recorded_deps.insert(file.ptr as u64) {
70 deps.push(file);
71 }
72 deps.push(SpanRecord {
73 id: thread_span_ptr,
74 name: thread_span_desc.name.as_ptr(),
75 target: thread_span_desc.location.target.as_ptr(),
76 module_path: thread_span_desc.location.module_path.as_ptr(),
77 file: thread_span_desc.location.file.as_ptr(),
78 line: thread_span_desc.location.line,
79 lod: thread_span_desc.location.lod as u32,
80 });
81 }
82}
83
84fn record_span_location_dependencies(
85 thread_span_location: &'static SpanLocation,
86 recorded_deps: &mut HashSet<u64>,
87 deps: &mut ThreadDepsQueue,
88) {
89 let location_id = thread_span_location as *const _ as u64;
90 if recorded_deps.insert(location_id) {
91 let target = Utf8StaticStringDependency::from(thread_span_location.target);
92 if recorded_deps.insert(target.ptr as u64) {
93 deps.push(target);
94 }
95 let module_path = Utf8StaticStringDependency::from(thread_span_location.module_path);
96 if recorded_deps.insert(module_path.ptr as u64) {
97 deps.push(module_path);
98 }
99 let file = Utf8StaticStringDependency::from(thread_span_location.file);
100 if recorded_deps.insert(file.ptr as u64) {
101 deps.push(file);
102 }
103 deps.push(SpanLocationRecord {
104 id: location_id,
105 target: thread_span_location.target.as_ptr(),
106 module_path: thread_span_location.module_path.as_ptr(),
107 file: thread_span_location.file.as_ptr(),
108 line: thread_span_location.line,
109 lod: thread_span_location.lod as u32,
110 });
111 }
112}
113
114fn record_named_scope_event_dependencies(
115 thread_span_location: &'static SpanLocation,
116 name: &StringId,
117 recorded_deps: &mut HashSet<u64>,
118 deps: &mut ThreadDepsQueue,
119) {
120 record_span_location_dependencies(thread_span_location, recorded_deps, deps);
121 if recorded_deps.insert(name.id()) {
122 deps.push(Utf8StaticStringDependency::from(name));
123 }
124}
125
126impl ExtractDeps for ThreadEventQueue {
127 type DepsQueue = ThreadDepsQueue;
128
129 fn extract(&self, dyn_deps: &DynDeps<Self::DepsQueue>) -> Self::DepsQueue {
130 let mut deps = ThreadDepsQueue::new(1024 * 1024);
131 let mut recorded_deps = HashSet::new();
132 for x in self.iter() {
133 match x {
134 ThreadEventQueueAny::BeginThreadSpanEvent(evt) => {
135 record_scope_event_dependencies(
136 evt.thread_span_desc,
137 &mut recorded_deps,
138 &mut deps,
139 );
140 }
141 ThreadEventQueueAny::EndThreadSpanEvent(evt) => {
142 record_scope_event_dependencies(
143 evt.thread_span_desc,
144 &mut recorded_deps,
145 &mut deps,
146 );
147 }
148 ThreadEventQueueAny::BeginThreadNamedSpanEvent(evt) => {
149 record_named_scope_event_dependencies(
150 evt.thread_span_location,
151 &evt.name,
152 &mut recorded_deps,
153 &mut deps,
154 );
155 }
156 ThreadEventQueueAny::EndThreadNamedSpanEvent(evt) => {
157 record_named_scope_event_dependencies(
158 evt.thread_span_location,
159 &evt.name,
160 &mut recorded_deps,
161 &mut deps,
162 );
163 }
164 ThreadEventQueueAny::BeginAsyncSpanEvent(evt) => {
165 record_scope_event_dependencies(evt.span_desc, &mut recorded_deps, &mut deps);
166 }
167 ThreadEventQueueAny::EndAsyncSpanEvent(evt) => {
168 record_scope_event_dependencies(evt.span_desc, &mut recorded_deps, &mut deps);
169 }
170 ThreadEventQueueAny::BeginAsyncNamedSpanEvent(evt) => {
171 record_named_scope_event_dependencies(
172 evt.span_location,
173 &evt.name,
174 &mut recorded_deps,
175 &mut deps,
176 );
177 }
178 ThreadEventQueueAny::EndAsyncNamedSpanEvent(evt) => {
179 record_named_scope_event_dependencies(
180 evt.span_location,
181 &evt.name,
182 &mut recorded_deps,
183 &mut deps,
184 );
185 }
186 ThreadEventQueueAny::BeginThreadDynNamedSpanEvent(evt) => {
187 record_span_location_dependencies(
188 evt.thread_span_location,
189 &mut recorded_deps,
190 &mut deps,
191 );
192 }
193 ThreadEventQueueAny::EndThreadDynNamedSpanEvent(evt) => {
194 record_span_location_dependencies(
195 evt.thread_span_location,
196 &mut recorded_deps,
197 &mut deps,
198 );
199 }
200 ThreadEventQueueAny::BeginAsyncDynNamedSpanEvent(evt) => {
201 record_span_location_dependencies(
202 evt.span_location,
203 &mut recorded_deps,
204 &mut deps,
205 );
206 }
207 ThreadEventQueueAny::EndAsyncDynNamedSpanEvent(evt) => {
208 record_span_location_dependencies(
209 evt.span_location,
210 &mut recorded_deps,
211 &mut deps,
212 );
213 }
214 }
215 }
216 deps.extend_from(dyn_deps.queue());
217 deps
218 }
219}
220
221pub type ThreadBlock = EventBlock<ThreadEventQueue>;
222pub type ThreadStream = EventStream<ThreadBlock>;
223
224impl ThreadStream {
225 pub fn push_dyn_named<T>(&mut self, name: &str, make: impl FnOnce(DynStringId) -> T)
227 where
228 T: InProcSerialize + ThreadEventQueueTypeIndex,
229 {
230 let (events, dyn_deps) = self.get_block_mut_parts();
231 let id = dyn_deps.intern_str(name);
232 events.push(make(DynStringId { id }));
233 }
234}