allocative/
global_root.rs

1/*
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under both the MIT license found in the
5 * LICENSE-MIT file in the root directory of this source tree and the Apache
6 * License, Version 2.0 found in the LICENSE-APACHE file in the root directory
7 * of this source tree.
8 */
9
10use std::sync::Mutex;
11
12use crate::allocative_trait::Allocative;
13
14static ROOTS: Mutex<Vec<&'static (dyn Allocative + Sync + 'static)>> = Mutex::new(Vec::new());
15
16/// Register global root which can be later traversed by profiler.
17///
18/// [`root`](crate::root) macro can be used to register global root.
19pub fn register_root(root: &'static (dyn Allocative + Sync + 'static)) {
20    ROOTS.lock().unwrap().push(root);
21}
22
23pub(crate) fn roots() -> Vec<&'static (dyn Allocative + Sync + 'static)> {
24    ROOTS.lock().unwrap().clone()
25}
26
27#[cfg(test)]
28mod tests {
29    use crate as allocative;
30    use crate::Allocative;
31    use crate::FlameGraphBuilder;
32
33    #[derive(Allocative)]
34    struct TestGlobalRoot {
35        x: u32,
36    }
37
38    #[allocative::root]
39    static TEST_GLOBAL_ROOT: TestGlobalRoot = TestGlobalRoot { x: 17 };
40
41    #[test]
42    fn test_derive() {
43        let mut fg = FlameGraphBuilder::default();
44        fg.visit_global_roots();
45        let fg = fg.finish_and_write_flame_graph();
46        assert!(fg.contains("TestGlobalRoot;x;u32 4"), "{}", fg);
47    }
48}