Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0153c25b authored by Felipe Leme's avatar Felipe Leme
Browse files

Improved SystemServer dumper to use weak references.

Otherwise, it would hold objects that are only used during boot.

Test: adb shell dumpsys system_server_dumper --name SystemServerInitThreadPool
Fixes: 443327246
Flag: EXEMPT BUGFIX

Change-Id: Iff76a8b7ab400962676ebe32dcb966e53272f608
parent 81e2ca71
Loading
Loading
Loading
Loading
+3 −5
Original line number Diff line number Diff line
@@ -74,7 +74,7 @@ public final class SystemServerInitThreadPool implements Dumpable {
                "system-server-init-thread", Process.THREAD_PRIORITY_FOREGROUND);
    }

    private static SystemServerInitThreadPool getInstance() {
    static SystemServerInitThreadPool getInstance() {
        SystemServerInitThreadPool instance;
        synchronized (LOCK) {
            Preconditions.checkState(sInstance != null, "Cannot get " + TAG
@@ -144,13 +144,11 @@ public final class SystemServerInitThreadPool implements Dumpable {
     *
     * @throws IllegalStateException if it has been started already without being shut down yet.
     */
    static SystemServerInitThreadPool start() {
        SystemServerInitThreadPool instance;
    static void start() {
        synchronized (LOCK) {
            Preconditions.checkState(sInstance == null, TAG + " already started");
            instance = sInstance = new SystemServerInitThreadPool();
            sInstance = new SystemServerInitThreadPool();
        }
        return instance;
    }

    /**
+29 −9
Original line number Diff line number Diff line
@@ -321,7 +321,9 @@ import java.io.File;
import java.io.FileDescriptor;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.ref.WeakReference;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.LinkedList;
@@ -757,7 +759,7 @@ public final class SystemServer implements Dumpable {
    private final class SystemServerDumper extends Binder {

        @GuardedBy("mDumpables")
        private final ArrayMap<String, Dumpable> mDumpables = new ArrayMap<>(4);
        private final ArrayMap<String, WeakReference<Dumpable>> mDumpables = new ArrayMap<>(4);

        @Override
        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
@@ -778,13 +780,17 @@ public final class SystemServer implements Dumpable {
                        return;
                    }
                    final String name = args[1];
                    final Dumpable dumpable = mDumpables.get(name);
                    if (dumpable == null) {
                    final var ref = mDumpables.get(name);
                    if (ref == null) {
                        pw.printf("No dumpable named %s\n", name);
                        return;
                    }

                    try (IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ")) {
                        final var dumpable = ref.get();
                        if (dumpable == null) {
                            ipw.printf("%s has been garbage collected\n", name);
                            return;
                        }
                        // Strip --name DUMPABLE from args
                        final String[] actualArgs = Arrays.copyOfRange(args, 2, args.length);
                        dumpable.dump(ipw, actualArgs);
@@ -793,22 +799,36 @@ public final class SystemServer implements Dumpable {
                }

                final int dumpablesSize = mDumpables.size();
                List<String> garbageCollected = null;
                try (IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ")) {
                    for (int i = 0; i < dumpablesSize; i++) {
                        final Dumpable dumpable = mDumpables.valueAt(i);
                        final var ref = mDumpables.valueAt(i);
                        final var dumpable = ref.get();
                        if (dumpable == null) {
                            if (garbageCollected == null) {
                                garbageCollected = new ArrayList<>(dumpablesSize);
                            }
                            garbageCollected.add(mDumpables.keyAt(i));
                            continue;
                        }
                        ipw.printf("%s:\n", dumpable.getDumpableName());
                        ipw.increaseIndent();
                        dumpable.dump(ipw, args);
                        ipw.decreaseIndent();
                        ipw.println();
                    }
                    if (garbageCollected != null) {
                        ipw.printf("%d dumpable(s) has been garbage collected: %s\n",
                                garbageCollected.size(), garbageCollected);
                    }
                }

            }
        }

        private void addDumpable(@NonNull Dumpable dumpable) {
        private void addDumpable(Dumpable dumpable) {
            synchronized (mDumpables) {
                mDumpables.put(dumpable.getDumpableName(), dumpable);
                mDumpables.put(dumpable.getDumpableName(), new WeakReference<>(dumpable));
            }
        }
    }
@@ -916,8 +936,8 @@ public final class SystemServer implements Dumpable {
            SystemServiceRegistry.sEnableServiceNotFoundWtf = true;

            // Prepare the thread pool for init tasks that can be parallelized
            SystemServerInitThreadPool tp = SystemServerInitThreadPool.start();
            mDumper.addDumpable(tp);
            SystemServerInitThreadPool.start();
            mDumper.addDumpable(SystemServerInitThreadPool.getInstance());

            // SystemConfig init is expensive, so enqueue the work as early as possible to allow
            // concurrent execution before it's needed (typically by ActivityManagerService).