@@ -251,6 +251,107 @@ impl PartialEq for TaskSignature {
251251
252252impl Eq for TaskSignature { }
253253
254+ pub ( crate ) type Loc = & ' static Location < ' static > ;
255+
256+ #[ derive( Debug , Clone , PartialEq , Eq , Hash ) ]
257+ pub ( crate ) enum Event < ' a > {
258+ AtomicRead ( & ' a ResourceSignature , Loc ) ,
259+ AtomicWrite ( & ' a ResourceSignature , Loc ) ,
260+ AtomicReadWrite ( & ' a ResourceSignature , Loc ) ,
261+ BatchSemaphoreAcq ( & ' a ResourceSignature , Loc ) ,
262+ BatchSemaphoreRel ( & ' a ResourceSignature , Loc ) ,
263+ BarrierWait ( & ' a ResourceSignature , Loc ) ,
264+ CondvarWait ( & ' a ResourceSignature , Loc ) ,
265+ CondvarNotify ( Loc ) ,
266+ Park ( Loc ) ,
267+ Unpark ( & ' a TaskSignature , Loc ) ,
268+ ChannelSend ( & ' a ResourceSignature , Loc ) ,
269+ ChannelRecv ( & ' a ResourceSignature , Loc ) ,
270+ Spawn ( & ' a TaskSignature ) ,
271+ Yield ( Loc ) ,
272+ Sleep ( Loc ) ,
273+ Exit ,
274+ Join ( & ' a TaskSignature , Loc ) ,
275+ Unknown ,
276+ }
277+
278+ impl < ' a > Event < ' a > {
279+ #[ track_caller]
280+ pub ( crate ) fn atomic_read ( sig : & ' a ResourceSignature ) -> Self {
281+ Self :: AtomicRead ( sig, Location :: caller ( ) )
282+ }
283+
284+ #[ track_caller]
285+ pub ( crate ) fn atomic_write ( sig : & ' a ResourceSignature ) -> Self {
286+ Self :: AtomicWrite ( sig, Location :: caller ( ) )
287+ }
288+
289+ #[ track_caller]
290+ pub ( crate ) fn atomic_read_write ( sig : & ' a ResourceSignature ) -> Self {
291+ Self :: AtomicReadWrite ( sig, Location :: caller ( ) )
292+ }
293+
294+ #[ track_caller]
295+ pub ( crate ) fn batch_semaphore_acq ( sig : & ' a ResourceSignature ) -> Self {
296+ Self :: BatchSemaphoreAcq ( sig, Location :: caller ( ) )
297+ }
298+
299+ #[ track_caller]
300+ pub ( crate ) fn batch_semaphore_rel ( sig : & ' a ResourceSignature ) -> Self {
301+ Self :: BatchSemaphoreRel ( sig, Location :: caller ( ) )
302+ }
303+
304+ #[ track_caller]
305+ pub ( crate ) fn barrier_wait ( sig : & ' a ResourceSignature ) -> Self {
306+ Self :: BarrierWait ( sig, Location :: caller ( ) )
307+ }
308+
309+ #[ track_caller]
310+ pub ( crate ) fn condvar_wait ( sig : & ' a ResourceSignature ) -> Self {
311+ Self :: CondvarWait ( sig, Location :: caller ( ) )
312+ }
313+
314+ #[ track_caller]
315+ pub ( crate ) fn condvar_notify ( ) -> Self {
316+ Self :: CondvarNotify ( Location :: caller ( ) )
317+ }
318+
319+ #[ track_caller]
320+ pub ( crate ) fn park ( ) -> Self {
321+ Self :: Park ( Location :: caller ( ) )
322+ }
323+
324+ #[ track_caller]
325+ pub ( crate ) fn unpark ( sig : & ' a TaskSignature ) -> Self {
326+ Self :: Unpark ( sig, Location :: caller ( ) )
327+ }
328+
329+ #[ track_caller]
330+ pub ( crate ) fn channel_send ( sig : & ' a ResourceSignature ) -> Self {
331+ Self :: ChannelSend ( sig, Location :: caller ( ) )
332+ }
333+
334+ #[ track_caller]
335+ pub ( crate ) fn channel_recv ( sig : & ' a ResourceSignature ) -> Self {
336+ Self :: ChannelRecv ( sig, Location :: caller ( ) )
337+ }
338+
339+ #[ track_caller]
340+ pub ( crate ) fn yield_now ( ) -> Self {
341+ Self :: Yield ( Location :: caller ( ) )
342+ }
343+
344+ #[ track_caller]
345+ pub ( crate ) fn sleep ( ) -> Self {
346+ Self :: Sleep ( Location :: caller ( ) )
347+ }
348+
349+ #[ track_caller]
350+ pub ( crate ) fn join ( sig : & ' a TaskSignature ) -> Self {
351+ Self :: Join ( sig, Location :: caller ( ) )
352+ }
353+ }
354+
254355/// A `Task` represents a user-level unit of concurrency. Each task has an `id` that is unique within
255356/// the execution, and a `state` reflecting whether the task is runnable (enabled) or not.
256357#[ derive( Debug ) ]
@@ -271,6 +372,8 @@ pub struct Task {
271372 // Remember whether the waker was invoked while we were running
272373 woken : bool ,
273374
375+ next_event : Event < ' static > ,
376+
274377 name : Option < String > ,
275378
276379 local_storage : StorageMap ,
@@ -342,6 +445,7 @@ impl Task {
342445 waiter : None ,
343446 waker,
344447 woken : false ,
448+ next_event : Event :: Unknown ,
345449 detached : false ,
346450 park_state : ParkState :: default ( ) ,
347451 name,
@@ -416,7 +520,7 @@ impl Task {
416520 let cx = & mut Context :: from_waker ( & waker) ;
417521 while future. as_mut ( ) . poll ( cx) . is_pending ( ) {
418522 ExecutionState :: with ( |state| state. current_mut ( ) . sleep_unless_woken ( ) ) ;
419- thread:: switch_task ( ) ;
523+ thread:: switch_keep_event ( ) ;
420524 }
421525 } ) ,
422526 stack_size,
@@ -651,6 +755,19 @@ impl Task {
651755 TASK_ID_TO_TAGS . with ( |cell| cell. borrow_mut ( ) . insert ( self . id ( ) , tag. clone ( ) ) ) ;
652756 self . tag . replace ( tag)
653757 }
758+
759+ /// Get the next_event with a downcast lifetime tied to self.
760+ pub ( crate ) fn next_event ( & self ) -> & Event < ' _ > {
761+ unsafe { std:: mem:: transmute ( & self . next_event ) }
762+ }
763+
764+ pub ( crate ) unsafe fn set_next_event ( & mut self , event : Event < ' _ > ) {
765+ self . next_event = unsafe { std:: mem:: transmute :: < Event < ' _ > , Event < ' static > > ( event) } ;
766+ }
767+
768+ pub ( crate ) fn unset_next_event ( & mut self ) {
769+ self . next_event = Event :: Unknown ;
770+ }
654771}
655772
656773#[ derive( PartialEq , Eq , Clone , Copy , Debug ) ]
0 commit comments