diff options
3 files changed, 58 insertions, 4 deletions
diff --git a/services/core/java/com/android/server/am/BroadcastConstants.java b/services/core/java/com/android/server/am/BroadcastConstants.java index dfac82cbe91b..04ba757d03e7 100644 --- a/services/core/java/com/android/server/am/BroadcastConstants.java +++ b/services/core/java/com/android/server/am/BroadcastConstants.java @@ -136,8 +136,8 @@ public class BroadcastConstants { private static final boolean DEFAULT_MODERN_QUEUE_ENABLED = true; /** - * For {@link BroadcastQueueModernImpl}: Maximum number of process queues to - * dispatch broadcasts to simultaneously. + * For {@link BroadcastQueueModernImpl}: Maximum dispatch parallelism + * that we'll tolerate for ordinary broadcast dispatch. */ public int MAX_RUNNING_PROCESS_QUEUES = DEFAULT_MAX_RUNNING_PROCESS_QUEUES; private static final String KEY_MAX_RUNNING_PROCESS_QUEUES = "bcast_max_running_process_queues"; @@ -145,6 +145,15 @@ public class BroadcastConstants { ActivityManager.isLowRamDeviceStatic() ? 2 : 4; /** + * For {@link BroadcastQueueModernImpl}: Additional running process queue parallelism beyond + * {@link #MAX_RUNNING_PROCESS_QUEUES} for dispatch of "urgent" broadcasts. + */ + public int EXTRA_RUNNING_URGENT_PROCESS_QUEUES = DEFAULT_EXTRA_RUNNING_URGENT_PROCESS_QUEUES; + private static final String KEY_EXTRA_RUNNING_URGENT_PROCESS_QUEUES = + "bcast_extra_running_urgent_process_queues"; + private static final int DEFAULT_EXTRA_RUNNING_URGENT_PROCESS_QUEUES = 1; + + /** * For {@link BroadcastQueueModernImpl}: Maximum number of active broadcasts * to dispatch to a "running" process queue before we retire them back to * being "runnable" to give other processes a chance to run. @@ -250,6 +259,10 @@ public class BroadcastConstants { updateDeviceConfigConstants(); } + public int getMaxRunningQueues() { + return MAX_RUNNING_PROCESS_QUEUES + EXTRA_RUNNING_URGENT_PROCESS_QUEUES; + } + private void updateSettingsConstants() { synchronized (this) { try { @@ -317,6 +330,9 @@ public class BroadcastConstants { DEFAULT_MODERN_QUEUE_ENABLED); MAX_RUNNING_PROCESS_QUEUES = getDeviceConfigInt(KEY_MAX_RUNNING_PROCESS_QUEUES, DEFAULT_MAX_RUNNING_PROCESS_QUEUES); + EXTRA_RUNNING_URGENT_PROCESS_QUEUES = getDeviceConfigInt( + KEY_EXTRA_RUNNING_URGENT_PROCESS_QUEUES, + DEFAULT_EXTRA_RUNNING_URGENT_PROCESS_QUEUES); MAX_RUNNING_ACTIVE_BROADCASTS = getDeviceConfigInt(KEY_MAX_RUNNING_ACTIVE_BROADCASTS, DEFAULT_MAX_RUNNING_ACTIVE_BROADCASTS); MAX_PENDING_BROADCASTS = getDeviceConfigInt(KEY_MAX_PENDING_BROADCASTS, diff --git a/services/core/java/com/android/server/am/BroadcastProcessQueue.java b/services/core/java/com/android/server/am/BroadcastProcessQueue.java index 7d9b4776bf37..0f9c775751af 100644 --- a/services/core/java/com/android/server/am/BroadcastProcessQueue.java +++ b/services/core/java/com/android/server/am/BroadcastProcessQueue.java @@ -584,6 +584,14 @@ class BroadcastProcessQueue { } /** + * Report whether this queue is currently handling an urgent broadcast. + */ + public boolean isPendingUrgent() { + BroadcastRecord next = peekNextBroadcastRecord(); + return (next != null) ? next.isUrgent() : false; + } + + /** * Quickly determine if this queue has broadcasts that are still waiting to * be delivered at some point in the future. */ diff --git a/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java b/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java index a7d843361762..765acf49c38d 100644 --- a/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java +++ b/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java @@ -138,7 +138,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue { // We configure runnable size only once at boot; it'd be too complex to // try resizing dynamically at runtime - mRunning = new BroadcastProcessQueue[mConstants.MAX_RUNNING_PROCESS_QUEUES]; + mRunning = new BroadcastProcessQueue[mConstants.getMaxRunningQueues()]; } /** @@ -293,6 +293,19 @@ class BroadcastQueueModernImpl extends BroadcastQueue { } /** + * Return the number of active queues that are delivering "urgent" broadcasts + */ + private int getRunningUrgentCount() { + int count = 0; + for (int i = 0; i < mRunning.length; i++) { + if (mRunning[i] != null && mRunning[i].getActive().isUrgent()) { + count++; + } + } + return count; + } + + /** * Return the first index of the given value contained inside * {@link #mRunning}, otherwise {@code -1}. */ @@ -356,7 +369,15 @@ class BroadcastQueueModernImpl extends BroadcastQueue { */ @GuardedBy("mService") private void updateRunningListLocked() { - int avail = mRunning.length - getRunningSize(); + // Allocated size here implicitly includes the extra reservation for urgent + // dispatches beyond the MAX_RUNNING_QUEUES soft limit for normal + // parallelism. If we're already dispatching some urgent broadcasts, + // count that against the extra first - its role is to permit progress of + // urgent broadcast traffic when the normal reservation is fully occupied + // with less-urgent dispatches, not to generally expand parallelism. + final int usedExtra = Math.min(getRunningUrgentCount(), + mConstants.EXTRA_RUNNING_URGENT_PROCESS_QUEUES); + int avail = mRunning.length - getRunningSize() - usedExtra; if (avail == 0) return; final int cookie = traceBegin("updateRunningList"); @@ -382,6 +403,15 @@ class BroadcastQueueModernImpl extends BroadcastQueue { continue; } + // If we've hit the soft limit for non-urgent dispatch parallelism, + // only consider delivering from queues whose ready broadcast is urgent + if (getRunningSize() >= mConstants.MAX_RUNNING_PROCESS_QUEUES) { + if (!queue.isPendingUrgent()) { + queue = nextQueue; + continue; + } + } + // If queues beyond this point aren't ready to run yet, schedule // another pass when they'll be runnable if (runnableAt > now && !waitingFor) { |