Loading services/core/java/com/android/server/am/ActivityManagerService.java +2 −0 Original line number Diff line number Diff line Loading @@ -18100,8 +18100,10 @@ public class ActivityManagerService extends IActivityManager.Stub if (!queue.isIdle()) { final String msg = "Waiting for queue " + queue + " to become idle..."; pw.println(msg); pw.println(queue.describeState()); pw.flush(); Slog.v(TAG, msg); queue.cancelDeferrals(); idle = false; } } services/core/java/com/android/server/am/BroadcastDispatcher.java +65 −11 Original line number Diff line number Diff line Loading @@ -65,6 +65,14 @@ public class BroadcastDispatcher { broadcasts.add(br); } int size() { return broadcasts.size(); } boolean isEmpty() { return broadcasts.isEmpty(); } void writeToProto(ProtoOutputStream proto, long fieldId) { for (BroadcastRecord br : broadcasts) { br.writeToProto(proto, fieldId); Loading Loading @@ -252,22 +260,48 @@ public class BroadcastDispatcher { synchronized (mLock) { return mCurrentBroadcast == null && mOrderedBroadcasts.isEmpty() && mDeferredBroadcasts.isEmpty() && mAlarmBroadcasts.isEmpty(); && isDeferralsListEmpty(mDeferredBroadcasts) && isDeferralsListEmpty(mAlarmBroadcasts); } } private static int pendingInDeferralsList(ArrayList<Deferrals> list) { int pending = 0; final int numEntries = list.size(); for (int i = 0; i < numEntries; i++) { pending += list.get(i).size(); } return pending; } private static boolean isDeferralsListEmpty(ArrayList<Deferrals> list) { return pendingInDeferralsList(list) == 0; } /** * Not quite the traditional size() measurement; includes any in-process but * not yet retired active outbound broadcast. * Strictly for logging, describe the currently pending contents in a human- * readable way */ public int totalUndelivered() { synchronized (mLock) { return mAlarmBroadcasts.size() + mDeferredBroadcasts.size() + mOrderedBroadcasts.size() + (mCurrentBroadcast == null ? 0 : 1); public String describeStateLocked() { final StringBuilder sb = new StringBuilder(128); if (mCurrentBroadcast != null) { sb.append("1 in flight, "); } sb.append(mOrderedBroadcasts.size()); sb.append(" ordered"); int n = pendingInDeferralsList(mAlarmBroadcasts); if (n > 0) { sb.append(", "); sb.append(n); sb.append(" deferrals in alarm recipients"); } n = pendingInDeferralsList(mDeferredBroadcasts); if (n > 0) { sb.append(", "); sb.append(n); sb.append(" deferred"); } return sb.toString(); } // ---------------------------------- Loading Loading @@ -579,6 +613,26 @@ public class BroadcastDispatcher { } } /** * Cancel all current deferrals; that is, make all currently-deferred broadcasts * immediately deliverable. Used by the wait-for-broadcast-idle mechanism. */ public void cancelDeferrals() { synchronized (mLock) { zeroDeferralTimes(mAlarmBroadcasts); zeroDeferralTimes(mDeferredBroadcasts); } } private static void zeroDeferralTimes(ArrayList<Deferrals> list) { final int num = list.size(); for (int i = 0; i < num; i++) { Deferrals d = list.get(i); // Safe to do this in-place because it won't break ordering d.deferUntil = d.deferredBy = 0; } } // ---------------------------------- /** Loading services/core/java/com/android/server/am/BroadcastQueue.java +16 −3 Original line number Diff line number Diff line Loading @@ -928,8 +928,8 @@ public final class BroadcastQueue { if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "processNextBroadcast [" + mQueueName + "]: " + mParallelBroadcasts.size() + " parallel broadcasts, " + mDispatcher.totalUndelivered() + " ordered broadcasts"); + mParallelBroadcasts.size() + " parallel broadcasts; " + mDispatcher.describeStateLocked()); mService.updateCpuStats(); Loading Loading @@ -1827,11 +1827,24 @@ public final class BroadcastQueue { record.intent == null ? "" : record.intent.getAction()); } final boolean isIdle() { boolean isIdle() { return mParallelBroadcasts.isEmpty() && mDispatcher.isEmpty() && (mPendingBroadcast == null); } // Used by wait-for-broadcast-idle : fast-forward all current deferrals to // be immediately deliverable. void cancelDeferrals() { mDispatcher.cancelDeferrals(); } String describeState() { synchronized (mService) { return mParallelBroadcasts.size() + " parallel; " + mDispatcher.describeStateLocked(); } } void writeToProto(ProtoOutputStream proto, long fieldId) { long token = proto.start(fieldId); proto.write(BroadcastQueueProto.QUEUE_NAME, mQueueName); Loading Loading
services/core/java/com/android/server/am/ActivityManagerService.java +2 −0 Original line number Diff line number Diff line Loading @@ -18100,8 +18100,10 @@ public class ActivityManagerService extends IActivityManager.Stub if (!queue.isIdle()) { final String msg = "Waiting for queue " + queue + " to become idle..."; pw.println(msg); pw.println(queue.describeState()); pw.flush(); Slog.v(TAG, msg); queue.cancelDeferrals(); idle = false; } }
services/core/java/com/android/server/am/BroadcastDispatcher.java +65 −11 Original line number Diff line number Diff line Loading @@ -65,6 +65,14 @@ public class BroadcastDispatcher { broadcasts.add(br); } int size() { return broadcasts.size(); } boolean isEmpty() { return broadcasts.isEmpty(); } void writeToProto(ProtoOutputStream proto, long fieldId) { for (BroadcastRecord br : broadcasts) { br.writeToProto(proto, fieldId); Loading Loading @@ -252,22 +260,48 @@ public class BroadcastDispatcher { synchronized (mLock) { return mCurrentBroadcast == null && mOrderedBroadcasts.isEmpty() && mDeferredBroadcasts.isEmpty() && mAlarmBroadcasts.isEmpty(); && isDeferralsListEmpty(mDeferredBroadcasts) && isDeferralsListEmpty(mAlarmBroadcasts); } } private static int pendingInDeferralsList(ArrayList<Deferrals> list) { int pending = 0; final int numEntries = list.size(); for (int i = 0; i < numEntries; i++) { pending += list.get(i).size(); } return pending; } private static boolean isDeferralsListEmpty(ArrayList<Deferrals> list) { return pendingInDeferralsList(list) == 0; } /** * Not quite the traditional size() measurement; includes any in-process but * not yet retired active outbound broadcast. * Strictly for logging, describe the currently pending contents in a human- * readable way */ public int totalUndelivered() { synchronized (mLock) { return mAlarmBroadcasts.size() + mDeferredBroadcasts.size() + mOrderedBroadcasts.size() + (mCurrentBroadcast == null ? 0 : 1); public String describeStateLocked() { final StringBuilder sb = new StringBuilder(128); if (mCurrentBroadcast != null) { sb.append("1 in flight, "); } sb.append(mOrderedBroadcasts.size()); sb.append(" ordered"); int n = pendingInDeferralsList(mAlarmBroadcasts); if (n > 0) { sb.append(", "); sb.append(n); sb.append(" deferrals in alarm recipients"); } n = pendingInDeferralsList(mDeferredBroadcasts); if (n > 0) { sb.append(", "); sb.append(n); sb.append(" deferred"); } return sb.toString(); } // ---------------------------------- Loading Loading @@ -579,6 +613,26 @@ public class BroadcastDispatcher { } } /** * Cancel all current deferrals; that is, make all currently-deferred broadcasts * immediately deliverable. Used by the wait-for-broadcast-idle mechanism. */ public void cancelDeferrals() { synchronized (mLock) { zeroDeferralTimes(mAlarmBroadcasts); zeroDeferralTimes(mDeferredBroadcasts); } } private static void zeroDeferralTimes(ArrayList<Deferrals> list) { final int num = list.size(); for (int i = 0; i < num; i++) { Deferrals d = list.get(i); // Safe to do this in-place because it won't break ordering d.deferUntil = d.deferredBy = 0; } } // ---------------------------------- /** Loading
services/core/java/com/android/server/am/BroadcastQueue.java +16 −3 Original line number Diff line number Diff line Loading @@ -928,8 +928,8 @@ public final class BroadcastQueue { if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "processNextBroadcast [" + mQueueName + "]: " + mParallelBroadcasts.size() + " parallel broadcasts, " + mDispatcher.totalUndelivered() + " ordered broadcasts"); + mParallelBroadcasts.size() + " parallel broadcasts; " + mDispatcher.describeStateLocked()); mService.updateCpuStats(); Loading Loading @@ -1827,11 +1827,24 @@ public final class BroadcastQueue { record.intent == null ? "" : record.intent.getAction()); } final boolean isIdle() { boolean isIdle() { return mParallelBroadcasts.isEmpty() && mDispatcher.isEmpty() && (mPendingBroadcast == null); } // Used by wait-for-broadcast-idle : fast-forward all current deferrals to // be immediately deliverable. void cancelDeferrals() { mDispatcher.cancelDeferrals(); } String describeState() { synchronized (mService) { return mParallelBroadcasts.size() + " parallel; " + mDispatcher.describeStateLocked(); } } void writeToProto(ProtoOutputStream proto, long fieldId) { long token = proto.start(fieldId); proto.write(BroadcastQueueProto.QUEUE_NAME, mQueueName); Loading