//! CPU 屏障与同步原语（memory barrier / cpu hint）

#![no_std]
#![cfg_attr(any(aarch64_moana, aarch64_moana_std), feature(stdarch_arm_hints, stdarch_arm_barrier))]

use core::sync::atomic::{self, Ordering};

core::cfg_select! {
    any(aarch64_moana, aarch64_moana_std) => {
        #[path = "aarch64.rs"]
        mod arch;
    }
    any(riscv64_moana, riscv64_moana_std) => {
        #[path = "riscv64.rs"]
        mod arch;
    }
    _ => {
        #[path = "stub.rs"]
        mod arch;
    }
}

/// 处理器"小憩"
#[inline(always)]
pub fn cpu_relax() {
    arch::arch_cpu_relax();
}

/// 编译器内存屏障
///
/// 阻止当前位置前后读写编译器的重排序
#[inline(always)]
pub fn barrier() {
    atomic::compiler_fence(Ordering::SeqCst);
}

/// 处理器读内存屏障(rmb)
///
/// 保证屏障之前的读不会被重排到屏障之后(aarch64 `dmb ishld` / riscv `fence r,r`)。
#[inline(always)]
pub fn smp_rmb() {
    arch::arch_smp_rmb();
}

/// 处理器写内存屏障(wmb)
///
/// 保证屏障之前的写不会被重排到屏障之后(aarch64 `dmb ishst` / riscv `fence w,w`)。
#[inline(always)]
pub fn smp_wmb() {
    arch::arch_smp_wmb();
}

/// 处理器内存屏障
///
/// 根据指定的顺序, 防止编译器和处理器围绕它重新排序某些类型的内存操作,
/// 该函数具有最严格的屏障级别
#[inline(always)]
pub fn smp_mb() {
    arch::arch_smp_mb();
}

/// MMIO 写前屏障(写设备寄存器之前)
///
/// 保证此前的普通内存写在该 MMIO 写到达设备之前完成,对应 Linux 的 `__io_bw()`
/// (aarch64 `dmb oshst` / riscv `fence w,o`)。`fence w,o` 用 I/O(`o`)位显式约束设备
/// 顺序,故在弱序 I/O PMA(无 Svpbmt 强序保证)下亦安全。配合内核 `writel` 访问器使用。
#[inline(always)]
pub fn io_wmb() {
    arch::arch_io_wmb();
}

/// MMIO 读后屏障(读设备寄存器之后)
///
/// 保证该 MMIO 读先于后续读/IO 完成,对应 Linux 的 `__io_ar()`
/// (aarch64 `dmb oshld` / riscv `fence i,ir`)。配合 `readl` 类访问器使用。
#[inline(always)]
pub fn io_rmb() {
    arch::arch_io_rmb();
}

/// 处理器指令同步屏障(ARM `ISB`)
///
/// 主要服务 aarch64:刷新流水线,使系统寄存器写入对后续指令生效。RISC-V 无等价指令,
/// 其实现仅为 `fence.i`(指令流同步,用于自修改代码),**不提供** ARM 那种上下文同步语义;
/// riscv 侧如需地址翻译/CSR 同步,请直接用 `sfence.vma` 等专用屏障。
#[inline(always)]
pub fn isb() {
    arch::arch_isb();
}
