Start on the runtime console subscriber

This commit is contained in:
Nadja Reitzenstein 2022-06-21 13:06:12 +02:00
parent 58f40d98ed
commit df7bd80d06
4 changed files with 96 additions and 1 deletions

View File

@ -123,4 +123,4 @@ tempfile = "3.2"
shadow-rs = "0.11" shadow-rs = "0.11"
[workspace] [workspace]
members = ["modules/*", "api"] members = ["runtime/*", "modules/*", "api"]

View File

@ -0,0 +1,10 @@
[package]
name = "console"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
console-api = "0.3"
tracing = "0.1"

View File

@ -0,0 +1,75 @@
use std::fmt;
use std::fmt::Formatter;
use std::ptr;
use std::sync::atomic::{AtomicPtr, AtomicUsize, Ordering};
use tracing::Metadata;
pub(crate) struct Callsites<const MAX_CALLSITES: usize> {
array: [AtomicPtr<Metadata<'static>>; MAX_CALLSITES],
len: AtomicUsize,
}
impl<const MAX_CALLSITES: usize> Callsites<MAX_CALLSITES> {
pub(crate) fn insert(&self, callsite: &'static Metadata<'static>) {
if self.contains(callsite) {
return;
}
let idx = self.len.fetch_add(1, Ordering::AcqRel);
if idx <= MAX_CALLSITES {
self.array[idx]
.compare_exchange(
ptr::null_mut(),
callsite as *const _ as *mut _,
Ordering::AcqRel,
Ordering::Acquire,
)
.expect("would have clobbered callsite array");
} else {
todo!("Need to spill callsite over into backup storage");
}
}
pub(crate) fn contains(&self, callsite: &'static Metadata<'static>) -> bool {
let mut idx = 0;
let mut end = self.len.load(Ordering::Acquire);
while {
for cs in &self.array[idx..end] {
let ptr = cs.load(Ordering::Acquire);
let meta = unsafe { ptr as *const _ as &'static Metadata<'static> };
if meta.callsite() == callsite.callsite() {
return true;
}
}
idx = end;
// Check if new callsites were added since we iterated
end = self.len.load(Ordering::Acquire);
end > idx
} {}
false
}
}
impl<const MAX_CALLSITES: usize> Default for Callsites<MAX_CALLSITES> {
fn default() -> Self {
const NULLPTR: AtomicPtr<_> = AtomicPtr::new(ptr::null_mut());
Self {
array: [NULLPTR; MAX_CALLSITES],
len: AtomicUsize::new(0),
}
}
}
impl<const MAX_CALLSITES: usize> fmt::Debug for Callsites<MAX_CALLSITES> {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
let len = self.len.load(Ordering::Acquire);
f.debug_struct("Callsites")
.field("MAX_CALLSITES", &MAX_CALLSITES)
.field("array", &&self.array[..len])
.field("len", &len)
.finish()
}
}

View File

@ -0,0 +1,10 @@
mod callsites;
#[cfg(test)]
mod tests {
#[test]
fn it_works() {
let result = 2 + 2;
assert_eq!(result, 4);
}
}