1 use std::ffi::c_void; 2 use std::io::Error; 3 use windows_sys::Win32::System::Diagnostics::Debug::FlushInstructionCache; 4 use windows_sys::Win32::System::Threading::FlushProcessWriteBuffers; 5 use windows_sys::Win32::System::Threading::GetCurrentProcess; 6 7 pub use std::io::Result; 8 9 /// See docs on [crate::pipeline_flush_mt] for a description of what this function is trying to do. 10 #[inline] pipeline_flush_mt() -> Result<()>11pub(crate) fn pipeline_flush_mt() -> Result<()> { 12 // If we are here, it means that the user has already called [cache_clear] for all buffers that 13 // are going to be holding code. We don't really care about flushing the write buffers, but 14 // the other guarantee that microsoft provides on this API. As documented: 15 // 16 // "The function generates an interprocessor interrupt (IPI) to all processors that are part of 17 // the current process affinity. It guarantees the visibility of write operations performed on 18 // one processor to the other processors." 19 // 20 // This all-core IPI acts as a core serializing operation, equivalent to a "broadcast" `ISB` 21 // instruction that the architecture does not provide and which is what we really want. 22 // 23 // See: https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-flushprocesswritebuffers 24 if cfg!(target_arch = "aarch64") { 25 unsafe { 26 FlushProcessWriteBuffers(); 27 } 28 } 29 30 Ok(()) 31 } 32 33 /// See docs on [crate::clear_cache] for a description of what this function is trying to do. 34 #[inline] clear_cache(ptr: *const c_void, len: usize) -> Result<()>35pub(crate) fn clear_cache(ptr: *const c_void, len: usize) -> Result<()> { 36 // See: 37 // * https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-flushinstructioncache 38 // * https://devblogs.microsoft.com/oldnewthing/20190902-00/?p=102828 39 unsafe { 40 let res = FlushInstructionCache(GetCurrentProcess(), ptr, len); 41 if res == 0 { 42 return Err(Error::last_os_error()); 43 } 44 } 45 46 Ok(()) 47 } 48