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,19 @@ impl<T> ArcList<T> {
5555pub  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 
62+                 . list 
63+                 . compare_exchange ( list,  Node :: EMPTY ,  SeqCst ,  SeqCst ) 
64+             { 
6265                Ok ( _)  => break , 
6366                Err ( l)  => list = l, 
6467            } 
6568        } 
6669        ArcList  { 
67-             list :  AtomicUsize :: new ( list) , 
70+             list :  AtomicPtr :: new ( list) , 
6871            _marker :  marker:: PhantomData , 
6972        } 
7073    } 
@@ -73,7 +76,7 @@ impl<T> ArcList<T> {
7376/// `push`. 
7477pub  fn  take_and_seal ( & self )  -> ArcList < T >  { 
7578        ArcList  { 
76-             list :  AtomicUsize :: new ( self . list . swap ( 1 ,  SeqCst ) ) , 
79+             list :  AtomicPtr :: new ( self . list . swap ( Node :: SEALED ,  SeqCst ) ) , 
7780            _marker :  marker:: PhantomData , 
7881        } 
7982    } 
@@ -82,7 +85,7 @@ impl<T> ArcList<T> {
8285/// empty list. 
8386pub  fn  pop ( & mut  self )  -> Option < Arc < Node < T > > >  { 
8487        let  head = * self . list . get_mut ( ) ; 
85-         if  head == 0  || head == 1  { 
88+         if  head == Node :: EMPTY  || head == Node :: SEALED  { 
8689            return  None ; 
8790        } 
8891        let  head = unsafe  {  Arc :: from_raw ( head as  * const  Node < T > )  } ; 
@@ -103,15 +106,19 @@ impl<T> Drop for ArcList<T> {
103106} 
104107
105108pub  struct  Node < T >  { 
106-     next :  AtomicUsize , 
109+     next :  AtomicPtr < Node < T > > , 
107110    enqueued :  AtomicBool , 
108111    data :  T , 
109112} 
110113
111114impl < T >  Node < T >  { 
115+     const  EMPTY :  * mut  Node < T >  = std:: ptr:: null_mut ( ) ; 
116+ 
117+     const  SEALED :  * mut  Node < T >  = std:: ptr:: null_mut :: < Node < T > > ( ) . wrapping_add ( 1 ) ; 
118+ 
112119    pub  fn  new ( data :  T )  -> Node < T >  { 
113120        Node  { 
114-             next :  AtomicUsize :: new ( 0 ) , 
121+             next :  AtomicPtr :: new ( Node :: EMPTY ) , 
115122            enqueued :  AtomicBool :: new ( false ) , 
116123            data, 
117124        } 
0 commit comments