micromegas_tracing/spans/
block.rs

1use super::{
2    BeginAsyncNamedSpanEvent, BeginAsyncSpanEvent, BeginThreadNamedSpanEvent, BeginThreadSpanEvent,
3    EndAsyncNamedSpanEvent, EndAsyncSpanEvent, EndThreadNamedSpanEvent, EndThreadSpanEvent,
4    SpanLocation, SpanLocationRecord, SpanMetadata, SpanRecord,
5};
6use crate::{
7    event::{EventBlock, EventStream, ExtractDeps},
8    string_id::StringId,
9};
10use micromegas_transit::{Utf8StaticStringDependency, prelude::*};
11use std::collections::HashSet;
12
13declare_queue_struct!(
14    struct ThreadEventQueue<
15        BeginThreadSpanEvent,
16        EndThreadSpanEvent,
17        BeginThreadNamedSpanEvent,
18        EndThreadNamedSpanEvent,
19        BeginAsyncSpanEvent,
20        EndAsyncSpanEvent,
21        BeginAsyncNamedSpanEvent,
22        EndAsyncNamedSpanEvent,
23    > {}
24);
25
26declare_queue_struct!(
27    struct ThreadDepsQueue<SpanRecord, SpanLocationRecord, Utf8StaticStringDependency> {}
28);
29
30fn record_scope_event_dependencies(
31    thread_span_desc: &'static SpanMetadata,
32    recorded_deps: &mut HashSet<u64>,
33    deps: &mut ThreadDepsQueue,
34) {
35    let thread_span_ptr = thread_span_desc as *const _ as u64;
36    if recorded_deps.insert(thread_span_ptr) {
37        let name = Utf8StaticStringDependency::from(thread_span_desc.name);
38        if recorded_deps.insert(name.ptr as u64) {
39            deps.push(name);
40        }
41        let target = Utf8StaticStringDependency::from(thread_span_desc.location.target);
42        if recorded_deps.insert(target.ptr as u64) {
43            deps.push(target);
44        }
45        let module_path = Utf8StaticStringDependency::from(thread_span_desc.location.module_path);
46        if recorded_deps.insert(module_path.ptr as u64) {
47            deps.push(module_path);
48        }
49        let file = Utf8StaticStringDependency::from(thread_span_desc.location.file);
50        if recorded_deps.insert(file.ptr as u64) {
51            deps.push(file);
52        }
53        deps.push(SpanRecord {
54            id: thread_span_ptr,
55            name: thread_span_desc.name.as_ptr(),
56            target: thread_span_desc.location.target.as_ptr(),
57            module_path: thread_span_desc.location.module_path.as_ptr(),
58            file: thread_span_desc.location.file.as_ptr(),
59            line: thread_span_desc.location.line,
60            lod: thread_span_desc.location.lod as u32,
61        });
62    }
63}
64
65fn record_named_scope_event_dependencies(
66    thread_span_location: &'static SpanLocation,
67    name: &StringId,
68    recorded_deps: &mut HashSet<u64>,
69    deps: &mut ThreadDepsQueue,
70) {
71    let location_id = thread_span_location as *const _ as u64;
72    if recorded_deps.insert(location_id) {
73        let target = Utf8StaticStringDependency::from(thread_span_location.target);
74        if recorded_deps.insert(target.ptr as u64) {
75            deps.push(target);
76        }
77        let module_path = Utf8StaticStringDependency::from(thread_span_location.module_path);
78        if recorded_deps.insert(module_path.ptr as u64) {
79            deps.push(module_path);
80        }
81        let file = Utf8StaticStringDependency::from(thread_span_location.file);
82        if recorded_deps.insert(file.ptr as u64) {
83            deps.push(file);
84        }
85        deps.push(SpanLocationRecord {
86            id: location_id,
87            target: thread_span_location.target.as_ptr(),
88            module_path: thread_span_location.module_path.as_ptr(),
89            file: thread_span_location.file.as_ptr(),
90            line: thread_span_location.line,
91            lod: thread_span_location.lod as u32,
92        });
93    }
94
95    if recorded_deps.insert(name.id()) {
96        deps.push(Utf8StaticStringDependency::from(name));
97    }
98}
99
100impl ExtractDeps for ThreadEventQueue {
101    type DepsQueue = ThreadDepsQueue;
102
103    fn extract(&self) -> Self::DepsQueue {
104        let mut deps = ThreadDepsQueue::new(1024 * 1024);
105        let mut recorded_deps = HashSet::new();
106        for x in self.iter() {
107            match x {
108                ThreadEventQueueAny::BeginThreadSpanEvent(evt) => {
109                    record_scope_event_dependencies(
110                        evt.thread_span_desc,
111                        &mut recorded_deps,
112                        &mut deps,
113                    );
114                }
115                ThreadEventQueueAny::EndThreadSpanEvent(evt) => {
116                    record_scope_event_dependencies(
117                        evt.thread_span_desc,
118                        &mut recorded_deps,
119                        &mut deps,
120                    );
121                }
122                ThreadEventQueueAny::BeginThreadNamedSpanEvent(evt) => {
123                    record_named_scope_event_dependencies(
124                        evt.thread_span_location,
125                        &evt.name,
126                        &mut recorded_deps,
127                        &mut deps,
128                    );
129                }
130                ThreadEventQueueAny::EndThreadNamedSpanEvent(evt) => {
131                    record_named_scope_event_dependencies(
132                        evt.thread_span_location,
133                        &evt.name,
134                        &mut recorded_deps,
135                        &mut deps,
136                    );
137                }
138                ThreadEventQueueAny::BeginAsyncSpanEvent(evt) => {
139                    record_scope_event_dependencies(evt.span_desc, &mut recorded_deps, &mut deps);
140                }
141                ThreadEventQueueAny::EndAsyncSpanEvent(evt) => {
142                    record_scope_event_dependencies(evt.span_desc, &mut recorded_deps, &mut deps);
143                }
144                ThreadEventQueueAny::BeginAsyncNamedSpanEvent(evt) => {
145                    record_named_scope_event_dependencies(
146                        evt.span_location,
147                        &evt.name,
148                        &mut recorded_deps,
149                        &mut deps,
150                    );
151                }
152                ThreadEventQueueAny::EndAsyncNamedSpanEvent(evt) => {
153                    record_named_scope_event_dependencies(
154                        evt.span_location,
155                        &evt.name,
156                        &mut recorded_deps,
157                        &mut deps,
158                    );
159                }
160            }
161        }
162        deps
163    }
164}
165
166pub type ThreadBlock = EventBlock<ThreadEventQueue>;
167pub type ThreadStream = EventStream<ThreadBlock>;