Skip to content

Commit

Permalink
Batch up uevent notifications
Browse files Browse the repository at this point in the history
Uevent notifications come in bursts especially at boot when we're
iterating over all devices. This batches the reports to Erlang up so
that there are significantly fewer context switches.

On a simple RPi0 W application, this trims 1.5 seconds off the boot time.
  • Loading branch information
fhunleth committed Mar 23, 2019
1 parent 47bcc5e commit 9e50a29
Showing 1 changed file with 20 additions and 8 deletions.
28 changes: 20 additions & 8 deletions src/uevent.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,12 @@ static int nl_uevent_process_one(struct mnl_socket *nl_uevent, char *resp)
{
char nlbuf[8192]; // See MNL_SOCKET_BUFFER_SIZE
int bytecount = mnl_socket_recvfrom(nl_uevent, nlbuf, sizeof(nlbuf));
if (bytecount <= 0)
err(EXIT_FAILURE, "mnl_socket_recvfrom");
if (bytecount <= 0) {
if (errno == EAGAIN)
return -1;
else
err(EXIT_FAILURE, "mnl_socket_recvfrom");
}

char *str = nlbuf;
char *str_end = str + bytecount;
Expand Down Expand Up @@ -207,15 +211,23 @@ static int nl_uevent_process_one(struct mnl_socket *nl_uevent, char *resp)

static void nl_uevent_process_all(struct mnl_socket *nl_uevent)
{
// Erlang response processing
// Erlang response buffer
char resp[8192];
int resp_index;
size_t resp_index;

// Process uevents until there aren't any more or we're
// within 1K of the end. This is pretty conservative since
// the Erlang reports looks like they're nearly always < 200 bytes.
for (resp_index = 0; resp_index < sizeof(resp) - 1024;) {
int bytes_added = nl_uevent_process_one(nl_uevent, &resp[resp_index]);
if (bytes_added < 0)
break;

resp_index = nl_uevent_process_one(nl_uevent, resp);
if (resp_index <= 0)
return;
resp_index += bytes_added;
}

write_all(resp, resp_index);
if (resp_index > 0)
write_all(resp, resp_index);
}

static int filter(const struct dirent *dirp)
Expand Down

0 comments on commit 9e50a29

Please sign in to comment.