GlobalLogBuffer

Struct GlobalLogBuffer 

Source
#[repr(C)]
pub(super) struct GlobalLogBuffer { writer_data: CachePadded64<WriterData>, reader_data: CachePadded64<ReaderData>, buffer: [LogEntry; 53], unread_bytes: AtomicUsize, }
Expand description

存储日志条目的锁无关环形缓冲区

采用多生产者单消费者 (MPSC) 设计,其中:

  • 多个 CPU 可以并发地写入日志而无需阻塞
  • 单个消费者线程按顺序读取日志

Fields§

§writer_data: CachePadded64<WriterData>

写入侧数据(由生产者更新)

§reader_data: CachePadded64<ReaderData>

读取侧数据(由消费者更新)

§buffer: [LogEntry; 53]

固定大小的日志条目数组

§unread_bytes: AtomicUsize

记录未读日志的总字节数

Implementations§

Source§

impl GlobalLogBuffer

Source

pub(super) const fn new() -> Self

在编译时创建一个新的全局日志缓冲区

Source

pub(super) fn write(&self, entry: &LogEntry)

将日志条目写入缓冲区

这是一个锁无关操作,执行以下步骤:

  1. 原子地获取一个唯一的序列号(票据)
  2. 使用模运算计算目标槽位索引
  3. 检查并处理潜在的缓冲区满(覆盖)逻辑
  4. 将日志数据复制到槽位(不包括 seq 字段)
  5. 使用 Release 内存屏障原子地设置 seq 来发布条目
  6. 增加未读字节计数
Source

fn handle_overwrite(&self, current_seq: usize)

处理缓冲区溢出,必要时推进读取指针

当缓冲区满且新的写入将覆盖未读条目时,此函数:

  1. 检测溢出条件
  2. 计算将被覆盖的条目数
  3. 更新丢弃计数
  4. 使用 CAS 循环原子地推进读取指针
Source

pub(super) fn read(&self) -> Option<LogEntry>

从缓冲区读取下一个日志条目

如果没有可用条目,则返回 None。这是一个锁无关的 单消费者操作,使用 Acquire 内存顺序确保与生产者的正确同步。 读取后会减少未读字节计数。

Source

pub(super) fn len(&self) -> usize

返回缓冲区中未读日志条目的数量

Source

pub(super) fn unread_bytes(&self) -> usize

返回未读日志的总字节数(格式化后)

Source

pub(super) fn dropped_count(&self) -> usize

返回由于缓冲区溢出而丢弃的日志总数

Source

pub(super) fn peek(&self, index: usize) -> Option<LogEntry>

非破坏性读取:按索引 peek 日志条目,不移动读指针

此方法允许读取缓冲区中的日志而不删除它们,主要用于 SyslogAction::ReadAll 操作。

§参数
  • index - 全局序列号(从 1 开始,与内部 seq 对应)
§返回值
  • Some(LogEntry) - 如果条目存在且有效
  • None - 如果索引超出范围或条目已被覆盖
§并发安全

此方法是完全无锁的,可以与 write 和 read 并发调用。

Source

pub(super) fn reader_index(&self) -> usize

获取当前可读取的起始索引(读指针位置)

Source

pub(super) fn writer_index(&self) -> usize

获取当前写入位置(下一个要写入的索引)

Auto Trait Implementations§

§

impl !Freeze for GlobalLogBuffer

§

impl RefUnwindSafe for GlobalLogBuffer

§

impl Send for GlobalLogBuffer

§

impl Sync for GlobalLogBuffer

§

impl Unpin for GlobalLogBuffer

§

impl UnwindSafe for GlobalLogBuffer

Blanket Implementations§

§

impl<T> Any for T
where T: 'static + ?Sized,

§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

impl<T> Borrow<T> for T
where T: ?Sized,

§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
§

impl<T> BorrowMut<T> for T
where T: ?Sized,

§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<T> From<T> for T

§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T, U> Into<U> for T
where U: From<T>,

§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of [From]<T> for U chooses to do.

§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.