Path: blob/main/crates/jit-icache-coherence/src/win.rs
1691 views
use std::ffi::c_void;1use std::io::Error;2use windows_sys::Win32::System::Diagnostics::Debug::FlushInstructionCache;3use windows_sys::Win32::System::Threading::FlushProcessWriteBuffers;4use windows_sys::Win32::System::Threading::GetCurrentProcess;56pub use std::io::Result;78/// See docs on [crate::pipeline_flush_mt] for a description of what this function is trying to do.9#[inline]10pub(crate) fn pipeline_flush_mt() -> Result<()> {11// If we are here, it means that the user has already called [cache_clear] for all buffers that12// are going to be holding code. We don't really care about flushing the write buffers, but13// the other guarantee that microsoft provides on this API. As documented:14//15// "The function generates an interprocessor interrupt (IPI) to all processors that are part of16// the current process affinity. It guarantees the visibility of write operations performed on17// one processor to the other processors."18//19// This all-core IPI acts as a core serializing operation, equivalent to a "broadcast" `ISB`20// instruction that the architecture does not provide and which is what we really want.21//22// See: https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-flushprocesswritebuffers23if cfg!(target_arch = "aarch64") {24unsafe {25FlushProcessWriteBuffers();26}27}2829Ok(())30}3132/// See docs on [crate::clear_cache] for a description of what this function is trying to do.33#[inline]34pub(crate) fn clear_cache(ptr: *const c_void, len: usize) -> Result<()> {35// See:36// * https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-flushinstructioncache37// * https://devblogs.microsoft.com/oldnewthing/20190902-00/?p=10282838unsafe {39let res = FlushInstructionCache(GetCurrentProcess(), ptr, len);40if res == 0 {41return Err(Error::last_os_error());42}43}4445Ok(())46}474849