summaryrefslogtreecommitdiff
path: root/profiler/src/lib.rs
diff options
context:
space:
mode:
authorMica White <botahamec@outlook.com>2024-08-15 20:23:26 -0400
committerMica White <botahamec@outlook.com>2024-08-25 19:24:37 -0400
commit509e5ce1e17417a70b9bcce8bc6e33c05106811d (patch)
tree5b1fe60a65b5f42a90023ead03c32336033afa1f /profiler/src/lib.rs
parentdb9aa9f1bf49e8bede384b9ceb1e1fb82b522799 (diff)
Start profiling
Diffstat (limited to 'profiler/src/lib.rs')
-rw-r--r--profiler/src/lib.rs103
1 files changed, 103 insertions, 0 deletions
diff --git a/profiler/src/lib.rs b/profiler/src/lib.rs
new file mode 100644
index 0000000..d23ad24
--- /dev/null
+++ b/profiler/src/lib.rs
@@ -0,0 +1,103 @@
+use std::sync::OnceLock;
+
+use alligator_console::{ConsoleLogger, ConsoleMessage};
+use chrono::{DateTime, Utc};
+use scopeguard::ScopeGuard;
+
+static GLOBAL_PROFILER: OnceLock<Profiler> = OnceLock::new();
+
+struct Profiler {
+ logger: ConsoleLogger,
+ start_time: DateTime<Utc>,
+}
+
+impl Profiler {
+ fn new(logger: ConsoleLogger) -> Self {
+ Self {
+ logger,
+ start_time: Utc::now(),
+ }
+ }
+
+ fn current_timestamp(&self) -> i64 {
+ Utc::now()
+ .signed_duration_since(DateTime::UNIX_EPOCH)
+ .num_microseconds()
+ .unwrap_or(i64::MAX)
+ }
+
+ fn finish_frame(&self) {
+ self.logger.send(ConsoleMessage::FrameTime {
+ timestamp: self.current_timestamp(),
+ })
+ }
+
+ fn start_scope(&self, scope_name: String) {
+ self.logger.send(ConsoleMessage::ScopeStart {
+ scope_name,
+ timestamp: self.current_timestamp(),
+ })
+ }
+
+ fn end_scope(&self) {
+ self.logger.send(ConsoleMessage::ScopeEnd {
+ timestamp: self.current_timestamp(),
+ })
+ }
+}
+
+pub fn set_profiler(logger: ConsoleLogger) {
+ GLOBAL_PROFILER.get_or_init(|| Profiler::new(logger));
+}
+
+pub fn finish_frame() {
+ GLOBAL_PROFILER.get().unwrap().finish_frame();
+}
+
+pub fn start_scope(scope_name: impl AsRef<str>) {
+ GLOBAL_PROFILER
+ .get()
+ .unwrap()
+ .start_scope(scope_name.as_ref().to_string());
+}
+
+pub fn end_scope() {
+ GLOBAL_PROFILER.get().unwrap().end_scope();
+}
+
+pub fn profile_scope(scope_name: impl AsRef<str>) -> ScopeGuard<(), impl FnOnce(())> {
+ start_scope(scope_name);
+ scopeguard::guard((), |_| end_scope())
+}
+
+#[macro_export]
+macro_rules! scope {
+ ($scope_name: expr) => {
+ let _profiling_scope = $crate::profile_scope($scope_name);
+ };
+ () => {
+ let _profiling_scope = $crate::profile_scope("unnamed scope");
+ };
+}
+
+#[macro_export]
+macro_rules! function_name {
+ () => {{
+ fn f() {}
+ fn type_name_of<T>(_: T) -> &'static str {
+ std::any::type_name::<T>()
+ }
+ type_name_of(f)
+ .split("::")
+ .filter(|&part| part != "f")
+ .collect::<Vec<&str>>()
+ .join("::")
+ }};
+}
+
+#[macro_export]
+macro_rules! profile_function {
+ () => {
+ $crate::scope!($crate::function_name!());
+ };
+}