Skip to content

Commit

Permalink
Add API for instrumentation to learn the starting wall time of bg thr…
Browse files Browse the repository at this point in the history
…eads

Summary: Computing things like "page faults since this thread was created" or "cpu time spent on this thread since it was created" is pretty easy - just measure it when you want it.  However, if you want to know "how much wall time has elapsed since this thread was created" you need to record some timing info when the thread is created.  This diff adds a an API for querying that from the RN thread holder abstraction.

Reviewed By: alexeylang

Differential Revision: D13246235

fbshipit-source-id: d36af61dbe27f662980fe508b2644e9d5255bb7e
  • Loading branch information
johnislarry authored and facebook-github-bot committed Dec 3, 2018
1 parent 9e0b791 commit 2330843
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,11 @@ public interface MessageQueueThread {
*/
@DoNotStrip
void quitSynchronous();

/**
* Returns the time in milliseconds at which this thread was started. This
* method is intended to be used for instrumentation purposes.
*/
@DoNotStrip
long getStartTimeMillis();
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@
import java.util.concurrent.Callable;
import java.util.concurrent.Future;

import android.os.SystemClock;
import android.os.Looper;
import android.os.Process;

import android.util.Pair;
import com.facebook.common.logging.FLog;
import com.facebook.proguard.annotations.DoNotStrip;
import com.facebook.react.bridge.AssertionException;
Expand All @@ -31,15 +32,25 @@ public class MessageQueueThreadImpl implements MessageQueueThread {
private final Looper mLooper;
private final MessageQueueThreadHandler mHandler;
private final String mAssertionErrorMessage;
private long mStartTimeMillis;
private volatile boolean mIsFinished = false;

private MessageQueueThreadImpl(
String name,
Looper looper,
QueueThreadExceptionHandler exceptionHandler) {
this(name, looper, exceptionHandler, -1);
}

private MessageQueueThreadImpl(
String name,
Looper looper,
QueueThreadExceptionHandler exceptionHandler,
long startTimeMillis) {
mName = name;
mLooper = looper;
mHandler = new MessageQueueThreadHandler(looper, exceptionHandler);
mStartTimeMillis = startTimeMillis;
mAssertionErrorMessage = "Expected to be called from the '" + getName() + "' thread!";
}

Expand Down Expand Up @@ -126,6 +137,12 @@ public void quitSynchronous() {
}
}

@DoNotStrip
@Override
public long getStartTimeMillis() {
return mStartTimeMillis;
}

public Looper getLooper() {
return mLooper;
}
Expand Down Expand Up @@ -180,21 +197,21 @@ private static MessageQueueThreadImpl startNewBackgroundThread(
final String name,
long stackSize,
QueueThreadExceptionHandler exceptionHandler) {
final SimpleSettableFuture<Looper> looperFuture = new SimpleSettableFuture<>();
final SimpleSettableFuture<Pair<Looper, Long>> dataFuture = new SimpleSettableFuture<>();
long startTimeMillis;
Thread bgThread = new Thread(null,
new Runnable() {
@Override
public void run() {
Process.setThreadPriority(Process.THREAD_PRIORITY_DISPLAY);
Looper.prepare();

looperFuture.set(Looper.myLooper());
dataFuture.set(new Pair<>(Looper.myLooper(), SystemClock.uptimeMillis()));
Looper.loop();
}
}, "mqt_" + name, stackSize);
bgThread.start();

Looper myLooper = looperFuture.getOrThrow();
return new MessageQueueThreadImpl(name, myLooper, exceptionHandler);
Pair<Looper, Long> pair = dataFuture.getOrThrow();
return new MessageQueueThreadImpl(name, pair.first, exceptionHandler, pair.second);
}
}

0 comments on commit 2330843

Please sign in to comment.