From 9097114e7154944c70c9caf4318cd5025a2ccee8 Mon Sep 17 00:00:00 2001 From: Jelle Foks Date: Mon, 22 Apr 2024 11:26:19 -0700 Subject: [PATCH] [Android] Fix CPU spinning of StarboardMain. (#3027) An integer overflow in a downconversion resulted in a negative timeout being used for the ALooper_pollAll call. This fixes that, and adds a ALooper_wake when a non-system event is injectet. b/335901937 (cherry picked from commit ed27e83d758dfa7227eb6d9cea075fa56fac819e) --- starboard/android/shared/application_android.cc | 17 +++++++++++++---- starboard/android/shared/application_android.h | 7 ++++++- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/starboard/android/shared/application_android.cc b/starboard/android/shared/application_android.cc index 8d56fa1f964f..74aae9220b3c 100644 --- a/starboard/android/shared/application_android.cc +++ b/starboard/android/shared/application_android.cc @@ -100,6 +100,7 @@ ApplicationAndroid::ApplicationAndroid(ALooper* looper) QueueApplication(sb_event_handle_callback), #endif // SB_API_VERSION >= 15 last_is_accessibility_high_contrast_text_enabled_(false) { + handle_system_events_.store(true); // Initialize Time Zone early so that local time works correctly. // Called once here to help SbTimeZoneGet*Name() tzset(); @@ -208,19 +209,27 @@ bool ApplicationAndroid::DestroyWindow(SbWindow window) { Event* ApplicationAndroid::WaitForSystemEventWithTimeout(SbTime time) { // Limit the polling time in case some non-system event is injected. - const int kMaxPollingTimeMillisecond = 10; + const int kMaxPollingTimeMillisecond = 1000; // Convert from microseconds to milliseconds, taking the ceiling value. // If we take the floor, or round, then we end up busy looping every time // the next event time is less than one millisecond. +<<<<<<< HEAD int timeout_millis = (time + kSbTimeMillisecond - 1) / kSbTimeMillisecond; +======= + int timeout_millis = + (time < + std::min(kSbInt64Max - 1000, 1000 * static_cast(INT_MAX - 1))) + ? (time + 1000 - 1) / 1000 + : INT_MAX; +>>>>>>> ed27e83d758 ([Android] Fix CPU spinning of StarboardMain. (#3027)) int looper_events; - int ident = ALooper_pollAll( + int ident = ALooper_pollOnce( std::min(std::max(timeout_millis, 0), kMaxPollingTimeMillisecond), NULL, &looper_events, NULL); // Ignore new system events while processing one. - handle_system_events_ = false; + handle_system_events_.store(false); switch (ident) { case kLooperIdAndroidCommand: @@ -231,7 +240,7 @@ Event* ApplicationAndroid::WaitForSystemEventWithTimeout(SbTime time) { break; } - handle_system_events_ = true; + handle_system_events_.store(true); // Always return NULL since we already dispatched our own system events. return NULL; diff --git a/starboard/android/shared/application_android.h b/starboard/android/shared/application_android.h index bca3b1f47da2..b6438d435829 100644 --- a/starboard/android/shared/application_android.h +++ b/starboard/android/shared/application_android.h @@ -128,8 +128,13 @@ class ApplicationAndroid void OnSuspend() override; // --- QueueApplication overrides --- +<<<<<<< HEAD bool MayHaveSystemEvents() override { return handle_system_events_; } Event* WaitForSystemEventWithTimeout(SbTime time) override; +======= + bool MayHaveSystemEvents() override { return handle_system_events_.load(); } + Event* WaitForSystemEventWithTimeout(int64_t time) override; +>>>>>>> ed27e83d758 ([Android] Fix CPU spinning of StarboardMain. (#3027)) void WakeSystemEventWait() override; private: @@ -144,7 +149,7 @@ class ApplicationAndroid // In certain situations, the Starboard thread should not try to process new // system events (e.g. while one is being processed). - bool handle_system_events_ = true; + atomic_bool handle_system_events_; // Synchronization for commands that change availability of Android resources // such as the input and/or native_window_.