17
17
#ifndef SWIFT_ABI_TASK_BACKDEPLOY56_H
18
18
#define SWIFT_ABI_TASK_BACKDEPLOY56_H
19
19
20
+ #include " Concurrency/TaskLocal.h"
20
21
#include " Executor.h"
21
22
#include " swift/ABI/HeapObject.h"
22
23
#include " swift/ABI/Metadata.h"
26
27
#include " VoucherShims.h"
27
28
#include " swift/Basic/STLExtras.h"
28
29
#include < bitset>
29
- #include < queue>
30
+ #include < queue> // TODO: remove and replace with our own mpsc
30
31
31
32
namespace swift {
32
33
class AsyncTask ;
@@ -275,13 +276,6 @@ class AsyncTask : public Job {
275
276
void setTaskId ();
276
277
uint64_t getTaskId ();
277
278
278
- // / Get the task's resume function, for logging purposes only. This will
279
- // / attempt to see through the various adapters that are sometimes used, and
280
- // / failing that will return ResumeTask. The returned function pointer may
281
- // / have a different signature than ResumeTask, and it's only for identifying
282
- // / code associated with the task.
283
- const void *getResumeFunctionForLogging ();
284
-
285
279
// / Given that we've already fully established the job context
286
280
// / in the current thread, start running this task. To establish
287
281
// / the job context correctly, call swift_job_run or
@@ -313,34 +307,44 @@ class AsyncTask : public Job {
313
307
// /
314
308
// / Generally this should be done immediately after updating
315
309
// / ActiveTask.
310
+ __attribute__ ((visibility(" hidden" )))
316
311
void flagAsRunning();
312
+ __attribute__ ((visibility(" hidden" )))
317
313
void flagAsRunning_slow();
318
314
319
- // / Flag that this task is now suspended.
315
+ // / Flag that this task is now suspended. This can update the
316
+ // / priority stored in the job flags if the priority hsa been
317
+ // / escalated. Generally this should be done immediately after
318
+ // / clearing ActiveTask and immediately before enqueuing the task
319
+ // / somewhere. TODO: record where the task is enqueued if
320
+ // / possible.
321
+ __attribute__ ((visibility(" hidden" )))
320
322
void flagAsSuspended();
323
+ __attribute__ ((visibility(" hidden" )))
321
324
void flagAsSuspended_slow();
322
325
323
- // / Flag that the task is to be enqueued on the provided executor and actually
324
- // / enqueue it
325
- void flagAsAndEnqueueOnExecutor (ExecutorRef newExecutor);
326
-
327
326
// / Flag that this task is now completed. This normally does not do anything
328
327
// / but can be used to locally insert logging.
328
+ __attribute__ ((visibility(" hidden" )))
329
329
void flagAsCompleted();
330
330
331
331
// / Check whether this task has been cancelled.
332
332
// / Checking this is, of course, inherently race-prone on its own.
333
+ __attribute__ ((visibility(" hidden" )))
333
334
bool isCancelled() const ;
334
335
335
336
// ==== Task Local Values ----------------------------------------------------
336
337
338
+ __attribute__ ((visibility(" hidden" )))
337
339
void localValuePush(const HeapObject *key,
338
340
/* +1 */ OpaqueValue *value,
339
341
const Metadata *valueType);
340
342
343
+ __attribute__ ((visibility(" hidden" )))
341
344
OpaqueValue *localValueGet(const HeapObject *key);
342
345
343
346
// / Returns true if storage has still more bindings.
347
+ __attribute__ ((visibility(" hidden" )))
344
348
bool localValuePop();
345
349
346
350
// ==== Child Fragment -------------------------------------------------------
@@ -566,8 +570,9 @@ class AsyncTask : public Job {
566
570
// / \c Executing, then \c waitingTask has been added to the
567
571
// / wait queue and will be scheduled when the future completes. Otherwise,
568
572
// / the future has completed and can be queried.
569
- // / The waiting task's async context will be initialized with the parameters if
573
+ // / The waiting task's async context will be intialized with the parameters if
570
574
// / the current's task state is executing.
575
+ __attribute__ ((visibility(" hidden" )))
571
576
FutureFragment::Status waitFuture(AsyncTask *waitingTask,
572
577
AsyncContext *waitingTaskContext,
573
578
TaskContinuationFunction *resumeFn,
@@ -614,6 +619,65 @@ inline void Job::runInFullyEstablishedContext() {
614
619
615
620
// ==== ------------------------------------------------------------------------
616
621
622
+ // / The Swift5.6 AsyncContextKind for the AsyncContext.
623
+ // / Note that these were removed in Swift5.7
624
+ // / (aca744b21165a20655502b563a6fa54c2c83efdf).
625
+ // / Kinds of async context.
626
+ enum class AsyncContextKind {
627
+ // / An ordinary asynchronous function.
628
+ Ordinary = 0 ,
629
+
630
+ // / A context which can yield to its caller.
631
+ Yielding = 1 ,
632
+
633
+ // / A continuation context.
634
+ Continuation = 2 ,
635
+
636
+ // Other kinds are reserved for interesting special
637
+ // intermediate contexts.
638
+
639
+ // Kinds >= 192 are private to the implementation.
640
+ First_Reserved = 192
641
+ };
642
+
643
+
644
+ // / The Swift5.6 AsyncContextFlags for the AsyncContext.
645
+ // / Note that these were removed in Swift5.7
646
+ // / (aca744b21165a20655502b563a6fa54c2c83efdf).
647
+ // / Flags for async contexts.
648
+ class AsyncContextFlags : public FlagSet <uint32_t > {
649
+ public:
650
+ enum {
651
+ Kind = 0 ,
652
+ Kind_width = 8 ,
653
+
654
+ CanThrow = 8 ,
655
+
656
+ // Kind-specific flags should grow down from 31.
657
+
658
+ Continuation_IsExecutorSwitchForced = 31 ,
659
+ };
660
+
661
+ explicit AsyncContextFlags (uint32_t bits) : FlagSet(bits) {}
662
+ constexpr AsyncContextFlags () {}
663
+ AsyncContextFlags (AsyncContextKind kind) {
664
+ setKind (kind);
665
+ }
666
+
667
+ // / The kind of context this represents.
668
+ FLAGSET_DEFINE_FIELD_ACCESSORS (Kind, Kind_width, AsyncContextKind,
669
+ getKind, setKind)
670
+
671
+ // / Whether this context is permitted to throw.
672
+ FLAGSET_DEFINE_FLAG_ACCESSORS (CanThrow, canThrow, setCanThrow)
673
+
674
+ // / See AsyncContinuationFlags::isExecutorSwitchForced.
675
+ FLAGSET_DEFINE_FLAG_ACCESSORS (Continuation_IsExecutorSwitchForced,
676
+ continuation_isExecutorSwitchForced,
677
+ continuation_setIsExecutorSwitchForced)
678
+ };
679
+
680
+
617
681
// / An asynchronous context within a task. Generally contexts are
618
682
// / allocated using the task-local stack alloc/dealloc operations, but
619
683
// / there's no guarantee of that, and the ABI is designed to permit
@@ -634,9 +698,19 @@ class alignas(MaximumAlignment) AsyncContext {
634
698
TaskContinuationFunction * __ptrauth_swift_async_context_resume
635
699
ResumeParent;
636
700
637
- AsyncContext (TaskContinuationFunction *resumeParent,
701
+ // / Flags describing this context.
702
+ // /
703
+ // / Note that this field is only 32 bits; any alignment padding
704
+ // / following this on 64-bit platforms can be freely used by the
705
+ // / function. If the function is a yielding function, that padding
706
+ // / is of course interrupted by the YieldToParent field.
707
+ AsyncContextFlags Flags;
708
+
709
+ AsyncContext (AsyncContextFlags flags,
710
+ TaskContinuationFunction *resumeParent,
638
711
AsyncContext *parent)
639
- : Parent (parent), ResumeParent (resumeParent) {}
712
+ : Parent (parent), ResumeParent (resumeParent),
713
+ Flags (flags) {}
640
714
641
715
AsyncContext (const AsyncContext &) = delete ;
642
716
AsyncContext &operator =(const AsyncContext &) = delete ;
@@ -660,66 +734,48 @@ class YieldingAsyncContext : public AsyncContext {
660
734
TaskContinuationFunction * __ptrauth_swift_async_context_yield
661
735
YieldToParent;
662
736
663
- YieldingAsyncContext (TaskContinuationFunction *resumeParent,
737
+ YieldingAsyncContext (AsyncContextFlags flags,
738
+ TaskContinuationFunction *resumeParent,
664
739
TaskContinuationFunction *yieldToParent,
665
740
AsyncContext *parent)
666
- : AsyncContext(resumeParent, parent),
741
+ : AsyncContext(flags, resumeParent, parent),
667
742
YieldToParent (yieldToParent) {}
743
+
744
+ static bool classof (const AsyncContext *context) {
745
+ return context->Flags .getKind () == AsyncContextKind::Yielding;
746
+ }
668
747
};
669
748
670
749
// / An async context that can be resumed as a continuation.
671
750
class ContinuationAsyncContext : public AsyncContext {
672
751
public:
673
- class FlagsType : public FlagSet <size_t > {
674
- public:
675
- enum {
676
- CanThrow = 0 ,
677
- IsExecutorSwitchForced = 1 ,
678
- };
679
-
680
- explicit FlagsType (size_t bits) : FlagSet(bits) {}
681
- constexpr FlagsType () {}
682
-
683
- // / Whether this is a throwing continuation.
684
- FLAGSET_DEFINE_FLAG_ACCESSORS (CanThrow,
685
- canThrow,
686
- setCanThrow)
687
-
688
- // / See AsyncContinuationFlags::isExecutorSwitchForced().
689
- FLAGSET_DEFINE_FLAG_ACCESSORS (IsExecutorSwitchForced,
690
- isExecutorSwitchForced,
691
- setIsExecutorSwitchForced)
692
- };
693
-
694
- // / Flags for the continuation. Not public ABI.
695
- FlagsType Flags;
696
-
697
752
// / An atomic object used to ensure that a continuation is not
698
753
// / scheduled immediately during a resume if it hasn't yet been
699
- // / awaited by the function which set it up. Not public ABI.
754
+ // / awaited by the function which set it up.
700
755
std::atomic<ContinuationStatus> AwaitSynchronization;
701
756
702
757
// / The error result value of the continuation.
703
758
// / This should be null-initialized when setting up the continuation.
704
759
// / Throwing resumers must overwrite this with a non-null value.
705
- // / Public ABI.
706
760
SwiftError *ErrorResult;
707
761
708
762
// / A pointer to the normal result value of the continuation.
709
763
// / Normal resumers must initialize this before resuming.
710
- // / Public ABI.
711
764
OpaqueValue *NormalResult;
712
765
713
766
// / The executor that should be resumed to.
714
- // / Public ABI.
715
767
ExecutorRef ResumeToExecutor;
716
768
717
769
void setErrorResult (SwiftError *error) {
718
770
ErrorResult = error;
719
771
}
720
772
721
773
bool isExecutorSwitchForced () const {
722
- return Flags.isExecutorSwitchForced ();
774
+ return Flags.continuation_isExecutorSwitchForced ();
775
+ }
776
+
777
+ static bool classof (const AsyncContext *context) {
778
+ return context->Flags .getKind () == AsyncContextKind::Continuation;
723
779
}
724
780
};
725
781
0 commit comments