SurfaceFlinger: fix OneShotTimer timespec overflow

struct timespec::tv_nsec must be < 1s to be considered as valid
input to sem_clockwait.

Test: interact with device and observe systraces
Bug: 170665374
Change-Id: I4aa5b86cd55fd89adb12cd5a28ce599c8a1c0c93
diff --git a/services/surfaceflinger/Scheduler/OneShotTimer.cpp b/services/surfaceflinger/Scheduler/OneShotTimer.cpp
index 2783800..8e807d6 100644
--- a/services/surfaceflinger/Scheduler/OneShotTimer.cpp
+++ b/services/surfaceflinger/Scheduler/OneShotTimer.cpp
@@ -16,6 +16,8 @@
 
 #include "OneShotTimer.h"
 
+#include <utils/Log.h>
+#include <utils/Timers.h>
 #include <chrono>
 #include <sstream>
 #include <thread>
@@ -29,9 +31,9 @@
 // (tv_sec) is the whole count of seconds. The second (tv_nsec) is the
 // nanosecond part of the count. This function takes care of translation.
 void calculateTimeoutTime(std::chrono::nanoseconds timestamp, timespec* spec) {
-    clock_gettime(CLOCK_MONOTONIC, spec);
-    spec->tv_sec += static_cast<__kernel_time_t>(timestamp.count() / kNsToSeconds);
-    spec->tv_nsec += timestamp.count() % kNsToSeconds;
+    const nsecs_t timeout = systemTime(CLOCK_MONOTONIC) + timestamp.count();
+    spec->tv_sec = static_cast<__kernel_time_t>(timeout / kNsToSeconds);
+    spec->tv_nsec = timeout % kNsToSeconds;
 }
 } // namespace
 
@@ -47,7 +49,8 @@
 }
 
 void OneShotTimer::start() {
-    sem_init(&mSemaphore, 0, 0);
+    int result = sem_init(&mSemaphore, 0, 0);
+    LOG_ALWAYS_FATAL_IF(result, "sem_init failed");
 
     if (!mThread.joinable()) {
         // Only create thread if it has not been created.
@@ -57,11 +60,13 @@
 
 void OneShotTimer::stop() {
     mStopTriggered = true;
-    sem_post(&mSemaphore);
+    int result = sem_post(&mSemaphore);
+    LOG_ALWAYS_FATAL_IF(result, "sem_post failed");
 
     if (mThread.joinable()) {
         mThread.join();
-        sem_destroy(&mSemaphore);
+        result = sem_destroy(&mSemaphore);
+        LOG_ALWAYS_FATAL_IF(result, "sem_destroy failed");
     }
 }
 
@@ -77,7 +82,12 @@
         }
 
         if (state == TimerState::IDLE) {
-            sem_wait(&mSemaphore);
+            int result = sem_wait(&mSemaphore);
+            if (result && errno != EINTR) {
+                std::stringstream ss;
+                ss << "sem_wait failed (" << errno << ")";
+                LOG_ALWAYS_FATAL("%s", ss.str().c_str());
+            }
             continue;
         }
 
@@ -101,7 +111,12 @@
             // Wait for mInterval time for semaphore signal.
             struct timespec ts;
             calculateTimeoutTime(std::chrono::nanoseconds(mInterval), &ts);
-            sem_clockwait(&mSemaphore, CLOCK_MONOTONIC, &ts);
+            int result = sem_clockwait(&mSemaphore, CLOCK_MONOTONIC, &ts);
+            if (result && errno != ETIMEDOUT && errno != EINTR) {
+                std::stringstream ss;
+                ss << "sem_clockwait failed (" << errno << ")";
+                LOG_ALWAYS_FATAL("%s", ss.str().c_str());
+            }
 
             state = checkForResetAndStop(state);
             if (state == TimerState::RESET) {
@@ -135,7 +150,8 @@
 
 void OneShotTimer::reset() {
     mResetTriggered = true;
-    sem_post(&mSemaphore);
+    int result = sem_post(&mSemaphore);
+    LOG_ALWAYS_FATAL_IF(result, "sem_post failed");
 }
 
 std::string OneShotTimer::dump() const {