logd: Find log time for arbitrary time to tail

- prototype to evaluate the increase in complexity or
  performance impact.

Change-Id: I4e815d74c023092fbb75055d260f75de57ad6522
diff --git a/logd/LogReader.cpp b/logd/LogReader.cpp
index 29bfbda..60a3507 100644
--- a/logd/LogReader.cpp
+++ b/logd/LogReader.cpp
@@ -92,14 +92,59 @@
     }
 
     // Convert realtime to monotonic time
-    if (start != log_time::EPOCH) {
-        log_time real(CLOCK_REALTIME);
-        log_time monotonic(CLOCK_MONOTONIC);
-        real -= monotonic; // I know this is not 100% accurate
-        start -= real;
-    }
     if (start == log_time::EPOCH) {
         start = LogTimeEntry::EPOCH;
+    } else {
+        class LogFindStart {
+            const pid_t mPid;
+            const unsigned mLogMask;
+            bool startTimeSet;
+            log_time &start;
+            log_time last;
+
+        public:
+            LogFindStart(unsigned logMask, pid_t pid, log_time &start)
+                    : mPid(pid)
+                    , mLogMask(logMask)
+                    , startTimeSet(false)
+                    , start(start)
+                    , last(LogTimeEntry::EPOCH)
+            { }
+
+            static bool callback(const LogBufferElement *element, void *obj) {
+                LogFindStart *me = reinterpret_cast<LogFindStart *>(obj);
+                if (!me->startTimeSet
+                        && (!me->mPid || (me->mPid == element->getPid()))
+                        && (me->mLogMask & (1 << element->getLogId()))) {
+                    if (me->start == element->getRealTime()) {
+                        me->start = element->getMonotonicTime();
+                        me->startTimeSet = true;
+                    } else {
+                        if (me->start < element->getRealTime()) {
+                            me->start = me->last;
+                            me->startTimeSet = true;
+                        }
+                        me->last = element->getMonotonicTime();
+                    }
+                }
+                return false;
+            }
+
+            bool found() { return startTimeSet; }
+        } logFindStart(logMask, pid, start);
+
+        logbuf().flushTo(cli, LogTimeEntry::EPOCH,
+                         FlushCommand::hasReadLogs(cli),
+                         logFindStart.callback, &logFindStart);
+
+        if (!logFindStart.found()) {
+            if (nonBlock) {
+                doSocketDelete(cli);
+                return false;
+            }
+            log_time now(CLOCK_MONOTONIC);
+            start = now;
+        }
     }
 
     FlushCommand command(*this, nonBlock, tail, logMask, pid, start);