Skip to content

Commit

Permalink
Redesign field set to support extern functions
Browse files Browse the repository at this point in the history
  • Loading branch information
Yuri6037 committed Jul 13, 2024
1 parent 5cf39af commit c2ca6e5
Show file tree
Hide file tree
Showing 8 changed files with 82 additions and 95 deletions.
8 changes: 4 additions & 4 deletions core/src/core/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ impl crate::profiler::Profiler for Engine {
todo!()
}

fn section_record<F: FieldSet>(&self, id: NonZeroU32, start: u64, end: u64, fields: &F) {
fn section_record(&self, id: NonZeroU32, start: u64, end: u64, fields: &FieldSet) {
todo!()
}
}
Expand All @@ -51,15 +51,15 @@ impl crate::trace::Tracer for Engine {
todo!()
}

fn span_create<F: FieldSet>(&self, callsite: NonZeroU32, fields: &F) -> NonZeroU32 {
fn span_create(&self, callsite: NonZeroU32, fields: &FieldSet) -> NonZeroU32 {
todo!()
}

fn span_enter(&self, id: NonZeroU32) {
todo!()
}

fn span_record<F: FieldSet>(&self, id: NonZeroU32, fields: &F) {
fn span_record(&self, id: NonZeroU32, fields: &FieldSet) {
todo!()
}

Expand All @@ -69,7 +69,7 @@ impl crate::trace::Tracer for Engine {
}

impl crate::logger::Logger for Engine {
fn log<F: FieldSet>(&self, callsite: &'static crate::logger::Callsite, msg: Arguments, fields: &F) {
fn log(&self, callsite: &'static crate::logger::Callsite, msg: Arguments, fields: &FieldSet) {
todo!()
}
}
135 changes: 61 additions & 74 deletions core/src/field.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,114 +28,101 @@

use std::fmt::Debug;

pub trait Visitor {
fn visit_int(&mut self, name: &str, value: i64) {
self.visit_debug(name, &value);
}
pub enum FieldValue<'a> {
Int(i64),
UInt(u64),
Float(f32),
Double(f64),
String(&'a str),
Debug(&'a dyn Debug)
}

fn visit_uint(&mut self, name: &str, value: u64) {
self.visit_debug(name, &value);
}
pub struct Field<'a> {
name: &'a str,
value: FieldValue<'a>
}

fn visit_float(&mut self, name: &str, value: f32) {
self.visit_debug(name, &value);
impl<'a> Field<'a> {
pub fn new(name: &'a str, value: impl Into<FieldValue<'a>>) -> Self {
Self {
name,
value: value.into()
}
}

fn visit_double(&mut self, name: &str, value: f64) {
self.visit_debug(name, &value);
pub fn new_debug(name: &'a str, value: &'a dyn Debug) -> Self {
Self {
name,
value: FieldValue::Debug(value)
}
}

fn visit_string(&mut self, name: &str, value: &str) {
self.visit_debug(name, &value);
pub fn name(&self) -> &str {
self.name
}

fn visit_debug<T: Debug>(&mut self, name: &str, debug: &T);
}

pub trait FieldSet {
fn record<V: Visitor>(&self, visitor: &mut V);
}

impl FieldSet for () {
fn record<V: Visitor>(&self, _: &mut V) {
pub fn value(&self) -> &FieldValue<'a> {
&self.value
}
}

macro_rules! impl_tuple_fieldset {
($(($($id: tt: $name: ident),*)),*) => {
macro_rules! impl_into_field_value {
// Would've preferred expr, but turns out expr is useless in macros, so let's not use it.
($($t: ty => $func: ident),*) => {
$(
impl<$($name: FieldSet),*> FieldSet for ($($name),*) {
fn record<V: Visitor>(&self, visitor: &mut V) {
$(
self.$id.record(visitor);
)*
impl<'a> From<$t> for FieldValue<'a> {
fn from(value: $t) -> Self {
FieldValue::$func(value as _)
}
}
)*
};
}

impl_tuple_fieldset!{
(0: T, 1: T1),
(0: T, 1: T1, 2: T2),
(0: T, 1: T1, 2: T2, 3: T3),
(0: T, 1: T1, 2: T2, 3: T3, 4: T4),
(0: T, 1: T1, 2: T2, 3: T3, 4: T4, 5: T5),
(0: T, 1: T1, 2: T2, 3: T3, 4: T4, 5: T5, 6: T6),
(0: T, 1: T1, 2: T2, 3: T3, 4: T4, 5: T5, 6: T6, 7: T7),
(0: T, 1: T1, 2: T2, 3: T3, 4: T4, 5: T5, 6: T6, 7: T7, 8: T8),
(0: T, 1: T1, 2: T2, 3: T3, 4: T4, 5: T5, 6: T6, 7: T7, 8: T8, 9: T9)
impl_into_field_value! {
u8 => UInt,
u16 => UInt,
u32 => UInt,
u64 => UInt,
i8 => Int,
i16 => Int,
i32 => Int,
i64 => Int,
f32 => Float,
f64 => Double
}

macro_rules! impl_fieldset {
// Would've preferred expr, but turns out expr is useless in macros, so let's not use it.
($($t: ty => $func: ident),*) => {
$(
impl FieldSet for (&str, $t) {
fn record<V: Visitor>(&self, visitor: &mut V) {
let (name, value) = self;
visitor.$func(name, *value as _);
}
}
)*
};
impl<'a> From<&'a str> for FieldValue<'a> {
fn from(value: &'a str) -> Self {
Self::String(value)
}
}

impl_fieldset! {
u8 => visit_uint,
u16 => visit_uint,
u32 => visit_uint,
u64 => visit_uint,
i8 => visit_int,
i16 => visit_int,
i32 => visit_int,
i64 => visit_int,
f32 => visit_float,
f64 => visit_double,
&str => visit_string
}
pub struct FieldSet<'a>(&'a [Field<'a>]);

pub struct D<T>(pub T);
impl<'a> FieldSet<'a> {
pub fn new(fields: &'a [Field<'a>]) -> Self {
Self(fields)
}

impl<T: Debug> FieldSet for (&str, D<T>) {
fn record<V: Visitor>(&self, visitor: &mut V) {
visitor.visit_debug(self.0, &self.1.0);
pub fn iter(&self) -> impl Iterator<Item=&'a Field<'a>> {
self.0.iter()
}
}

#[macro_export]
macro_rules! field {
($name: ident) => {(stringify!($name), $name)};
(?$name: ident) => {(stringify!($name), $crate::field::D($name))};
($name: ident = $value: expr) => {(stringify!($name), $value)};
($name: ident = ?$value: expr) => {(stringify!($name), $crate::field::D($value))};
($name: ident) => {$crate::field::Field::new(stringify!($name), $name)};
(?$name: ident) => {$crate::field::Field::new_debug(stringify!($name), &$name)};
($name: ident = $value: expr) => {$crate::field::Field::new(stringify!($name), $value)};
($name: ident = ?$value: expr) => {$crate::field::Field::new_debug(stringify!($name), &$value)};
}

#[macro_export]
macro_rules! fields {
($({$($field: tt)*})*) => {
($(
$crate::field::FieldSet::new(&[$(
field!($($field)*),
)*)
)*])
};
}
2 changes: 1 addition & 1 deletion core/src/logger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ impl Callsite {
}

pub trait Logger {
fn log<F: FieldSet>(&self, callsite: &'static Callsite, msg: Arguments, fields: &F);
fn log(&self, callsite: &'static Callsite, msg: Arguments, fields: &FieldSet);
}

#[cfg(test)]
Expand Down
4 changes: 2 additions & 2 deletions core/src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ macro_rules! log {
static _CALLSITE: $crate::logger::Callsite = $crate::logger::Callsite::new(bp3d_logger::Location::new(module_path!(), file!(), line!()), $level);
use $crate::logger::Logger;
$crate::core::ENGINE.get().map(|v|
v.log(&_CALLSITE, format_args!($msg $(, $($args),*)?), &$($crate::field!($($field)*),)*)
v.log(&_CALLSITE, format_args!($msg $(, $($args),*)?), &$crate::field::FieldSet::new(&[$($crate::field!($($field)*),)*]))
);
}
};
Expand All @@ -42,7 +42,7 @@ macro_rules! log {
static _CALLSITE: $crate::logger::Callsite = $crate::logger::Callsite::new(bp3d_logger::Location::new(module_path!(), file!(), line!()), $level);
use $crate::logger::Logger;
$crate::core::ENGINE.get().map(|v|
v.log(&_CALLSITE, format_args!($msg $(, $($args),*)?), &())
v.log(&_CALLSITE, format_args!($msg $(, $($args),*)?), &$crate::field::FieldSet::new(&[]))
);
}
};
Expand Down
3 changes: 2 additions & 1 deletion core/src/profiler/interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,10 @@ use crate::profiler::section::Section;

pub trait Profiler {
fn section_register(&self, section: &'static Section) -> NonZeroU32;
fn section_record<F: FieldSet>(&self, id: NonZeroU32, start: u64, end: u64, fields: &F);
fn section_record(&self, id: NonZeroU32, start: u64, end: u64, fields: &FieldSet);
}

extern "Rust" {
pub fn profiler_section_register(section: &'static Section) -> NonZeroU32;
pub fn profiler_section_record(id: NonZeroU32, start: u64, end: u64, fields: &FieldSet);
}
17 changes: 8 additions & 9 deletions core/src/profiler/section.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,13 @@ thread_local! {
static CUR_TIME: Instant = Instant::now();
}

pub struct Entered<F: FieldSet> {
pub struct Entered<'a> {
id: NonZeroU32,
start: u64,
fields: F
fields: FieldSet<'a>
}

impl<F: FieldSet> Drop for Entered<F> {
impl<'a> Drop for Entered<'a> {
fn drop(&mut self) {
let end = CUR_TIME.with(|v| v.elapsed().as_nanos() as _);
let engine = unsafe { crate::core::ENGINE.get().unwrap_unchecked() };
Expand Down Expand Up @@ -108,7 +108,7 @@ impl Section {
self.id.get_or_init(|| crate::core::ENGINE.get().map(|v| v.section_register(self)))
}

pub fn enter<F: FieldSet>(&'static self, fields: F) -> Option<Entered<F>> {
pub fn enter<'a>(&'static self, fields: FieldSet<'a>) -> Option<Entered<'a>> {
let id = self.get_id();
id.map(|id| Entered {
id,
Expand All @@ -121,7 +121,6 @@ impl Section {
#[cfg(test)]
mod tests {
use crate::{field, fields, location};
use crate::field::D;
use crate::profiler::profiler_section_register;
use crate::profiler::section::{Level, Section};

Expand All @@ -138,20 +137,20 @@ mod tests {
#[test]
fn basic() {
static SECTION: Section = Section::new("api_test", location!(), Level::Event);
unsafe { profiler_section_register(&SECTION) };
//unsafe { profiler_section_register(&SECTION) };
}

#[test]
fn api_test() {
static SECTION: Section = Section::new("api_test", location!(), Level::Event);
static SECTION2: Section = Section::new("api_test2", location!(), Level::Event)
.set_parent(&SECTION);
assert!(SECTION.enter(()).is_none());
/*assert!(SECTION.enter([]).is_none());
assert!(SECTION.enter(("test", 42)).is_none());
assert!(SECTION.enter(("test", "test 123")).is_none());
assert!(SECTION.enter(("test", 42.42)).is_none());
assert!(SECTION.enter(("test", D(Level::Event))).is_none());
assert!(SECTION.enter((("test", D(Level::Event)), ("test2", 42))).is_none());
assert!(SECTION.enter(("test", Level::Event)).is_none());
assert!(SECTION.enter((("test", Level::Event), ("test2", 42))).is_none());*/
let value = 32;
let str = "this is a test";
let lvl = Level::Event;
Expand Down
4 changes: 2 additions & 2 deletions core/src/trace/interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ use crate::trace::span::Callsite;

pub trait Tracer {
fn register_callsite(&self, callsite: &'static Callsite) -> NonZeroU32;
fn span_create<F: FieldSet>(&self, callsite: NonZeroU32, fields: &F) -> NonZeroU32;
fn span_create(&self, callsite: NonZeroU32, fields: &FieldSet) -> NonZeroU32;
fn span_enter(&self, id: NonZeroU32);
fn span_record<F: FieldSet>(&self, id: NonZeroU32, fields: &F);
fn span_record(&self, id: NonZeroU32, fields: &FieldSet);
fn span_exit(&self, id: NonZeroU32);
}
4 changes: 2 additions & 2 deletions core/src/trace/span.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ pub struct Span {
}

impl Span {
pub fn new<F: FieldSet>(callsite: &'static Callsite, fields: &F) -> Self {
pub fn new(callsite: &'static Callsite, fields: &FieldSet) -> Self {
let id = callsite.get_id()
.map(|cid| crate::core::ENGINE.get().map(|v| v.span_create(cid, fields)))
.flatten();
Expand All @@ -66,7 +66,7 @@ impl Span {
}
}

pub fn record<F: FieldSet>(&self, fields: &F) {
pub fn record(&self, fields: &FieldSet) {
if let Some(id) = self.id {
unsafe { crate::core::ENGINE.get().unwrap_unchecked().span_record(id, fields) };
}
Expand Down

0 comments on commit c2ca6e5

Please sign in to comment.