@@ -970,32 +970,40 @@ inline bool AsyncTask::isCancelled() const {
970970 .isCancelled ();
971971}
972972
973- inline void AsyncTask::flagAsRunning () {
973+ inline uint32_t AsyncTask::flagAsRunning () {
974974
975975#if SWIFT_CONCURRENCY_ENABLE_PRIORITY_ESCALATION
976976 dispatch_thread_override_info_s threadOverrideInfo;
977977 threadOverrideInfo = swift_dispatch_thread_get_current_override_qos_floor ();
978978 qos_class_t overrideFloor = threadOverrideInfo.override_qos_floor ;
979+ qos_class_t basePriorityCeil = overrideFloor;
980+ qos_class_t taskBasePriority = (qos_class_t ) _private ().BasePriority ;
979981#endif
980982
981983 auto oldStatus = _private ()._status ().load (std::memory_order_relaxed);
982984 assert (!oldStatus.isRunning ());
983985 assert (!oldStatus.isComplete ());
984986
987+ uint32_t dispatchOpaquePriority = 0 ;
985988 if (!oldStatus.hasTaskDependency ()) {
986989 SWIFT_TASK_DEBUG_LOG (" %p->flagAsRunning() with no task dependency" , this );
987990 assert (_private ().dependencyRecord == nullptr );
988991
989992 while (true ) {
990993#if SWIFT_CONCURRENCY_ENABLE_PRIORITY_ESCALATION
991- // Task's priority is greater than the thread's - do a self escalation
994+ // If the base priority is not equal to the current override floor then
995+ // dispqatch may need to apply the base priority to the thread. If the
996+ // current priority is higher than the override floor, then dispatch may
997+ // need to apply a self-override. In either case, call into dispatch to
998+ // do this.
992999 qos_class_t maxTaskPriority = (qos_class_t ) oldStatus.getStoredPriority ();
993- if (threadOverrideInfo.can_override && (maxTaskPriority > overrideFloor)) {
994- SWIFT_TASK_DEBUG_LOG (" [Override] Self-override thread with oq_floor %#x to match task %p's max priority %#x" ,
995- overrideFloor, this , maxTaskPriority);
1000+ if (threadOverrideInfo.can_override && (taskBasePriority != basePriorityCeil || maxTaskPriority > overrideFloor)) {
1001+ SWIFT_TASK_DEBUG_LOG (" [Override] Self-override thread with oq_floor %#x to match task %p's max priority %#x and base priority %#x " ,
1002+ overrideFloor, this , maxTaskPriority, taskBasePriority );
9961003
997- ( void ) swift_dispatch_thread_override_self (maxTaskPriority);
1004+ dispatchOpaquePriority = swift_dispatch_thread_override_self_with_base (maxTaskPriority, taskBasePriority );
9981005 overrideFloor = maxTaskPriority;
1006+ basePriorityCeil = taskBasePriority;
9991007 }
10001008#endif
10011009 // Set self as executor and remove escalation bit if any - the task's
@@ -1024,14 +1032,19 @@ inline void AsyncTask::flagAsRunning() {
10241032 ActiveTaskStatus& newStatus) {
10251033
10261034#if SWIFT_CONCURRENCY_ENABLE_PRIORITY_ESCALATION
1027- // Task's priority is greater than the thread's - do a self escalation
1035+ // If the base priority is not equal to the current override floor then
1036+ // dispqatch may need to apply the base priority to the thread. If the
1037+ // current priority is higher than the override floor, then dispatch may
1038+ // need to apply a self-override. In either case, call into dispatch to
1039+ // do this.
10281040 qos_class_t maxTaskPriority = (qos_class_t ) oldStatus.getStoredPriority ();
1029- if (threadOverrideInfo.can_override && (maxTaskPriority > overrideFloor)) {
1030- SWIFT_TASK_DEBUG_LOG (" [Override] Self-override thread with oq_floor %#x to match task %p's max priority %#x" ,
1031- overrideFloor, this , maxTaskPriority);
1041+ if (threadOverrideInfo.can_override && (taskBasePriority != basePriorityCeil || maxTaskPriority > overrideFloor)) {
1042+ SWIFT_TASK_DEBUG_LOG (" [Override] Self-override thread with oq_floor %#x to match task %p's max priority %#x and base priority %#x " ,
1043+ overrideFloor, this , maxTaskPriority, taskBasePriority );
10321044
1033- ( void ) swift_dispatch_thread_override_self (maxTaskPriority);
1045+ dispatchOpaquePriority = swift_dispatch_thread_override_self_with_base (maxTaskPriority, taskBasePriority );
10341046 overrideFloor = maxTaskPriority;
1047+ basePriorityCeil = taskBasePriority;
10351048 }
10361049#endif
10371050 // Set self as executor and remove escalation bit if any - the task's
@@ -1047,7 +1060,7 @@ inline void AsyncTask::flagAsRunning() {
10471060 swift_task_enterThreadLocalContext (
10481061 (char *)&_private ().ExclusivityAccessSet [0 ]);
10491062 }
1050-
1063+ return dispatchOpaquePriority;
10511064}
10521065
10531066// / TODO (rokhinip): We need the handoff of the thread to the next executor to
0 commit comments