Profiling

This commit is contained in:
4lDO2
2023-10-07 22:05:44 +02:00
parent a285863335
commit f973bc4128
10 changed files with 219 additions and 22 deletions
+75
View File
@@ -1,3 +1,8 @@
use core::cell::UnsafeCell;
use core::sync::atomic::{AtomicUsize, Ordering};
use alloc::boxed::Box;
use crate::LogicalCpuId;
use crate::context::switch::ContextSwitchPercpu;
@@ -11,6 +16,76 @@ pub struct PercpuBlock {
// TODO: Put mailbox queues here, e.g. for TLB shootdown? Just be sure to 128-byte align it
// first to avoid cache invalidation.
pub profiling: Option<&'static RingBuffer>,
}
const N: usize = 64 * 1024 * 1024;
pub struct RingBuffer {
head: AtomicUsize,
tail: AtomicUsize,
buf: &'static [UnsafeCell<usize>; N],
pub(crate) nmi_kcount: AtomicUsize,
pub(crate) nmi_ucount: AtomicUsize,
}
impl RingBuffer {
unsafe fn advance_head(&self, n: usize) {
self.head.store(self.head.load(Ordering::Acquire).wrapping_add(n), Ordering::Release);
}
unsafe fn advance_tail(&self, n: usize) {
self.tail.store(self.tail.load(Ordering::Acquire).wrapping_add(n), Ordering::Release);
}
unsafe fn sender_owned(&self) -> [&[UnsafeCell<usize>]; 2] {
let head = self.head.load(Ordering::Acquire) % N;
let tail = self.tail.load(Ordering::Acquire) % N;
if head <= tail {
[&self.buf[tail..], &self.buf[..head]]
} else {
[&self.buf[tail..head], &[]]
}
}
unsafe fn receiver_owned(&self) -> [&[UnsafeCell<usize>]; 2] {
let head = self.head.load(Ordering::Acquire) % N;
let tail = self.tail.load(Ordering::Acquire) % N;
if head > tail {
[&self.buf[head..], &self.buf[..tail]]
} else {
[&self.buf[head..tail], &[]]
}
}
pub unsafe fn extend(&self, mut slice: &[usize]) -> usize {
let mut n = 0;
for mut sender_slice in self.sender_owned() {
while !slice.is_empty() && !sender_slice.is_empty() {
sender_slice[0].get().write(slice[0]);
slice = &slice[1..];
sender_slice = &sender_slice[1..];
n += 1;
}
}
self.advance_tail(n);
n
}
pub unsafe fn peek(&self) -> [&[usize]; 2] {
self.receiver_owned().map(|slice| core::slice::from_raw_parts(slice.as_ptr().cast(), slice.len()))
}
pub unsafe fn advance(&self, n: usize) {
self.advance_head(n)
}
pub fn create() -> &'static Self {
Box::leak(Box::new(Self {
head: AtomicUsize::new(0),
tail: AtomicUsize::new(0),
buf: Box::leak(unsafe { Box::new_zeroed().assume_init() }),
nmi_kcount: AtomicUsize::new(0),
nmi_ucount: AtomicUsize::new(0),
}))
}
}
// PercpuBlock::current() is implemented somewhere in the arch-specific modules