resolve merge conflicts of 40654b7696 to qt-dev-plus-aosp

Bug: None
Test: I solemnly swear I tested this conflict resolution.
Merged-In: If26d625c4b1e5e8eee54dcdacb32360b0d852829
Change-Id: I36452eb4cfbc1c22533a2168aaa2ee0fad54286c
This commit is contained in:
Chris Wailes
2019-05-15 16:25:49 -07:00
committed by Mathieu Chartier
5 changed files with 289 additions and 165 deletions

View File

@@ -172,6 +172,11 @@ public final class Zygote {
*/
public static final int SOCKET_BUFFER_SIZE = 256;
/**
* @hide for internal use only
*/
private static final int PRIORITY_MAX = -20;
/** a prototype instance for a future List.toArray() */
protected static final int[][] INT_ARRAY_2D = new int[0][0];
@@ -236,8 +241,7 @@ public final class Zygote {
int[] fdsToIgnore, boolean startChildZygote, String instructionSet, String appDataDir,
int targetSdkVersion) {
ZygoteHooks.preFork();
// Resets nice priority for zygote process.
resetNicePriority();
int pid = nativeForkAndSpecialize(
uid, gid, gids, runtimeFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose,
fdsToIgnore, startChildZygote, instructionSet, appDataDir);
@@ -249,6 +253,7 @@ public final class Zygote {
// Note that this event ends at the end of handleChildProc,
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "PostFork");
}
ZygoteHooks.postForkCommon();
return pid;
}
@@ -335,15 +340,16 @@ public final class Zygote {
public static int forkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,
int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
ZygoteHooks.preFork();
// Resets nice priority for zygote process.
resetNicePriority();
int pid = nativeForkSystemServer(
uid, gid, gids, runtimeFlags, rlimits,
permittedCapabilities, effectiveCapabilities);
// Enable tracing as soon as we enter the system_server.
if (pid == 0) {
Trace.setTracingEnabled(true, runtimeFlags);
}
ZygoteHooks.postForkCommon();
return pid;
}
@@ -461,13 +467,16 @@ public final class Zygote {
/**
* Fork a new unspecialized app process from the zygote
*
* @param usapPoolSocket The server socket the USAP will call accept on
* @param sessionSocketRawFDs Anonymous session sockets that are currently open
* @param isPriorityFork Value controlling the process priority level until accept is called
* @return In the Zygote process this function will always return null; in unspecialized app
* processes this function will return a Runnable object representing the new
* application that is passed up from usapMain.
*/
static Runnable forkUsap(LocalServerSocket usapPoolSocket,
int[] sessionSocketRawFDs) {
int[] sessionSocketRawFDs,
boolean isPriorityFork) {
FileDescriptor[] pipeFDs = null;
try {
@@ -477,7 +486,8 @@ public final class Zygote {
}
int pid =
nativeForkUsap(pipeFDs[0].getInt$(), pipeFDs[1].getInt$(), sessionSocketRawFDs);
nativeForkUsap(pipeFDs[0].getInt$(), pipeFDs[1].getInt$(),
sessionSocketRawFDs, isPriorityFork);
if (pid == 0) {
IoUtils.closeQuietly(pipeFDs[0]);
@@ -491,8 +501,9 @@ public final class Zygote {
}
private static native int nativeForkUsap(int readPipeFD,
int writePipeFD,
int[] sessionSocketRawFDs);
int writePipeFD,
int[] sessionSocketRawFDs,
boolean isPriorityFork);
/**
* This function is used by unspecialized app processes to wait for specialization requests from
@@ -515,6 +526,11 @@ public final class Zygote {
// Load resources
ZygoteInit.nativePreloadGraphicsDriver();
// Change the priority to max before calling accept so we can respond to new specialization
// requests as quickly as possible. This will be reverted to the default priority in the
// native specialization code.
boostUsapPriority();
while (true) {
try {
sessionSocket = usapPoolSocket.accept();
@@ -626,6 +642,12 @@ public final class Zygote {
}
}
private static void boostUsapPriority() {
nativeBoostUsapPriority();
}
private static native void nativeBoostUsapPriority();
private static final String USAP_ERROR_PREFIX = "Invalid command to USAP: ";
/**
@@ -865,15 +887,6 @@ public final class Zygote {
ZygoteHooks.postForkChild(runtimeFlags, isSystemServer, isZygote, instructionSet);
}
/**
* Resets the calling thread priority to the default value (Thread.NORM_PRIORITY
* or nice value 0). This updates both the priority value in java.lang.Thread and
* the nice value (setpriority).
*/
static void resetNicePriority() {
Thread.currentThread().setPriority(Thread.NORM_PRIORITY);
}
/**
* Executes "/system/bin/sh -c <command>" using the exec() system call.
* This method throws a runtime exception if exec() failed, otherwise, this

View File

@@ -330,7 +330,7 @@ class ZygoteConnection {
if (zygoteServer.isUsapPoolEnabled()) {
Runnable fpResult =
zygoteServer.fillUsapPool(
new int[]{mSocket.getFileDescriptor().getInt$()});
new int[]{mSocket.getFileDescriptor().getInt$()}, false);
if (fpResult != null) {
zygoteServer.setForkChild();

View File

@@ -822,6 +822,9 @@ public class ZygoteInit {
public static void main(String argv[]) {
ZygoteServer zygoteServer = null;
// Set the initial thread priority to the "normal" value.
Thread.currentThread().setPriority(Thread.NORM_PRIORITY);
// Mark zygote start. This ensures that thread creation will throw
// an error.
ZygoteHooks.startZygoteNoThreadCreation();
@@ -881,8 +884,6 @@ public class ZygoteInit {
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
SystemClock.uptimeMillis());
bootTimingsTraceLog.traceEnd(); // ZygotePreload
} else {
Zygote.resetNicePriority();
}
// Do an initial gc to clean up after startup

View File

@@ -66,6 +66,15 @@ class ZygoteServer {
/** The default value used for the USAP_POOL_SIZE_MIN device property */
private static final String USAP_POOL_SIZE_MIN_DEFAULT = "1";
/**
* Number of milliseconds to delay before refilling the pool if it hasn't reached its
* minimum value.
*/
private static final int USAP_REFILL_DELAY_MS = 3000;
/** The "not a timestamp" value for the refill delay timestamp mechanism. */
private static final int INVALID_TIMESTAMP = -1;
/**
* Indicates if this Zygote server can support a unspecialized app process pool. Currently this
* should only be true for the primary and secondary Zygotes, and not the App Zygotes or the
@@ -131,6 +140,12 @@ class ZygoteServer {
*/
private int mUsapPoolRefillThreshold = 0;
private enum UsapPoolRefillAction {
DELAYED,
IMMEDIATE,
NONE
}
ZygoteServer() {
mUsapPoolEventFD = null;
mZygoteSocket = null;
@@ -293,9 +308,16 @@ class ZygoteServer {
}
}
private void fetchUsapPoolPolicyPropsIfUnfetched() {
if (mIsFirstPropertyCheck) {
mIsFirstPropertyCheck = false;
fetchUsapPoolPolicyProps();
}
}
/**
* Checks to see if the current policy says that pool should be refilled, and spawns new USAPs
* if necessary.
* Refill the USAP Pool to the appropriate level, determined by whether this is a priority
* refill event or not.
*
* @param sessionSocketRawFDs Anonymous session sockets that are currently open
* @return In the Zygote process this function will always return null; in unspecialized app
@@ -303,39 +325,46 @@ class ZygoteServer {
* application that is passed up from usapMain.
*/
Runnable fillUsapPool(int[] sessionSocketRawFDs) {
Runnable fillUsapPool(int[] sessionSocketRawFDs, boolean isPriorityRefill) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Zygote:FillUsapPool");
// Ensure that the pool properties have been fetched.
fetchUsapPoolPolicyPropsWithMinInterval();
fetchUsapPoolPolicyPropsIfUnfetched();
int usapPoolCount = Zygote.getUsapPoolCount();
int numUsapsToSpawn = mUsapPoolSizeMax - usapPoolCount;
int numUsapsToSpawn;
if (usapPoolCount < mUsapPoolSizeMin
|| numUsapsToSpawn >= mUsapPoolRefillThreshold) {
// Disable some VM functionality and reset some system values
// before forking.
ZygoteHooks.preFork();
Zygote.resetNicePriority();
while (usapPoolCount++ < mUsapPoolSizeMax) {
Runnable caller = Zygote.forkUsap(mUsapPoolSocket, sessionSocketRawFDs);
if (caller != null) {
return caller;
}
}
// Re-enable runtime services for the Zygote. Services for unspecialized app process
// are re-enabled in specializeAppProcess.
ZygoteHooks.postForkCommon();
if (isPriorityRefill) {
// Refill to min
numUsapsToSpawn = mUsapPoolSizeMin - usapPoolCount;
Log.i("zygote",
"Filled the USAP pool. New USAPs: " + numUsapsToSpawn);
"Priority USAP Pool refill. New USAPs: " + numUsapsToSpawn);
} else {
// Refill up to max
numUsapsToSpawn = mUsapPoolSizeMax - usapPoolCount;
Log.i("zygote",
"Delayed USAP Pool refill. New USAPs: " + numUsapsToSpawn);
}
// Disable some VM functionality and reset some system values
// before forking.
ZygoteHooks.preFork();
while (--numUsapsToSpawn >= 0) {
Runnable caller =
Zygote.forkUsap(mUsapPoolSocket, sessionSocketRawFDs, isPriorityRefill);
if (caller != null) {
return caller;
}
}
// Re-enable runtime services for the Zygote. Services for unspecialized app process
// are re-enabled in specializeAppProcess.
ZygoteHooks.postForkCommon();
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
return null;
@@ -358,7 +387,7 @@ class ZygoteServer {
mUsapPoolEnabled = newStatus;
if (newStatus) {
return fillUsapPool(new int[]{ sessionSocket.getFileDescriptor().getInt$() });
return fillUsapPool(new int[]{ sessionSocket.getFileDescriptor().getInt$() }, false);
} else {
Zygote.emptyUsapPool();
return null;
@@ -377,6 +406,8 @@ class ZygoteServer {
socketFDs.add(mZygoteSocket.getFileDescriptor());
peers.add(null);
long usapPoolRefillTriggerTimestamp = INVALID_TIMESTAMP;
while (true) {
fetchUsapPoolPolicyPropsWithMinInterval();
@@ -430,142 +461,192 @@ class ZygoteServer {
}
}
int pollTimeoutMs;
if (usapPoolRefillTriggerTimestamp == INVALID_TIMESTAMP) {
pollTimeoutMs = -1;
} else {
int elapsedTimeMs =
(int) (System.currentTimeMillis() - usapPoolRefillTriggerTimestamp);
if (elapsedTimeMs >= USAP_REFILL_DELAY_MS) {
// Normalize the poll timeout value when the time between one poll event and the
// next pushes us over the delay value. This prevents poll receiving a 0
// timeout value, which would result in it returning immediately.
pollTimeoutMs = -1;
} else {
pollTimeoutMs = USAP_REFILL_DELAY_MS - elapsedTimeMs;
}
}
int pollReturnValue;
try {
Os.poll(pollFDs, -1);
pollReturnValue = Os.poll(pollFDs, pollTimeoutMs);
} catch (ErrnoException ex) {
throw new RuntimeException("poll failed", ex);
}
boolean usapPoolFDRead = false;
UsapPoolRefillAction usapPoolRefillAction = UsapPoolRefillAction.NONE;
if (pollReturnValue == 0) {
// The poll timeout has been exceeded. This only occurs when we have finished the
// USAP pool refill delay period.
while (--pollIndex >= 0) {
if ((pollFDs[pollIndex].revents & POLLIN) == 0) {
continue;
}
usapPoolRefillTriggerTimestamp = INVALID_TIMESTAMP;
usapPoolRefillAction = UsapPoolRefillAction.DELAYED;
if (pollIndex == 0) {
// Zygote server socket
ZygoteConnection newPeer = acceptCommandPeer(abiList);
peers.add(newPeer);
socketFDs.add(newPeer.getFileDescriptor());
} else if (pollIndex < usapPoolEventFDIndex) {
// Session socket accepted from the Zygote server socket
try {
ZygoteConnection connection = peers.get(pollIndex);
final Runnable command = connection.processOneCommand(this);
// TODO (chriswailes): Is this extra check necessary?
if (mIsForkChild) {
// We're in the child. We should always have a command to run at this
// stage if processOneCommand hasn't called "exec".
if (command == null) {
throw new IllegalStateException("command == null");
}
return command;
} else {
// We're in the server - we should never have any commands to run.
if (command != null) {
throw new IllegalStateException("command != null");
}
// We don't know whether the remote side of the socket was closed or
// not until we attempt to read from it from processOneCommand. This
// shows up as a regular POLLIN event in our regular processing loop.
if (connection.isClosedByPeer()) {
connection.closeSocket();
peers.remove(pollIndex);
socketFDs.remove(pollIndex);
}
}
} catch (Exception e) {
if (!mIsForkChild) {
// We're in the server so any exception here is one that has taken place
// pre-fork while processing commands or reading / writing from the
// control socket. Make a loud noise about any such exceptions so that
// we know exactly what failed and why.
Slog.e(TAG, "Exception executing zygote command: ", e);
// Make sure the socket is closed so that the other end knows
// immediately that something has gone wrong and doesn't time out
// waiting for a response.
ZygoteConnection conn = peers.remove(pollIndex);
conn.closeSocket();
socketFDs.remove(pollIndex);
} else {
// We're in the child so any exception caught here has happened post
// fork and before we execute ActivityThread.main (or any other main()
// method). Log the details of the exception and bring down the process.
Log.e(TAG, "Caught post-fork exception in child process.", e);
throw e;
}
} finally {
// Reset the child flag, in the event that the child process is a child-
// zygote. The flag will not be consulted this loop pass after the Runnable
// is returned.
mIsForkChild = false;
}
} else {
// Either the USAP pool event FD or a USAP reporting pipe.
// If this is the event FD the payload will be the number of USAPs removed.
// If this is a reporting pipe FD the payload will be the PID of the USAP
// that was just specialized. The `continue` statements below ensure that
// the messagePayload will always be valid if we complete the try block without
// an exception.
long messagePayload;
try {
byte[] buffer = new byte[Zygote.USAP_MANAGEMENT_MESSAGE_BYTES];
int readBytes = Os.read(pollFDs[pollIndex].fd, buffer, 0, buffer.length);
if (readBytes == Zygote.USAP_MANAGEMENT_MESSAGE_BYTES) {
DataInputStream inputStream =
new DataInputStream(new ByteArrayInputStream(buffer));
messagePayload = inputStream.readLong();
} else {
Log.e(TAG, "Incomplete read from USAP management FD of size "
+ readBytes);
continue;
}
} catch (Exception ex) {
if (pollIndex == usapPoolEventFDIndex) {
Log.e(TAG, "Failed to read from USAP pool event FD: "
+ ex.getMessage());
} else {
Log.e(TAG, "Failed to read from USAP reporting pipe: "
+ ex.getMessage());
}
} else {
boolean usapPoolFDRead = false;
while (--pollIndex >= 0) {
if ((pollFDs[pollIndex].revents & POLLIN) == 0) {
continue;
}
if (pollIndex > usapPoolEventFDIndex) {
Zygote.removeUsapTableEntry((int) messagePayload);
}
if (pollIndex == 0) {
// Zygote server socket
usapPoolFDRead = true;
ZygoteConnection newPeer = acceptCommandPeer(abiList);
peers.add(newPeer);
socketFDs.add(newPeer.getFileDescriptor());
} else if (pollIndex < usapPoolEventFDIndex) {
// Session socket accepted from the Zygote server socket
try {
ZygoteConnection connection = peers.get(pollIndex);
final Runnable command = connection.processOneCommand(this);
// TODO (chriswailes): Is this extra check necessary?
if (mIsForkChild) {
// We're in the child. We should always have a command to run at
// this stage if processOneCommand hasn't called "exec".
if (command == null) {
throw new IllegalStateException("command == null");
}
return command;
} else {
// We're in the server - we should never have any commands to run.
if (command != null) {
throw new IllegalStateException("command != null");
}
// We don't know whether the remote side of the socket was closed or
// not until we attempt to read from it from processOneCommand. This
// shows up as a regular POLLIN event in our regular processing
// loop.
if (connection.isClosedByPeer()) {
connection.closeSocket();
peers.remove(pollIndex);
socketFDs.remove(pollIndex);
}
}
} catch (Exception e) {
if (!mIsForkChild) {
// We're in the server so any exception here is one that has taken
// place pre-fork while processing commands or reading / writing
// from the control socket. Make a loud noise about any such
// exceptions so that we know exactly what failed and why.
Slog.e(TAG, "Exception executing zygote command: ", e);
// Make sure the socket is closed so that the other end knows
// immediately that something has gone wrong and doesn't time out
// waiting for a response.
ZygoteConnection conn = peers.remove(pollIndex);
conn.closeSocket();
socketFDs.remove(pollIndex);
} else {
// We're in the child so any exception caught here has happened post
// fork and before we execute ActivityThread.main (or any other
// main() method). Log the details of the exception and bring down
// the process.
Log.e(TAG, "Caught post-fork exception in child process.", e);
throw e;
}
} finally {
// Reset the child flag, in the event that the child process is a child-
// zygote. The flag will not be consulted this loop pass after the
// Runnable is returned.
mIsForkChild = false;
}
} else {
// Either the USAP pool event FD or a USAP reporting pipe.
// If this is the event FD the payload will be the number of USAPs removed.
// If this is a reporting pipe FD the payload will be the PID of the USAP
// that was just specialized. The `continue` statements below ensure that
// the messagePayload will always be valid if we complete the try block
// without an exception.
long messagePayload;
try {
byte[] buffer = new byte[Zygote.USAP_MANAGEMENT_MESSAGE_BYTES];
int readBytes =
Os.read(pollFDs[pollIndex].fd, buffer, 0, buffer.length);
if (readBytes == Zygote.USAP_MANAGEMENT_MESSAGE_BYTES) {
DataInputStream inputStream =
new DataInputStream(new ByteArrayInputStream(buffer));
messagePayload = inputStream.readLong();
} else {
Log.e(TAG, "Incomplete read from USAP management FD of size "
+ readBytes);
continue;
}
} catch (Exception ex) {
if (pollIndex == usapPoolEventFDIndex) {
Log.e(TAG, "Failed to read from USAP pool event FD: "
+ ex.getMessage());
} else {
Log.e(TAG, "Failed to read from USAP reporting pipe: "
+ ex.getMessage());
}
continue;
}
if (pollIndex > usapPoolEventFDIndex) {
Zygote.removeUsapTableEntry((int) messagePayload);
}
usapPoolFDRead = true;
}
}
if (usapPoolFDRead) {
int usapPoolCount = Zygote.getUsapPoolCount();
if (usapPoolCount < mUsapPoolSizeMin) {
// Immediate refill
usapPoolRefillAction = UsapPoolRefillAction.IMMEDIATE;
} else if (mUsapPoolSizeMax - usapPoolCount >= mUsapPoolRefillThreshold) {
// Delayed refill
usapPoolRefillTriggerTimestamp = System.currentTimeMillis();
}
}
}
// Check to see if the USAP pool needs to be refilled.
if (usapPoolFDRead) {
if (usapPoolRefillAction != UsapPoolRefillAction.NONE) {
int[] sessionSocketRawFDs =
socketFDs.subList(1, socketFDs.size())
.stream()
.mapToInt(FileDescriptor::getInt$)
.toArray();
final Runnable command = fillUsapPool(sessionSocketRawFDs);
final boolean isPriorityRefill =
usapPoolRefillAction == UsapPoolRefillAction.IMMEDIATE;
final Runnable command =
fillUsapPool(sessionSocketRawFDs, isPriorityRefill);
if (command != null) {
return command;
} else if (isPriorityRefill) {
// Schedule a delayed refill to finish refilling the pool.
usapPoolRefillTriggerTimestamp = System.currentTimeMillis();
}
}
}

View File

@@ -169,6 +169,15 @@ static int gUsapPoolEventFD = -1;
*/
static constexpr int USAP_POOL_SIZE_MAX_LIMIT = 100;
/** The numeric value for the maximum priority a process may possess. */
static constexpr int PROCESS_PRIORITY_MAX = -20;
/** The numeric value for the minimum priority a process may possess. */
static constexpr int PROCESS_PRIORITY_MIN = 19;
/** The numeric value for the normal priority a process should have. */
static constexpr int PROCESS_PRIORITY_DEFAULT = 0;
/**
* A helper class containing accounting information for USAPs.
*/
@@ -893,7 +902,8 @@ static void ClearUsapTable() {
// Utility routine to fork a process from the zygote.
static pid_t ForkCommon(JNIEnv* env, bool is_system_server,
const std::vector<int>& fds_to_close,
const std::vector<int>& fds_to_ignore) {
const std::vector<int>& fds_to_ignore,
bool is_priority_fork) {
SetSignalHandlers();
// Curry a failure function.
@@ -926,6 +936,12 @@ static pid_t ForkCommon(JNIEnv* env, bool is_system_server,
pid_t pid = fork();
if (pid == 0) {
if (is_priority_fork) {
setpriority(PRIO_PROCESS, 0, PROCESS_PRIORITY_MAX);
} else {
setpriority(PRIO_PROCESS, 0, PROCESS_PRIORITY_MIN);
}
// The child process.
PreApplicationInit();
@@ -1123,6 +1139,9 @@ static void SpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray gids,
env->CallStaticVoidMethod(gZygoteClass, gCallPostForkChildHooks, runtime_flags,
is_system_server, is_child_zygote, managed_instruction_set);
// Reset the process priority to the default value.
setpriority(PRIO_PROCESS, 0, PROCESS_PRIORITY_DEFAULT);
if (env->ExceptionCheck()) {
fail_fn("Error calling post fork hooks.");
}
@@ -1360,7 +1379,7 @@ static jint com_android_internal_os_Zygote_nativeForkAndSpecialize(
fds_to_ignore.push_back(gUsapPoolEventFD);
}
pid_t pid = ForkCommon(env, false, fds_to_close, fds_to_ignore);
pid_t pid = ForkCommon(env, false, fds_to_close, fds_to_ignore, true);
if (pid == 0) {
SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits,
@@ -1387,7 +1406,8 @@ static jint com_android_internal_os_Zygote_nativeForkSystemServer(
pid_t pid = ForkCommon(env, true,
fds_to_close,
fds_to_ignore);
fds_to_ignore,
true);
if (pid == 0) {
SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits,
permitted_capabilities, effective_capabilities,
@@ -1429,13 +1449,15 @@ static jint com_android_internal_os_Zygote_nativeForkSystemServer(
* zygote in managed code.
* @param managed_session_socket_fds A list of anonymous session sockets that must be ignored by
* the FD hygiene code and automatically "closed" in the new USAP.
* @param is_priority_fork Controls the nice level assigned to the newly created process
* @return
*/
static jint com_android_internal_os_Zygote_nativeForkUsap(JNIEnv* env,
jclass,
jint read_pipe_fd,
jint write_pipe_fd,
jintArray managed_session_socket_fds) {
jintArray managed_session_socket_fds,
jboolean is_priority_fork) {
std::vector<int> fds_to_close(MakeUsapPipeReadFDVector()),
fds_to_ignore(fds_to_close);
@@ -1457,7 +1479,8 @@ static jint com_android_internal_os_Zygote_nativeForkUsap(JNIEnv* env,
fds_to_ignore.push_back(write_pipe_fd);
fds_to_ignore.insert(fds_to_ignore.end(), session_socket_fds.begin(), session_socket_fds.end());
pid_t usap_pid = ForkCommon(env, /* is_system_server= */ false, fds_to_close, fds_to_ignore);
pid_t usap_pid = ForkCommon(env, /* is_system_server= */ false, fds_to_close, fds_to_ignore,
is_priority_fork == JNI_TRUE);
if (usap_pid != 0) {
++gUsapPoolCount;
@@ -1678,6 +1701,10 @@ static jboolean com_android_internal_os_Zygote_nativeDisableExecuteOnly(JNIEnv*
return dl_iterate_phdr(disable_execute_only, nullptr) == 0;
}
static void com_android_internal_os_Zygote_nativeBoostUsapPriority(JNIEnv* env, jclass) {
setpriority(PRIO_PROCESS, 0, PROCESS_PRIORITY_MAX);
}
static const JNINativeMethod gMethods[] = {
{ "nativeForkAndSpecialize",
"(II[II[[IILjava/lang/String;Ljava/lang/String;[I[IZLjava/lang/String;Ljava/lang/String;)I",
@@ -1690,7 +1717,7 @@ static const JNINativeMethod gMethods[] = {
(void *) com_android_internal_os_Zygote_nativePreApplicationInit },
{ "nativeInstallSeccompUidGidFilter", "(II)V",
(void *) com_android_internal_os_Zygote_nativeInstallSeccompUidGidFilter },
{ "nativeForkUsap", "(II[I)I",
{ "nativeForkUsap", "(II[IZ)I",
(void *) com_android_internal_os_Zygote_nativeForkUsap },
{ "nativeSpecializeAppProcess",
"(II[II[[IILjava/lang/String;Ljava/lang/String;ZLjava/lang/String;Ljava/lang/String;)V",
@@ -1708,7 +1735,9 @@ static const JNINativeMethod gMethods[] = {
{ "nativeEmptyUsapPool", "()V",
(void *) com_android_internal_os_Zygote_nativeEmptyUsapPool },
{ "nativeDisableExecuteOnly", "()Z",
(void *) com_android_internal_os_Zygote_nativeDisableExecuteOnly }
(void *) com_android_internal_os_Zygote_nativeDisableExecuteOnly },
{ "nativeBoostUsapPriority", "()V",
(void* ) com_android_internal_os_Zygote_nativeBoostUsapPriority }
};
int register_com_android_internal_os_Zygote(JNIEnv* env) {