summaryrefslogtreecommitdiff
path: root/logcat/tests/logcat_benchmark.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'logcat/tests/logcat_benchmark.cpp')
-rw-r--r--logcat/tests/logcat_benchmark.cpp133
1 files changed, 133 insertions, 0 deletions
diff --git a/logcat/tests/logcat_benchmark.cpp b/logcat/tests/logcat_benchmark.cpp
new file mode 100644
index 000000000..8d8862889
--- /dev/null
+++ b/logcat/tests/logcat_benchmark.cpp
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2013-2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <benchmark/benchmark.h>
+
+static const char begin[] = "--------- beginning of ";
+
+static void BM_logcat_sorted_order(benchmark::State& state) {
+ FILE* fp;
+
+ if (!state.KeepRunning()) return;
+
+ fp = popen(
+ "logcat -v time -b radio -b events -b system -b main -d 2>/dev/null",
+ "r");
+ if (!fp) return;
+
+ class timestamp {
+ private:
+ int month;
+ int day;
+ int hour;
+ int minute;
+ int second;
+ int millisecond;
+ bool ok;
+
+ public:
+ void init(const char* buffer) {
+ ok = false;
+ if (buffer != NULL) {
+ ok = sscanf(buffer, "%d-%d %d:%d:%d.%d ", &month, &day, &hour,
+ &minute, &second, &millisecond) == 6;
+ }
+ }
+
+ explicit timestamp(const char* buffer) {
+ init(buffer);
+ }
+
+ bool operator<(timestamp& T) {
+ return !ok || !T.ok || (month < T.month) ||
+ ((month == T.month) &&
+ ((day < T.day) ||
+ ((day == T.day) &&
+ ((hour < T.hour) ||
+ ((hour == T.hour) &&
+ ((minute < T.minute) ||
+ ((minute == T.minute) &&
+ ((second < T.second) ||
+ ((second == T.second) &&
+ (millisecond < T.millisecond))))))))));
+ }
+
+ bool valid(void) {
+ return ok;
+ }
+ } last(NULL);
+
+ char* last_buffer = NULL;
+ char buffer[5120];
+
+ int count = 0;
+ int next_lt_last = 0;
+
+ while (fgets(buffer, sizeof(buffer), fp)) {
+ if (!strncmp(begin, buffer, sizeof(begin) - 1)) {
+ continue;
+ }
+ if (!last.valid()) {
+ free(last_buffer);
+ last_buffer = strdup(buffer);
+ last.init(buffer);
+ }
+ timestamp next(buffer);
+ if (next < last) {
+ if (last_buffer) {
+ fprintf(stderr, "<%s", last_buffer);
+ }
+ fprintf(stderr, ">%s", buffer);
+ ++next_lt_last;
+ }
+ if (next.valid()) {
+ free(last_buffer);
+ last_buffer = strdup(buffer);
+ last.init(buffer);
+ }
+ ++count;
+ }
+ free(last_buffer);
+
+ pclose(fp);
+
+ static const int max_ok = 2;
+
+ // Allow few fails, happens with readers active
+ fprintf(stderr, "%s: %d/%d out of order entries\n",
+ (next_lt_last) ? ((next_lt_last <= max_ok) ? "WARNING" : "ERROR")
+ : "INFO",
+ next_lt_last, count);
+
+ if (next_lt_last > max_ok) {
+ fprintf(stderr, "EXPECT_GE(max_ok=%d, next_lt_last=%d)\n", max_ok,
+ next_lt_last);
+ }
+
+ // sample statistically too small
+ if (count < 100) {
+ fprintf(stderr, "EXPECT_LT(100, count=%d)\n", count);
+ }
+
+ state.KeepRunning();
+}
+BENCHMARK(BM_logcat_sorted_order);
+
+BENCHMARK_MAIN();