Skip to content
This repository has been archived by the owner on Nov 8, 2023. It is now read-only.

Commit

Permalink
init: Prevent spin loop while waiting for exec or property
Browse files Browse the repository at this point in the history
Currently, when we are waiting for an exec service or a property, if
there are either any services to be restarted or any more commands to
be run, we set the epoll_timeout to handle these events.  However, we
don't actually restart and processes or execute any commands while
waiting, so this essentially turns this waiting into a spin loop,
particularly in the common case of having more commands to execute,
where epoll_timeout is set to 0.

The change only sets epoll_timeout if we're not waiting.

Note that the only way to stop waiting for an exec service or a
property is for a signal or property to be delivered to init, which
happens through the epoll fds, so it's safe to indefinitely wait for
epoll to return.

Test: Boot bullhead
Change-Id: Iae3b217eb28182038b464fd39df8e7d27b5e23ff
  • Loading branch information
Tom Cherry committed Mar 24, 2017
1 parent 2af784b commit 77ddcd5
Showing 1 changed file with 12 additions and 10 deletions.
22 changes: 12 additions & 10 deletions init/init.cpp
Expand Up @@ -1322,23 +1322,25 @@ int main(int argc, char** argv) {
am.QueueBuiltinAction(queue_property_triggers_action, "queue_property_triggers");

while (true) {
// By default, sleep until something happens.
int epoll_timeout_ms = -1;

if (!(waiting_for_exec || waiting_for_prop)) {
am.ExecuteOneCommand();
restart_processes();
}
if (!(waiting_for_exec || waiting_for_prop)) {
restart_processes();

// By default, sleep until something happens.
int epoll_timeout_ms = -1;
// If there's a process that needs restarting, wake up in time for that.
if (process_needs_restart_at != 0) {
epoll_timeout_ms = (process_needs_restart_at - time(nullptr)) * 1000;
if (epoll_timeout_ms < 0) epoll_timeout_ms = 0;
}

// If there's a process that needs restarting, wake up in time for that.
if (process_needs_restart_at != 0) {
epoll_timeout_ms = (process_needs_restart_at - time(nullptr)) * 1000;
if (epoll_timeout_ms < 0) epoll_timeout_ms = 0;
// If there's more work to do, wake up again immediately.
if (am.HasMoreCommands()) epoll_timeout_ms = 0;
}

// If there's more work to do, wake up again immediately.
if (am.HasMoreCommands()) epoll_timeout_ms = 0;

epoll_event ev;
int nr = TEMP_FAILURE_RETRY(epoll_wait(epoll_fd, &ev, 1, epoll_timeout_ms));
if (nr == -1) {
Expand Down

0 comments on commit 77ddcd5

Please sign in to comment.