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

Commit 52646191 authored by Bart Van Assche's avatar Bart Van Assche
Browse files

libhealthloop: Reduce the number of ScheduleBatteryUpdate() calls



Instead of calling ScheduleBatteryUpdate() every time a uevent has been
received, only call it after the netlink socket receive buffer has been
drained. This change is safe because the contents of the power supply
uevent messages is ignored.

A subtle change in this CL is that an additional call to
uevent_kernel_multicast_recv() is introduced after all the receive
buffer has been drained. In case of a receive buffer overflow, this
extra call will receive and clear the socket error (sk_err).

Bug: 362986353
Change-Id: Ic1c489dde3338f0142def743b4cd654363517486
Signed-off-by: default avatarBart Van Assche <bvanassche@google.com>
parent 1f2a9d0b
Loading
Loading
Loading
Loading
+31 −22
Original line number Diff line number Diff line
@@ -43,6 +43,8 @@ namespace android {
namespace hardware {
namespace health {

static constexpr uint32_t kUeventMsgLen = 2048;

HealthLoop::HealthLoop() {
    InitHealthdConfig(&healthd_config_);
    awake_poll_interval_ = -1;
@@ -121,32 +123,39 @@ void HealthLoop::PeriodicChores() {
    ScheduleBatteryUpdate();
}

#define UEVENT_MSG_LEN 2048
void HealthLoop::UeventEvent(uint32_t /*epevents*/) {
    // No need to lock because uevent_fd_ is guaranteed to be initialized.

    char msg[UEVENT_MSG_LEN + 2];
    char* cp;
    int n;

    n = uevent_kernel_multicast_recv(uevent_fd_, msg, UEVENT_MSG_LEN);
    if (n <= 0) return;
    if (n >= UEVENT_MSG_LEN) /* overflow -- discard */
        return;
// Returns true if and only if the battery statistics should be updated.
bool HealthLoop::RecvUevents() {
    bool update_stats = false;
    for (;;) {
        char msg[kUeventMsgLen + 2];
        int n = uevent_kernel_multicast_recv(uevent_fd_, msg, kUeventMsgLen);
        if (n <= 0) return update_stats;
        if (n >= kUeventMsgLen) {
            // too long -- discard
            continue;
        }
        if (update_stats) {
            continue;
        }

        msg[n] = '\0';
        msg[n + 1] = '\0';
    cp = msg;

    while (*cp) {
        if (!strcmp(cp, "SUBSYSTEM=power_supply")) {
            ScheduleBatteryUpdate();
        for (char* cp = msg; *cp;) {
            if (strcmp(cp, "SUBSYSTEM=power_supply") == 0) {
                update_stats = true;
                break;
            }

            /* advance to after the next \0 */
        while (*cp++)
            ;
            while (*cp++) {
            }
        }
    }
}

void HealthLoop::UeventEvent(uint32_t /*epevents*/) {
    if (RecvUevents()) {
        ScheduleBatteryUpdate();
    }
}

+1 −0
Original line number Diff line number Diff line
@@ -93,6 +93,7 @@ class HealthLoop {
    void WakeAlarmInit();
    void WakeAlarmEvent(uint32_t);
    void UeventInit();
    bool RecvUevents();
    void UeventEvent(uint32_t);
    void WakeAlarmSetInterval(int interval);
    void PeriodicChores();