33use std:: marker;
44use std:: ops:: Deref ;
55use std:: sync:: atomic:: Ordering :: SeqCst ;
6- use std:: sync:: atomic:: { AtomicBool , AtomicUsize } ;
6+ use std:: sync:: atomic:: { AtomicBool , AtomicPtr } ;
77use std:: sync:: Arc ;
88
99pub struct ArcList < T > {
10- list : AtomicUsize ,
10+ list : AtomicPtr < Node < T > > ,
1111 _marker : marker:: PhantomData < T > ,
1212}
1313
1414impl < T > ArcList < T > {
1515 pub fn new ( ) -> ArcList < T > {
1616 ArcList {
17- list : AtomicUsize :: new ( 0 ) ,
17+ list : AtomicPtr :: new ( Node :: EMPTY ) ,
1818 _marker : marker:: PhantomData ,
1919 }
2020 }
@@ -31,10 +31,10 @@ impl<T> ArcList<T> {
3131 return Ok ( ( ) ) ;
3232 }
3333 let mut head = self . list . load ( SeqCst ) ;
34- let node = Arc :: into_raw ( data. clone ( ) ) as usize ;
34+ let node = Arc :: into_raw ( data. clone ( ) ) as * mut Node < T > ;
3535 loop {
3636 // If we've been sealed off, abort and return an error
37- if head == 1 {
37+ if head == Node :: sealed ( ) {
3838 unsafe {
3939 drop ( Arc :: from_raw ( node as * mut Node < T > ) ) ;
4040 }
@@ -55,16 +55,16 @@ impl<T> ArcList<T> {
5555 pub fn take ( & self ) -> ArcList < T > {
5656 let mut list = self . list . load ( SeqCst ) ;
5757 loop {
58- if list == 1 {
58+ if list == Node :: sealed ( ) {
5959 break ;
6060 }
61- match self . list . compare_exchange ( list, 0 , SeqCst , SeqCst ) {
61+ match self . list . compare_exchange ( list, Node :: EMPTY , SeqCst , SeqCst ) {
6262 Ok ( _) => break ,
6363 Err ( l) => list = l,
6464 }
6565 }
6666 ArcList {
67- list : AtomicUsize :: new ( list) ,
67+ list : AtomicPtr :: new ( list) ,
6868 _marker : marker:: PhantomData ,
6969 }
7070 }
@@ -73,7 +73,7 @@ impl<T> ArcList<T> {
7373 /// `push`.
7474 pub fn take_and_seal ( & self ) -> ArcList < T > {
7575 ArcList {
76- list : AtomicUsize :: new ( self . list . swap ( 1 , SeqCst ) ) ,
76+ list : AtomicPtr :: new ( self . list . swap ( Node :: sealed ( ) , SeqCst ) ) ,
7777 _marker : marker:: PhantomData ,
7878 }
7979 }
@@ -82,7 +82,7 @@ impl<T> ArcList<T> {
8282 /// empty list.
8383 pub fn pop ( & mut self ) -> Option < Arc < Node < T > > > {
8484 let head = * self . list . get_mut ( ) ;
85- if head == 0 || head == 1 {
85+ if head == Node :: EMPTY || head == Node :: sealed ( ) {
8686 return None ;
8787 }
8888 let head = unsafe { Arc :: from_raw ( head as * const Node < T > ) } ;
@@ -103,15 +103,21 @@ impl<T> Drop for ArcList<T> {
103103}
104104
105105pub struct Node < T > {
106- next : AtomicUsize ,
106+ next : AtomicPtr < Node < T > > ,
107107 enqueued : AtomicBool ,
108108 data : T ,
109109}
110110
111111impl < T > Node < T > {
112+ const EMPTY : * mut Node < T > = std:: ptr:: null_mut ( ) ;
113+
114+ const fn sealed ( ) -> * mut Node < T > {
115+ std:: ptr:: null_mut :: < Node < T > > ( ) . wrapping_add ( 1 )
116+ }
117+
112118 pub fn new ( data : T ) -> Node < T > {
113119 Node {
114- next : AtomicUsize :: new ( 0 ) ,
120+ next : AtomicPtr :: new ( Node :: EMPTY ) ,
115121 enqueued : AtomicBool :: new ( false ) ,
116122 data,
117123 }
0 commit comments