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 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