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> {
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
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`.
7477 pub 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.
8386 pub 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