@@ -27,7 +27,6 @@ use std::boxed::FnBox;
2727use std:: cell:: UnsafeCell ;
2828use std:: io;
2929use std:: mem;
30- use std:: ptr;
3130use std:: sync:: Arc ;
3231use std:: sync:: mpsc:: { self , Sender , Receiver } ;
3332use std:: thread:: { self , Builder } ;
@@ -41,7 +40,7 @@ use coroutine::{self, Coroutine, State, Handle, SendableCoroutinePtr};
4140use options:: Options ;
4241use scheduler:: Scheduler ;
4342
44- thread_local ! ( static PROCESSOR : UnsafeCell <* mut Processor > = UnsafeCell :: new( ptr :: null_mut ( ) ) ) ;
43+ thread_local ! ( static PROCESSOR : UnsafeCell <Option < Processor >> = UnsafeCell :: new( None ) ) ;
4544
4645#[ derive( Debug ) ]
4746pub struct ForceUnwind ;
@@ -100,21 +99,27 @@ impl Processor {
10099 }
101100 }
102101
102+ fn set_and_get_tls ( p : Processor ) -> & ' static mut Processor {
103+ PROCESSOR . with ( move |proc_opt| unsafe {
104+ * proc_opt. get ( ) = Some ( p) ;
105+ ( * proc_opt. get ( ) ) . as_mut ( ) . unwrap ( )
106+ } )
107+ }
108+
103109 #[ inline]
104110 pub fn run_with_neighbors ( processor_id : usize ,
105111 sched : Arc < Scheduler > ,
106112 neigh : Vec < Stealer < SendableCoroutinePtr > > )
107113 -> ( thread:: JoinHandle < ( ) > ,
108114 Sender < ProcMessage > ,
109115 Stealer < SendableCoroutinePtr > ) {
110- let mut p = Processor :: new_with_neighbors ( processor_id, sched, neigh) ;
111- let ( msg, st) = ( p. handle ( ) , p. stealer ( ) ) ;
116+ let p = Processor :: new_with_neighbors ( processor_id, sched, neigh) ;
117+ let msg = p. handle ( ) ;
118+ let st = p. stealer ( ) ;
112119 let hdl = Builder :: new ( )
113120 . name ( format ! ( "Processor #{}" , processor_id) )
114121 . spawn ( move || {
115- // Set to thread local
116- PROCESSOR . with ( |proc_ptr| unsafe { * proc_ptr. get ( ) = & mut p } ) ;
117-
122+ let mut p = Processor :: set_and_get_tls ( p) ;
118123 if let Err ( err) = p. schedule ( ) {
119124 panic ! ( "Processor::schedule return Err: {:?}" , err) ;
120125 }
@@ -135,15 +140,11 @@ impl Processor {
135140 where M : FnOnce ( ) -> T + Send + ' static ,
136141 T : Send + ' static
137142 {
138- let mut p = Processor :: new_with_neighbors ( processor_id, sched, Vec :: new ( ) ) ;
143+ let p = Processor :: new_with_neighbors ( processor_id, sched, Vec :: new ( ) ) ;
139144 let ( msg, st) = ( p. handle ( ) , p. stealer ( ) ) ;
140145 let ( tx, rx) = :: std:: sync:: mpsc:: channel ( ) ;
141146 let hdl = Builder :: new ( ) . name ( format ! ( "Processor #{}" , processor_id) ) . spawn ( move || {
142- // Set to thread local
143- PROCESSOR . with ( |proc_ptr| unsafe {
144- * proc_ptr. get ( ) = & mut p
145- } ) ;
146-
147+ let mut p = Processor :: set_and_get_tls ( p) ;
147148 let wrapper = move || {
148149 let ret = unsafe { :: try ( move || f ( ) ) } ;
149150
@@ -164,16 +165,22 @@ impl Processor {
164165 & * self . scheduler
165166 }
166167
168+ /// Get the thread local processor
169+ #[ inline]
170+ pub fn current ( ) -> Option < & ' static mut Processor > {
171+ PROCESSOR . with ( |proc_opt| unsafe { ( * proc_opt. get ( ) ) . as_mut ( ) } )
172+ }
173+
167174 #[ inline]
168175 // Get the current running coroutine
169- pub unsafe fn running ( & mut self ) -> Option < * mut Coroutine > {
176+ pub fn running ( & mut self ) -> Option < * mut Coroutine > {
170177 self . cur_running
171178 }
172179
173- /// Get the thread local processor
174180 #[ inline]
175- pub fn current ( ) -> & ' static mut Processor {
176- PROCESSOR . with ( |p| unsafe { & mut * * p. get ( ) } )
181+ // Get the current running coroutine
182+ pub fn current_running ( ) -> Option < * mut Coroutine > {
183+ Processor :: current ( ) . and_then ( Processor :: running)
177184 }
178185
179186 #[ inline]
@@ -188,7 +195,7 @@ impl Processor {
188195
189196 #[ inline]
190197 // Call by scheduler
191- pub unsafe fn ready ( & mut self , coro_ptr : * mut Coroutine ) {
198+ pub fn ready ( & mut self , coro_ptr : * mut Coroutine ) {
192199 self . has_ready_tasks = true ;
193200 self . queue_worker . push ( SendableCoroutinePtr ( coro_ptr) ) ;
194201 }
@@ -211,7 +218,7 @@ impl Processor {
211218 }
212219
213220 #[ inline]
214- unsafe fn run_with_all_local_tasks ( & mut self , coro_ptr : * mut Coroutine ) {
221+ fn run_with_all_local_tasks ( & mut self , coro_ptr : * mut Coroutine ) {
215222 let mut hdl = coro_ptr;
216223 loop {
217224 let is_suspended = match self . resume ( hdl) {
@@ -252,9 +259,7 @@ impl Processor {
252259 ' outerloop: loop {
253260 // 1. Run all tasks in local queue
254261 if let Some ( hdl) = self . queue_worker . pop ( ) {
255- unsafe {
256- self . run_with_all_local_tasks ( hdl. 0 ) ;
257- }
262+ self . run_with_all_local_tasks ( hdl. 0 ) ;
258263 } else {
259264 self . has_ready_tasks = false ;
260265 }
@@ -266,10 +271,10 @@ impl Processor {
266271 ProcMessage :: Shutdown => {
267272 self . destroy_all_coroutines ( ) ;
268273 }
269- ProcMessage :: Ready ( SendableCoroutinePtr ( ptr) ) => unsafe {
274+ ProcMessage :: Ready ( SendableCoroutinePtr ( ptr) ) => {
270275 self . ready ( ptr) ;
271276 self . has_ready_tasks = true ;
272- } ,
277+ }
273278 }
274279 }
275280
@@ -288,9 +293,7 @@ impl Processor {
288293 for idx in ( 0 ..self . neighbor_stealers . len ( ) ) . map ( |x| ( x + rand_idx) % total_stealers) {
289294 if let Stolen :: Data ( SendableCoroutinePtr ( hdl) ) = self . neighbor_stealers [ idx]
290295 . steal ( ) {
291- unsafe {
292- self . run_with_all_local_tasks ( hdl) ;
293- }
296+ self . run_with_all_local_tasks ( hdl) ;
294297 continue ' outerloop;
295298 }
296299 }
@@ -312,9 +315,7 @@ impl Processor {
312315
313316 // 1. Drain the work queue.
314317 if let Some ( hdl) = self . queue_worker . pop ( ) {
315- unsafe {
316- self . run_with_all_local_tasks ( hdl. 0 ) ;
317- }
318+ self . run_with_all_local_tasks ( hdl. 0 ) ;
318319 }
319320 }
320321
0 commit comments