1 | use std::cell::Cell; |
2 | use std::mem; |
3 | |
4 | use crossbeam_utils::CachePadded; |
5 | |
6 | #[test] |
7 | fn default() { |
8 | let x: CachePadded<u64> = Default::default(); |
9 | assert_eq!(*x, 0); |
10 | } |
11 | |
12 | #[test] |
13 | fn store_u64() { |
14 | let x: CachePadded<u64> = CachePadded::new(17); |
15 | assert_eq!(*x, 17); |
16 | } |
17 | |
18 | #[test] |
19 | fn store_pair() { |
20 | let x: CachePadded<(u64, u64)> = CachePadded::new((17, 37)); |
21 | assert_eq!(x.0, 17); |
22 | assert_eq!(x.1, 37); |
23 | } |
24 | |
25 | #[test] |
26 | fn distance() { |
27 | let arr = [CachePadded::new(17u8), CachePadded::new(37u8)]; |
28 | let a = &*arr[0] as *const u8; |
29 | let b = &*arr[1] as *const u8; |
30 | let align = mem::align_of::<CachePadded<()>>(); |
31 | assert!(align >= 32); |
32 | assert_eq!(unsafe { a.add(align) }, b); |
33 | } |
34 | |
35 | #[test] |
36 | fn different_sizes() { |
37 | CachePadded::new(17u8); |
38 | CachePadded::new(17u16); |
39 | CachePadded::new(17u32); |
40 | CachePadded::new([17u64; 0]); |
41 | CachePadded::new([17u64; 1]); |
42 | CachePadded::new([17u64; 2]); |
43 | CachePadded::new([17u64; 3]); |
44 | CachePadded::new([17u64; 4]); |
45 | CachePadded::new([17u64; 5]); |
46 | CachePadded::new([17u64; 6]); |
47 | CachePadded::new([17u64; 7]); |
48 | CachePadded::new([17u64; 8]); |
49 | } |
50 | |
51 | #[test] |
52 | fn large() { |
53 | let a = [17u64; 9]; |
54 | let b = CachePadded::new(a); |
55 | assert!(mem::size_of_val(&a) <= mem::size_of_val(&b)); |
56 | } |
57 | |
58 | #[test] |
59 | fn debug() { |
60 | assert_eq!( |
61 | format!("{:?}" , CachePadded::new(17u64)), |
62 | "CachePadded { value: 17 }" |
63 | ); |
64 | } |
65 | |
66 | #[test] |
67 | fn drops() { |
68 | let count = Cell::new(0); |
69 | |
70 | struct Foo<'a>(&'a Cell<usize>); |
71 | |
72 | impl<'a> Drop for Foo<'a> { |
73 | fn drop(&mut self) { |
74 | self.0.set(self.0.get() + 1); |
75 | } |
76 | } |
77 | |
78 | let a = CachePadded::new(Foo(&count)); |
79 | let b = CachePadded::new(Foo(&count)); |
80 | |
81 | assert_eq!(count.get(), 0); |
82 | drop(a); |
83 | assert_eq!(count.get(), 1); |
84 | drop(b); |
85 | assert_eq!(count.get(), 2); |
86 | } |
87 | |
88 | #[allow (clippy::clone_on_copy)] // This is intentional. |
89 | #[test] |
90 | fn clone() { |
91 | let a = CachePadded::new(17); |
92 | let b = a.clone(); |
93 | assert_eq!(*a, *b); |
94 | } |
95 | |
96 | #[test] |
97 | fn runs_custom_clone() { |
98 | let count = Cell::new(0); |
99 | |
100 | struct Foo<'a>(&'a Cell<usize>); |
101 | |
102 | impl<'a> Clone for Foo<'a> { |
103 | fn clone(&self) -> Foo<'a> { |
104 | self.0.set(self.0.get() + 1); |
105 | Foo::<'a>(self.0) |
106 | } |
107 | } |
108 | |
109 | let a = CachePadded::new(Foo(&count)); |
110 | let _ = a.clone(); |
111 | |
112 | assert_eq!(count.get(), 1); |
113 | } |
114 | |