@@ -935,32 +935,40 @@ inline bool AsyncTask::isCancelled() const {
935935 .isCancelled ();
936936}
937937
938- inline void AsyncTask::flagAsRunning () {
938+ inline uint32_t AsyncTask::flagAsRunning () {
939939
940940#if SWIFT_CONCURRENCY_ENABLE_PRIORITY_ESCALATION
941941 dispatch_thread_override_info_s threadOverrideInfo;
942942 threadOverrideInfo = swift_dispatch_thread_get_current_override_qos_floor ();
943943 qos_class_t overrideFloor = threadOverrideInfo.override_qos_floor ;
944+ qos_class_t basePriorityCeil = overrideFloor;
945+ qos_class_t taskBasePriority = (qos_class_t ) _private ().BasePriority ;
944946#endif
945947
946948 auto oldStatus = _private ()._status ().load (std::memory_order_relaxed);
947949 assert (!oldStatus.isRunning ());
948950 assert (!oldStatus.isComplete ());
949951
952+ uint32_t dispatch_opaque_priority = 0 ;
950953 if (!oldStatus.hasTaskDependency ()) {
951954 SWIFT_TASK_DEBUG_LOG (" %p->flagAsRunning() with no task dependency" , this );
952955 assert (_private ().dependencyRecord == nullptr );
953956
954957 while (true ) {
955958#if SWIFT_CONCURRENCY_ENABLE_PRIORITY_ESCALATION
956- // Task's priority is greater than the thread's - do a self escalation
959+ // If the base priority is not equal to the current override floor then
960+ // dispqatch may need to apply the base priority to the thread. If the
961+ // current priority is higher than the override floor, then dispatch may
962+ // need to apply a self-override. In either case, call into dispatch to
963+ // do this.
957964 qos_class_t maxTaskPriority = (qos_class_t ) oldStatus.getStoredPriority ();
958- if (threadOverrideInfo.can_override && (maxTaskPriority > overrideFloor)) {
959- SWIFT_TASK_DEBUG_LOG (" [Override] Self-override thread with oq_floor %#x to match task %p's max priority %#x" ,
960- overrideFloor, this , maxTaskPriority);
965+ if (threadOverrideInfo.can_override && (taskBasePriority != basePriorityCeil || maxTaskPriority > overrideFloor)) {
966+ SWIFT_TASK_DEBUG_LOG (" [Override] Self-override thread with oq_floor %#x to match task %p's max priority %#x and base priority %#x " ,
967+ overrideFloor, this , maxTaskPriority, taskBasePriority );
961968
962- ( void ) swift_dispatch_thread_override_self (maxTaskPriority);
969+ dispatch_opaque_priority = swift_dispatch_thread_override_self_with_base (maxTaskPriority, taskBasePriority );
963970 overrideFloor = maxTaskPriority;
971+ basePriorityCeil = taskBasePriority;
964972 }
965973#endif
966974 // Set self as executor and remove escalation bit if any - the task's
@@ -989,14 +997,19 @@ inline void AsyncTask::flagAsRunning() {
989997 ActiveTaskStatus& newStatus) {
990998
991999#if SWIFT_CONCURRENCY_ENABLE_PRIORITY_ESCALATION
992- // Task's priority is greater than the thread's - do a self escalation
1000+ // If the base priority is not equal to the current override floor then
1001+ // dispqatch may need to apply the base priority to the thread. If the
1002+ // current priority is higher than the override floor, then dispatch may
1003+ // need to apply a self-override. In either case, call into dispatch to
1004+ // do this.
9931005 qos_class_t maxTaskPriority = (qos_class_t ) oldStatus.getStoredPriority ();
994- if (threadOverrideInfo.can_override && (maxTaskPriority > overrideFloor)) {
995- SWIFT_TASK_DEBUG_LOG (" [Override] Self-override thread with oq_floor %#x to match task %p's max priority %#x" ,
996- overrideFloor, this , maxTaskPriority);
1006+ if (threadOverrideInfo.can_override && (taskBasePriority != basePriorityCeil || maxTaskPriority > overrideFloor)) {
1007+ SWIFT_TASK_DEBUG_LOG (" [Override] Self-override thread with oq_floor %#x to match task %p's max priority %#x and base priority %#x " ,
1008+ overrideFloor, this , maxTaskPriority, taskBasePriority );
9971009
998- ( void ) swift_dispatch_thread_override_self (maxTaskPriority);
1010+ dispatch_opaque_priority = swift_dispatch_thread_override_self_with_base (maxTaskPriority, taskBasePriority );
9991011 overrideFloor = maxTaskPriority;
1012+ basePriorityCeil = taskBasePriority;
10001013 }
10011014#endif
10021015 // Set self as executor and remove escalation bit if any - the task's
@@ -1012,7 +1025,7 @@ inline void AsyncTask::flagAsRunning() {
10121025 swift_task_enterThreadLocalContext (
10131026 (char *)&_private ().ExclusivityAccessSet [0 ]);
10141027 }
1015-
1028+ return dispatch_opaque_priority;
10161029}
10171030
10181031// / TODO (rokhinip): We need the handoff of the thread to the next executor to
0 commit comments