1 // Copyright (c) 2024 Huawei Technologies Co.,Ltd. All rights reserved. 2 // 3 // StratoVirt is licensed under Mulan PSL v2. 4 // You can use this software according to the terms and conditions of the Mulan 5 // PSL v2. 6 // You may obtain a copy of Mulan PSL v2 at: 7 // http://license.coscl.org.cn/MulanPSL2 8 // THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY 9 // KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO 10 // NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 11 // See the Mulan PSL v2 for more details. 12 13 use lazy_static::lazy_static; 14 use std::sync::atomic::{AtomicI32, Ordering}; 15 16 #[cfg(all(target_env = "ohos", feature = "trace_to_hitrace"))] 17 use crate::hitrace::{finish_trace, finish_trace_async, start_trace, start_trace_async}; 18 19 #[cfg(feature = "trace_to_ftrace")] 20 use crate::ftrace::write_trace_marker; 21 22 lazy_static! { 23 static ref TRACE_SCOPE_COUNTER: AtomicI32 = AtomicI32::new(i32::MIN); 24 } 25 26 #[derive(Clone)] 27 pub enum Scope { 28 Common(TraceScope), 29 Asyn(TraceScopeAsyn), 30 None, 31 } 32 33 #[derive(Clone)] 34 pub struct TraceScope {} 35 36 impl TraceScope { new(value: String) -> Self37 pub fn new(value: String) -> Self { 38 #[cfg(feature = "trace_to_logger")] 39 { 40 log::trace!("[SCOPE_START]{}", value); 41 } 42 #[cfg(feature = "trace_to_ftrace")] 43 { 44 write_trace_marker(&format!("[SCOPE_START]{}", value)); 45 } 46 #[cfg(all(target_env = "ohos", feature = "trace_to_hitrace"))] 47 { 48 start_trace(&value); 49 } 50 TraceScope {} 51 } 52 } 53 54 impl Drop for TraceScope { drop(&mut self)55 fn drop(&mut self) { 56 #[cfg(feature = "trace_to_logger")] 57 { 58 log::trace!("[SCOPE_END]"); 59 } 60 #[cfg(feature = "trace_to_ftrace")] 61 { 62 write_trace_marker("[SCOPE_END]"); 63 } 64 #[cfg(all(target_env = "ohos", feature = "trace_to_hitrace"))] 65 { 66 finish_trace() 67 } 68 } 69 } 70 71 #[derive(Clone)] 72 pub struct TraceScopeAsyn { 73 value: String, 74 id: i32, 75 } 76 77 impl TraceScopeAsyn { 78 #[allow(unused_variables)] new(value: String) -> Self79 pub fn new(value: String) -> Self { 80 // SAFETY: AtomicI32 can be safely shared between threads. 81 let id = TRACE_SCOPE_COUNTER 82 .fetch_update(Ordering::SeqCst, Ordering::SeqCst, |x| { 83 Some(x.wrapping_add(1)) 84 }) 85 .unwrap(); 86 #[cfg(feature = "trace_to_logger")] 87 { 88 log::trace!("[SCOPE_START(id={})]{}", id, value); 89 } 90 #[cfg(feature = "trace_to_ftrace")] 91 { 92 write_trace_marker(&format!("[SCOPE_START(id={})]{}", id, value)); 93 } 94 #[cfg(all(target_env = "ohos", feature = "trace_to_hitrace"))] 95 { 96 start_trace_async(&value, id); 97 } 98 TraceScopeAsyn { value, id } 99 } 100 } 101 102 impl Drop for TraceScopeAsyn { drop(&mut self)103 fn drop(&mut self) { 104 #[cfg(feature = "trace_to_logger")] 105 { 106 log::trace!("[SCOPE_END(id={})]{}", self.id, self.value); 107 } 108 #[cfg(feature = "trace_to_ftrace")] 109 { 110 write_trace_marker(&format!("[SCOPE_END(id={})]{}", self.id, self.value)); 111 } 112 #[cfg(all(target_env = "ohos", feature = "trace_to_hitrace"))] 113 { 114 finish_trace_async(&self.value, self.id); 115 } 116 } 117 } 118