1
- use core:: {
2
- marker :: PhantomData ,
3
- num :: { NonZeroU32 , NonZeroU64 } ,
4
- ptr :: NonNull ,
5
- sync :: atomic:: { AtomicU64 , Ordering } ,
6
- } ;
1
+ use core:: { marker :: PhantomData , ptr :: NonNull , sync :: atomic :: Ordering } ;
2
+
3
+ # [ cfg ( not ( feature = "portable-atomic" ) ) ]
4
+ use core :: sync :: atomic ;
5
+ # [ cfg ( feature = "portable- atomic" ) ]
6
+ use portable_atomic as atomic ;
7
7
8
8
use super :: { Node , Stack } ;
9
9
10
+ #[ cfg( target_pointer_width = "32" ) ]
11
+ mod types {
12
+ use super :: atomic;
13
+
14
+ pub type Inner = u64 ;
15
+ pub type InnerAtomic = atomic:: AtomicU64 ;
16
+ pub type InnerNonZero = core:: num:: NonZeroU64 ;
17
+
18
+ pub type Tag = core:: num:: NonZeroU32 ;
19
+ pub type Address = u32 ;
20
+ }
21
+
22
+ #[ cfg( target_pointer_width = "64" ) ]
23
+ mod types {
24
+ use super :: atomic;
25
+
26
+ pub type Inner = u128 ;
27
+ pub type InnerAtomic = atomic:: AtomicU128 ;
28
+ pub type InnerNonZero = core:: num:: NonZeroU128 ;
29
+
30
+ pub type Tag = core:: num:: NonZeroU64 ;
31
+ pub type Address = u64 ;
32
+ }
33
+
34
+ use types:: * ;
35
+
10
36
pub struct AtomicPtr < N >
11
37
where
12
38
N : Node ,
13
39
{
14
- inner : AtomicU64 ,
40
+ inner : InnerAtomic ,
15
41
_marker : PhantomData < * mut N > ,
16
42
}
17
43
18
44
impl < N > AtomicPtr < N >
19
45
where
20
46
N : Node ,
21
47
{
48
+ #[ inline]
22
49
pub const fn null ( ) -> Self {
23
50
Self {
24
- inner : AtomicU64 :: new ( 0 ) ,
51
+ inner : InnerAtomic :: new ( 0 ) ,
25
52
_marker : PhantomData ,
26
53
}
27
54
}
@@ -35,37 +62,35 @@ where
35
62
) -> Result < ( ) , Option < NonNullPtr < N > > > {
36
63
self . inner
37
64
. compare_exchange_weak (
38
- current
39
- . map ( |pointer| pointer. into_u64 ( ) )
40
- . unwrap_or_default ( ) ,
41
- new. map ( |pointer| pointer. into_u64 ( ) ) . unwrap_or_default ( ) ,
65
+ current. map ( NonNullPtr :: into_inner) . unwrap_or_default ( ) ,
66
+ new. map ( NonNullPtr :: into_inner) . unwrap_or_default ( ) ,
42
67
success,
43
68
failure,
44
69
)
45
70
. map ( drop)
46
- . map_err ( NonNullPtr :: from_u64 )
71
+ . map_err ( NonNullPtr :: from_inner )
47
72
}
48
73
74
+ #[ inline]
49
75
fn load ( & self , order : Ordering ) -> Option < NonNullPtr < N > > {
50
- NonZeroU64 :: new ( self . inner . load ( order) ) . map ( |inner| NonNullPtr {
76
+ InnerNonZero :: new ( self . inner . load ( order) ) . map ( |inner| NonNullPtr {
51
77
inner,
52
78
_marker : PhantomData ,
53
79
} )
54
80
}
55
81
82
+ #[ inline]
56
83
fn store ( & self , value : Option < NonNullPtr < N > > , order : Ordering ) {
57
- self . inner . store (
58
- value. map ( |pointer| pointer. into_u64 ( ) ) . unwrap_or_default ( ) ,
59
- order,
60
- )
84
+ self . inner
85
+ . store ( value. map ( NonNullPtr :: into_inner) . unwrap_or_default ( ) , order)
61
86
}
62
87
}
63
88
64
89
pub struct NonNullPtr < N >
65
90
where
66
91
N : Node ,
67
92
{
68
- inner : NonZeroU64 ,
93
+ inner : InnerNonZero ,
69
94
_marker : PhantomData < * mut N > ,
70
95
}
71
96
@@ -84,65 +109,66 @@ impl<N> NonNullPtr<N>
84
109
where
85
110
N : Node ,
86
111
{
112
+ #[ inline]
87
113
pub fn as_ptr ( & self ) -> * mut N {
88
114
self . inner . get ( ) as * mut N
89
115
}
90
116
117
+ #[ inline]
91
118
pub fn from_static_mut_ref ( ref_ : & ' static mut N ) -> NonNullPtr < N > {
92
119
let non_null = NonNull :: from ( ref_) ;
93
120
Self :: from_non_null ( non_null)
94
121
}
95
122
96
123
fn from_non_null ( ptr : NonNull < N > ) -> Self {
97
- let address = ptr. as_ptr ( ) as u32 ;
124
+ let address = ptr. as_ptr ( ) as Address ;
98
125
let tag = initial_tag ( ) . get ( ) ;
99
126
100
- let value = ( u64 :: from ( tag) << 32 ) | u64 :: from ( address) ;
127
+ let value = ( Inner :: from ( tag) << Address :: BITS ) | Inner :: from ( address) ;
101
128
102
129
Self {
103
- inner : unsafe { NonZeroU64 :: new_unchecked ( value) } ,
130
+ inner : unsafe { InnerNonZero :: new_unchecked ( value) } ,
104
131
_marker : PhantomData ,
105
132
}
106
133
}
107
134
108
- fn from_u64 ( value : u64 ) -> Option < Self > {
109
- NonZeroU64 :: new ( value) . map ( |inner| Self {
135
+ #[ inline]
136
+ fn from_inner ( value : Inner ) -> Option < Self > {
137
+ InnerNonZero :: new ( value) . map ( |inner| Self {
110
138
inner,
111
139
_marker : PhantomData ,
112
140
} )
113
141
}
114
142
143
+ #[ inline]
115
144
fn non_null ( & self ) -> NonNull < N > {
116
- unsafe { NonNull :: new_unchecked ( self . inner . get ( ) as * mut N ) }
145
+ unsafe { NonNull :: new_unchecked ( self . as_ptr ( ) ) }
117
146
}
118
147
119
- fn tag ( & self ) -> NonZeroU32 {
120
- unsafe { NonZeroU32 :: new_unchecked ( ( self . inner . get ( ) >> 32 ) as u32 ) }
148
+ #[ inline]
149
+ fn into_inner ( self ) -> Inner {
150
+ self . inner . get ( )
121
151
}
122
152
123
- fn into_u64 ( self ) -> u64 {
124
- self . inner . get ( )
153
+ #[ inline]
154
+ fn tag ( & self ) -> Tag {
155
+ unsafe { Tag :: new_unchecked ( ( self . inner . get ( ) >> Address :: BITS ) as Address ) }
125
156
}
126
157
127
158
fn increase_tag ( & mut self ) {
128
- let address = self . as_ptr ( ) as u32 ;
159
+ let address = self . as_ptr ( ) as Address ;
129
160
130
- let new_tag = self
131
- . tag ( )
132
- . get ( )
133
- . checked_add ( 1 )
134
- . map ( |val| unsafe { NonZeroU32 :: new_unchecked ( val) } )
135
- . unwrap_or_else ( initial_tag)
136
- . get ( ) ;
161
+ let new_tag = self . tag ( ) . checked_add ( 1 ) . unwrap_or_else ( initial_tag) . get ( ) ;
137
162
138
- let value = ( u64 :: from ( new_tag) << 32 ) | u64 :: from ( address) ;
163
+ let value = ( Inner :: from ( new_tag) << Address :: BITS ) | Inner :: from ( address) ;
139
164
140
- self . inner = unsafe { NonZeroU64 :: new_unchecked ( value) } ;
165
+ self . inner = unsafe { InnerNonZero :: new_unchecked ( value) } ;
141
166
}
142
167
}
143
168
144
- fn initial_tag ( ) -> NonZeroU32 {
145
- unsafe { NonZeroU32 :: new_unchecked ( 1 ) }
169
+ #[ inline]
170
+ const fn initial_tag ( ) -> Tag {
171
+ Tag :: MIN
146
172
}
147
173
148
174
pub unsafe fn push < N > ( stack : & Stack < N > , new_top : NonNullPtr < N > )
0 commit comments