Loading libsuspend/Android.bp +1 −0 Original line number Original line Diff line number Diff line Loading @@ -14,6 +14,7 @@ cc_library { export_include_dirs: ["include"], export_include_dirs: ["include"], local_include_dirs: ["include"], local_include_dirs: ["include"], shared_libs: [ shared_libs: [ "libbase", "liblog", "liblog", "libcutils", "libcutils", ], ], Loading libsuspend/autosuspend_wakeup_count.cpp +45 −58 Original line number Original line Diff line number Diff line Loading @@ -17,7 +17,6 @@ #define LOG_TAG "libsuspend" #define LOG_TAG "libsuspend" //#define LOG_NDEBUG 0 //#define LOG_NDEBUG 0 #include <errno.h> #include <fcntl.h> #include <fcntl.h> #include <pthread.h> #include <pthread.h> #include <semaphore.h> #include <semaphore.h> Loading @@ -29,22 +28,29 @@ #include <sys/types.h> #include <sys/types.h> #include <unistd.h> #include <unistd.h> #include <log/log.h> #include <android-base/file.h> #include <android-base/logging.h> #include <android-base/strings.h> #include "autosuspend_ops.h" #include "autosuspend_ops.h" #define SYS_POWER_STATE "/sys/power/state" #define SYS_POWER_WAKEUP_COUNT "/sys/power/wakeup_count" #define BASE_SLEEP_TIME 100000 #define BASE_SLEEP_TIME 100000 #define MAX_SLEEP_TIME 60000000 static int state_fd; static int state_fd; static int wakeup_count_fd; static int wakeup_count_fd; using android::base::ReadFdToString; using android::base::Trim; using android::base::WriteStringToFd; static pthread_t suspend_thread; static pthread_t suspend_thread; static sem_t suspend_lockout; static sem_t suspend_lockout; static const char* sleep_state = "mem"; static const char* sleep_state = "mem"; static void (*wakeup_func)(bool success) = NULL; static void (*wakeup_func)(bool success) = NULL; static int sleep_time = BASE_SLEEP_TIME; static int sleep_time = BASE_SLEEP_TIME; static constexpr char sys_power_state[] = "/sys/power/state"; static constexpr char sys_power_wakeup_count[] = "/sys/power/wakeup_count"; static void update_sleep_time(bool success) { static void update_sleep_time(bool success) { if (success) { if (success) { Loading @@ -52,13 +58,10 @@ static void update_sleep_time(bool success) { return; return; } } // double sleep time after each failure up to one minute // double sleep time after each failure up to one minute sleep_time = MIN(sleep_time * 2, 60000000); sleep_time = MIN(sleep_time * 2, MAX_SLEEP_TIME); } } static void* suspend_thread_func(void* arg __attribute__((unused))) { static void* suspend_thread_func(void* arg __attribute__((unused))) { char buf[80]; char wakeup_count[20]; int wakeup_count_len; int ret; int ret; bool success = true; bool success = true; Loading @@ -66,95 +69,84 @@ static void* suspend_thread_func(void* arg __attribute__((unused))) { update_sleep_time(success); update_sleep_time(success); usleep(sleep_time); usleep(sleep_time); success = false; success = false; ALOGV("%s: read wakeup_count", __func__); LOG(VERBOSE) << "read wakeup_count"; lseek(wakeup_count_fd, 0, SEEK_SET); lseek(wakeup_count_fd, 0, SEEK_SET); wakeup_count_len = std::string wakeup_count; TEMP_FAILURE_RETRY(read(wakeup_count_fd, wakeup_count, sizeof(wakeup_count))); if (!ReadFdToString(wakeup_count_fd, &wakeup_count)) { if (wakeup_count_len < 0) { PLOG(ERROR) << "error reading from " << sys_power_wakeup_count; strerror_r(errno, buf, sizeof(buf)); ALOGE("Error reading from %s: %s", SYS_POWER_WAKEUP_COUNT, buf); wakeup_count_len = 0; continue; continue; } } if (!wakeup_count_len) { ALOGE("Empty wakeup count"); wakeup_count = Trim(wakeup_count); if (wakeup_count.empty()) { LOG(ERROR) << "empty wakeup count"; continue; continue; } } ALOGV("%s: wait", __func__); LOG(VERBOSE) << "wait"; ret = sem_wait(&suspend_lockout); ret = sem_wait(&suspend_lockout); if (ret < 0) { if (ret < 0) { strerror_r(errno, buf, sizeof(buf)); PLOG(ERROR) << "error waiting on semaphore"; ALOGE("Error waiting on semaphore: %s", buf); continue; continue; } } ALOGV("%s: write %*s to wakeup_count", __func__, wakeup_count_len, wakeup_count); LOG(VERBOSE) << "write " << wakeup_count << " to wakeup_count"; ret = TEMP_FAILURE_RETRY(write(wakeup_count_fd, wakeup_count, wakeup_count_len)); if (WriteStringToFd(wakeup_count, wakeup_count_fd)) { if (ret < 0) { LOG(VERBOSE) << "write " << sleep_state << " to " << sys_power_state; strerror_r(errno, buf, sizeof(buf)); success = WriteStringToFd(sleep_state, state_fd); ALOGE("Error writing to %s: %s", SYS_POWER_WAKEUP_COUNT, buf); } else { ALOGV("%s: write %s to %s", __func__, sleep_state, SYS_POWER_STATE); ret = TEMP_FAILURE_RETRY(write(state_fd, sleep_state, strlen(sleep_state))); if (ret >= 0) { success = true; } void (*func)(bool success) = wakeup_func; void (*func)(bool success) = wakeup_func; if (func != NULL) { if (func != NULL) { (*func)(success); (*func)(success); } } } else { PLOG(ERROR) << "error writing to " << sys_power_wakeup_count; } } ALOGV("%s: release sem", __func__); LOG(VERBOSE) << "release sem"; ret = sem_post(&suspend_lockout); ret = sem_post(&suspend_lockout); if (ret < 0) { if (ret < 0) { strerror_r(errno, buf, sizeof(buf)); PLOG(ERROR) << "error releasing semaphore"; ALOGE("Error releasing semaphore: %s", buf); } } } } return NULL; return NULL; } } static int autosuspend_wakeup_count_enable(void) { static int autosuspend_wakeup_count_enable(void) { char buf[80]; int ret; int ret; ALOGV("autosuspend_wakeup_count_enable"); LOG(VERBOSE) << "autosuspend_wakeup_count_enable"; ret = sem_post(&suspend_lockout); ret = sem_post(&suspend_lockout); if (ret < 0) { if (ret < 0) { strerror_r(errno, buf, sizeof(buf)); PLOG(ERROR) << "error changing semaphore"; ALOGE("Error changing semaphore: %s", buf); } } ALOGV("autosuspend_wakeup_count_enable done"); LOG(VERBOSE) << "autosuspend_wakeup_count_enable done"; return ret; return ret; } } static int autosuspend_wakeup_count_disable(void) { static int autosuspend_wakeup_count_disable(void) { char buf[80]; int ret; int ret; ALOGV("autosuspend_wakeup_count_disable"); LOG(VERBOSE) << "autosuspend_wakeup_count_disable"; ret = sem_wait(&suspend_lockout); ret = sem_wait(&suspend_lockout); if (ret < 0) { if (ret < 0) { strerror_r(errno, buf, sizeof(buf)); PLOG(ERROR) << "error changing semaphore"; ALOGE("Error changing semaphore: %s", buf); } } ALOGV("autosuspend_wakeup_count_disable done"); LOG(VERBOSE) << "autosuspend_wakeup_count_disable done"; return ret; return ret; } } static void autosuspend_set_wakeup_callback(void (*func)(bool success)) { static void autosuspend_set_wakeup_callback(void (*func)(bool success)) { if (wakeup_func != NULL) { if (wakeup_func != NULL) { ALOGE("Duplicate wakeup callback applied, keeping original"); LOG(ERROR) << "duplicate wakeup callback applied, keeping original"; return; return; } } wakeup_func = func; wakeup_func = func; Loading @@ -168,36 +160,31 @@ struct autosuspend_ops autosuspend_wakeup_count_ops = { struct autosuspend_ops* autosuspend_wakeup_count_init(void) { struct autosuspend_ops* autosuspend_wakeup_count_init(void) { int ret; int ret; char buf[80]; state_fd = TEMP_FAILURE_RETRY(open(SYS_POWER_STATE, O_RDWR)); state_fd = TEMP_FAILURE_RETRY(open(sys_power_state, O_RDWR)); if (state_fd < 0) { if (state_fd < 0) { strerror_r(errno, buf, sizeof(buf)); PLOG(ERROR) << "error opening " << sys_power_state; ALOGE("Error opening %s: %s", SYS_POWER_STATE, buf); goto err_open_state; goto err_open_state; } } wakeup_count_fd = TEMP_FAILURE_RETRY(open(SYS_POWER_WAKEUP_COUNT, O_RDWR)); wakeup_count_fd = TEMP_FAILURE_RETRY(open(sys_power_wakeup_count, O_RDWR)); if (wakeup_count_fd < 0) { if (wakeup_count_fd < 0) { strerror_r(errno, buf, sizeof(buf)); PLOG(ERROR) << "error opening " << sys_power_wakeup_count; ALOGE("Error opening %s: %s", SYS_POWER_WAKEUP_COUNT, buf); goto err_open_wakeup_count; goto err_open_wakeup_count; } } ret = sem_init(&suspend_lockout, 0, 0); ret = sem_init(&suspend_lockout, 0, 0); if (ret < 0) { if (ret < 0) { strerror_r(errno, buf, sizeof(buf)); PLOG(ERROR) << "error creating semaphore"; ALOGE("Error creating semaphore: %s", buf); goto err_sem_init; goto err_sem_init; } } ret = pthread_create(&suspend_thread, NULL, suspend_thread_func, NULL); ret = pthread_create(&suspend_thread, NULL, suspend_thread_func, NULL); if (ret) { if (ret) { strerror_r(ret, buf, sizeof(buf)); LOG(ERROR) << "error creating thread: " << strerror(ret); ALOGE("Error creating thread: %s", buf); goto err_pthread_create; goto err_pthread_create; } } ALOGI("Selected wakeup count"); LOG(INFO) << "selected wakeup count"; return &autosuspend_wakeup_count_ops; return &autosuspend_wakeup_count_ops; err_pthread_create: err_pthread_create: Loading Loading
libsuspend/Android.bp +1 −0 Original line number Original line Diff line number Diff line Loading @@ -14,6 +14,7 @@ cc_library { export_include_dirs: ["include"], export_include_dirs: ["include"], local_include_dirs: ["include"], local_include_dirs: ["include"], shared_libs: [ shared_libs: [ "libbase", "liblog", "liblog", "libcutils", "libcutils", ], ], Loading
libsuspend/autosuspend_wakeup_count.cpp +45 −58 Original line number Original line Diff line number Diff line Loading @@ -17,7 +17,6 @@ #define LOG_TAG "libsuspend" #define LOG_TAG "libsuspend" //#define LOG_NDEBUG 0 //#define LOG_NDEBUG 0 #include <errno.h> #include <fcntl.h> #include <fcntl.h> #include <pthread.h> #include <pthread.h> #include <semaphore.h> #include <semaphore.h> Loading @@ -29,22 +28,29 @@ #include <sys/types.h> #include <sys/types.h> #include <unistd.h> #include <unistd.h> #include <log/log.h> #include <android-base/file.h> #include <android-base/logging.h> #include <android-base/strings.h> #include "autosuspend_ops.h" #include "autosuspend_ops.h" #define SYS_POWER_STATE "/sys/power/state" #define SYS_POWER_WAKEUP_COUNT "/sys/power/wakeup_count" #define BASE_SLEEP_TIME 100000 #define BASE_SLEEP_TIME 100000 #define MAX_SLEEP_TIME 60000000 static int state_fd; static int state_fd; static int wakeup_count_fd; static int wakeup_count_fd; using android::base::ReadFdToString; using android::base::Trim; using android::base::WriteStringToFd; static pthread_t suspend_thread; static pthread_t suspend_thread; static sem_t suspend_lockout; static sem_t suspend_lockout; static const char* sleep_state = "mem"; static const char* sleep_state = "mem"; static void (*wakeup_func)(bool success) = NULL; static void (*wakeup_func)(bool success) = NULL; static int sleep_time = BASE_SLEEP_TIME; static int sleep_time = BASE_SLEEP_TIME; static constexpr char sys_power_state[] = "/sys/power/state"; static constexpr char sys_power_wakeup_count[] = "/sys/power/wakeup_count"; static void update_sleep_time(bool success) { static void update_sleep_time(bool success) { if (success) { if (success) { Loading @@ -52,13 +58,10 @@ static void update_sleep_time(bool success) { return; return; } } // double sleep time after each failure up to one minute // double sleep time after each failure up to one minute sleep_time = MIN(sleep_time * 2, 60000000); sleep_time = MIN(sleep_time * 2, MAX_SLEEP_TIME); } } static void* suspend_thread_func(void* arg __attribute__((unused))) { static void* suspend_thread_func(void* arg __attribute__((unused))) { char buf[80]; char wakeup_count[20]; int wakeup_count_len; int ret; int ret; bool success = true; bool success = true; Loading @@ -66,95 +69,84 @@ static void* suspend_thread_func(void* arg __attribute__((unused))) { update_sleep_time(success); update_sleep_time(success); usleep(sleep_time); usleep(sleep_time); success = false; success = false; ALOGV("%s: read wakeup_count", __func__); LOG(VERBOSE) << "read wakeup_count"; lseek(wakeup_count_fd, 0, SEEK_SET); lseek(wakeup_count_fd, 0, SEEK_SET); wakeup_count_len = std::string wakeup_count; TEMP_FAILURE_RETRY(read(wakeup_count_fd, wakeup_count, sizeof(wakeup_count))); if (!ReadFdToString(wakeup_count_fd, &wakeup_count)) { if (wakeup_count_len < 0) { PLOG(ERROR) << "error reading from " << sys_power_wakeup_count; strerror_r(errno, buf, sizeof(buf)); ALOGE("Error reading from %s: %s", SYS_POWER_WAKEUP_COUNT, buf); wakeup_count_len = 0; continue; continue; } } if (!wakeup_count_len) { ALOGE("Empty wakeup count"); wakeup_count = Trim(wakeup_count); if (wakeup_count.empty()) { LOG(ERROR) << "empty wakeup count"; continue; continue; } } ALOGV("%s: wait", __func__); LOG(VERBOSE) << "wait"; ret = sem_wait(&suspend_lockout); ret = sem_wait(&suspend_lockout); if (ret < 0) { if (ret < 0) { strerror_r(errno, buf, sizeof(buf)); PLOG(ERROR) << "error waiting on semaphore"; ALOGE("Error waiting on semaphore: %s", buf); continue; continue; } } ALOGV("%s: write %*s to wakeup_count", __func__, wakeup_count_len, wakeup_count); LOG(VERBOSE) << "write " << wakeup_count << " to wakeup_count"; ret = TEMP_FAILURE_RETRY(write(wakeup_count_fd, wakeup_count, wakeup_count_len)); if (WriteStringToFd(wakeup_count, wakeup_count_fd)) { if (ret < 0) { LOG(VERBOSE) << "write " << sleep_state << " to " << sys_power_state; strerror_r(errno, buf, sizeof(buf)); success = WriteStringToFd(sleep_state, state_fd); ALOGE("Error writing to %s: %s", SYS_POWER_WAKEUP_COUNT, buf); } else { ALOGV("%s: write %s to %s", __func__, sleep_state, SYS_POWER_STATE); ret = TEMP_FAILURE_RETRY(write(state_fd, sleep_state, strlen(sleep_state))); if (ret >= 0) { success = true; } void (*func)(bool success) = wakeup_func; void (*func)(bool success) = wakeup_func; if (func != NULL) { if (func != NULL) { (*func)(success); (*func)(success); } } } else { PLOG(ERROR) << "error writing to " << sys_power_wakeup_count; } } ALOGV("%s: release sem", __func__); LOG(VERBOSE) << "release sem"; ret = sem_post(&suspend_lockout); ret = sem_post(&suspend_lockout); if (ret < 0) { if (ret < 0) { strerror_r(errno, buf, sizeof(buf)); PLOG(ERROR) << "error releasing semaphore"; ALOGE("Error releasing semaphore: %s", buf); } } } } return NULL; return NULL; } } static int autosuspend_wakeup_count_enable(void) { static int autosuspend_wakeup_count_enable(void) { char buf[80]; int ret; int ret; ALOGV("autosuspend_wakeup_count_enable"); LOG(VERBOSE) << "autosuspend_wakeup_count_enable"; ret = sem_post(&suspend_lockout); ret = sem_post(&suspend_lockout); if (ret < 0) { if (ret < 0) { strerror_r(errno, buf, sizeof(buf)); PLOG(ERROR) << "error changing semaphore"; ALOGE("Error changing semaphore: %s", buf); } } ALOGV("autosuspend_wakeup_count_enable done"); LOG(VERBOSE) << "autosuspend_wakeup_count_enable done"; return ret; return ret; } } static int autosuspend_wakeup_count_disable(void) { static int autosuspend_wakeup_count_disable(void) { char buf[80]; int ret; int ret; ALOGV("autosuspend_wakeup_count_disable"); LOG(VERBOSE) << "autosuspend_wakeup_count_disable"; ret = sem_wait(&suspend_lockout); ret = sem_wait(&suspend_lockout); if (ret < 0) { if (ret < 0) { strerror_r(errno, buf, sizeof(buf)); PLOG(ERROR) << "error changing semaphore"; ALOGE("Error changing semaphore: %s", buf); } } ALOGV("autosuspend_wakeup_count_disable done"); LOG(VERBOSE) << "autosuspend_wakeup_count_disable done"; return ret; return ret; } } static void autosuspend_set_wakeup_callback(void (*func)(bool success)) { static void autosuspend_set_wakeup_callback(void (*func)(bool success)) { if (wakeup_func != NULL) { if (wakeup_func != NULL) { ALOGE("Duplicate wakeup callback applied, keeping original"); LOG(ERROR) << "duplicate wakeup callback applied, keeping original"; return; return; } } wakeup_func = func; wakeup_func = func; Loading @@ -168,36 +160,31 @@ struct autosuspend_ops autosuspend_wakeup_count_ops = { struct autosuspend_ops* autosuspend_wakeup_count_init(void) { struct autosuspend_ops* autosuspend_wakeup_count_init(void) { int ret; int ret; char buf[80]; state_fd = TEMP_FAILURE_RETRY(open(SYS_POWER_STATE, O_RDWR)); state_fd = TEMP_FAILURE_RETRY(open(sys_power_state, O_RDWR)); if (state_fd < 0) { if (state_fd < 0) { strerror_r(errno, buf, sizeof(buf)); PLOG(ERROR) << "error opening " << sys_power_state; ALOGE("Error opening %s: %s", SYS_POWER_STATE, buf); goto err_open_state; goto err_open_state; } } wakeup_count_fd = TEMP_FAILURE_RETRY(open(SYS_POWER_WAKEUP_COUNT, O_RDWR)); wakeup_count_fd = TEMP_FAILURE_RETRY(open(sys_power_wakeup_count, O_RDWR)); if (wakeup_count_fd < 0) { if (wakeup_count_fd < 0) { strerror_r(errno, buf, sizeof(buf)); PLOG(ERROR) << "error opening " << sys_power_wakeup_count; ALOGE("Error opening %s: %s", SYS_POWER_WAKEUP_COUNT, buf); goto err_open_wakeup_count; goto err_open_wakeup_count; } } ret = sem_init(&suspend_lockout, 0, 0); ret = sem_init(&suspend_lockout, 0, 0); if (ret < 0) { if (ret < 0) { strerror_r(errno, buf, sizeof(buf)); PLOG(ERROR) << "error creating semaphore"; ALOGE("Error creating semaphore: %s", buf); goto err_sem_init; goto err_sem_init; } } ret = pthread_create(&suspend_thread, NULL, suspend_thread_func, NULL); ret = pthread_create(&suspend_thread, NULL, suspend_thread_func, NULL); if (ret) { if (ret) { strerror_r(ret, buf, sizeof(buf)); LOG(ERROR) << "error creating thread: " << strerror(ret); ALOGE("Error creating thread: %s", buf); goto err_pthread_create; goto err_pthread_create; } } ALOGI("Selected wakeup count"); LOG(INFO) << "selected wakeup count"; return &autosuspend_wakeup_count_ops; return &autosuspend_wakeup_count_ops; err_pthread_create: err_pthread_create: Loading