1 /*
2 * Copyright (C) 2013-2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20
21 #include <benchmark/benchmark.h>
22
23 static const char begin[] = "--------- beginning of ";
24
BM_logcat_sorted_order(benchmark::State & state)25 static void BM_logcat_sorted_order(benchmark::State& state) {
26 FILE* fp;
27
28 if (!state.KeepRunning()) return;
29
30 fp = popen(
31 "logcat -v time -b radio -b events -b system -b main -d 2>/dev/null",
32 "r");
33 if (!fp) return;
34
35 class timestamp {
36 private:
37 int month;
38 int day;
39 int hour;
40 int minute;
41 int second;
42 int millisecond;
43 bool ok;
44
45 public:
46 void init(const char* buffer) {
47 ok = false;
48 if (buffer != NULL) {
49 ok = sscanf(buffer, "%d-%d %d:%d:%d.%d ", &month, &day, &hour,
50 &minute, &second, &millisecond) == 6;
51 }
52 }
53
54 explicit timestamp(const char* buffer) {
55 init(buffer);
56 }
57
58 bool operator<(timestamp& T) {
59 return !ok || !T.ok || (month < T.month) ||
60 ((month == T.month) &&
61 ((day < T.day) ||
62 ((day == T.day) &&
63 ((hour < T.hour) ||
64 ((hour == T.hour) &&
65 ((minute < T.minute) ||
66 ((minute == T.minute) &&
67 ((second < T.second) ||
68 ((second == T.second) &&
69 (millisecond < T.millisecond))))))))));
70 }
71
72 bool valid(void) {
73 return ok;
74 }
75 } last(NULL);
76
77 char* last_buffer = NULL;
78 char buffer[5120];
79
80 int count = 0;
81 int next_lt_last = 0;
82
83 while (fgets(buffer, sizeof(buffer), fp)) {
84 if (!strncmp(begin, buffer, sizeof(begin) - 1)) {
85 continue;
86 }
87 if (!last.valid()) {
88 free(last_buffer);
89 last_buffer = strdup(buffer);
90 last.init(buffer);
91 }
92 timestamp next(buffer);
93 if (next < last) {
94 if (last_buffer) {
95 fprintf(stderr, "<%s", last_buffer);
96 }
97 fprintf(stderr, ">%s", buffer);
98 ++next_lt_last;
99 }
100 if (next.valid()) {
101 free(last_buffer);
102 last_buffer = strdup(buffer);
103 last.init(buffer);
104 }
105 ++count;
106 }
107 free(last_buffer);
108
109 pclose(fp);
110
111 static const int max_ok = 2;
112
113 // Allow few fails, happens with readers active
114 fprintf(stderr, "%s: %d/%d out of order entries\n",
115 (next_lt_last) ? ((next_lt_last <= max_ok) ? "WARNING" : "ERROR")
116 : "INFO",
117 next_lt_last, count);
118
119 if (next_lt_last > max_ok) {
120 fprintf(stderr, "EXPECT_GE(max_ok=%d, next_lt_last=%d)\n", max_ok,
121 next_lt_last);
122 }
123
124 // sample statistically too small
125 if (count < 100) {
126 fprintf(stderr, "EXPECT_LT(100, count=%d)\n", count);
127 }
128
129 state.KeepRunning();
130 }
131 BENCHMARK(BM_logcat_sorted_order);
132
133 BENCHMARK_MAIN();
134