clf/lib.rs
1/*!
2Flush the cpu cache line by `__builtin_clear_cache()`
3
4This crate can be used when you do benchmarks that are not dependent on the cpu cache.
5
6# Supports
7
8- gcc and clang
9- gnu and musl
10- x86_64, aarch64, mips64el, powerpc64le ... etc
11- minimum support rustc 1.56.1 (59eed8a2a 2021-11-01)
12
13# Bugs
14
15- armv7-unknown-linux-musleabihf: can not compile
16- x86_64-pc-windows-msvc: can not compile
17
18# Examples
19Easy to use:
20
21```text
22let a = vec![1, 2, 3, 4, 5, 6, 7, 8, 9];
23clf::cache_line_flush_with_slice(&a);
24```
25
26or
27
28```text
29let a = vec![1, 2, 3, 4, 5, 6, 7, 8, 9];
30let begin_ptr = a.as_ptr();
31let end_ptr = unsafe { begin_ptr.add(a.len()) };
32clf::cache_line_flush_with_ptr(begin_ptr, end_ptr);
33```
34
35# References
36
37[CPU cache](https://en.wikipedia.org/wiki/CPU_cache)
38
39*/
40#[link(name = "clf")]
41extern "C" {
42 fn _cache_line_flush(begin_ptr: *const u8, end_ptr: *const u8);
43}
44
45///
46/// flush the cpu cache line, this parameters are pointers.
47///
48#[allow(clippy::not_unsafe_ptr_arg_deref)]
49pub fn cache_line_flush_with_ptr(begin_ptr: *const u8, end_ptr: *const u8) {
50 unsafe { _cache_line_flush(begin_ptr, end_ptr) };
51}
52
53///
54/// flush the cpu cache line, this parameter is a slice.
55///
56pub fn cache_line_flush_with_slice<T>(slice: &[T]) {
57 let begin_ptr = slice.as_ptr();
58 let end_ptr = unsafe { begin_ptr.add(slice.len()) };
59 unsafe { _cache_line_flush(begin_ptr as *const u8, end_ptr as *const u8) };
60}
61
62#[cfg(test)]
63mod tests {
64 #[test]
65 fn it_works_1() {
66 let a = [1, 2, 3, 4, 5, 6, 7, 8, 9];
67 super::cache_line_flush_with_ptr(a.as_ptr(), unsafe { a.as_ptr().add(a.len()) });
68 assert_eq!(2 + 2, 4);
69 }
70 #[test]
71 fn it_works_2() {
72 let a = vec![1, 2, 3, 4, 5, 6, 7, 8, 9];
73 super::cache_line_flush_with_slice(&a);
74 assert_eq!(2 + 2, 4);
75 }
76}