1 /* 2 * 3 * Copyright 2017, The Android Open Source Project 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 #ifndef ANDROID_TYPED_LOGGER_H 19 #define ANDROID_TYPED_LOGGER_H 20 21 #include <media/nbaio/NBLog.h> 22 #include <algorithm> 23 24 /* 25 Fowler-Noll-Vo (FNV-1a) hash function for the file name. 26 Hashes at compile time. FNV-1a iterative function: 27 28 hash = offset_basis 29 for each byte to be hashed 30 hash = hash xor byte 31 hash = hash * FNV_prime 32 return hash 33 34 offset_basis and FNV_prime values depend on the size of the hash output 35 Following values are defined by FNV and should not be changed arbitrarily 36 */ 37 38 template<typename T> 39 constexpr T offset_basis(); 40 41 template<typename T> 42 constexpr T FNV_prime(); 43 44 template<> 45 constexpr uint32_t offset_basis<uint32_t>() { 46 return 2166136261u; 47 } 48 49 template<> 50 constexpr uint32_t FNV_prime<uint32_t>() { 51 return 16777619u; 52 } 53 54 template<> 55 constexpr uint64_t offset_basis<uint64_t>() { 56 return 14695981039346656037ull; 57 } 58 59 template<> 60 constexpr uint64_t FNV_prime<uint64_t>() { 61 return 1099511628211ull; 62 } 63 64 template <typename T, size_t n> 65 constexpr T fnv1a(const char (&file)[n], int i = n - 1) { 66 return i == -1 ? offset_basis<T>() : (fnv1a<T>(file, i - 1) ^ file[i]) * FNV_prime<T>(); 67 } 68 69 template <size_t n> 70 constexpr uint64_t hash(const char (&file)[n], uint32_t line) { 71 // Line numbers over or equal to 2^16 are clamped to 2^16 - 1. This way increases collisions 72 // compared to wrapping around, but is easy to identify because it doesn't produce aliasing. 73 // It's a very unlikely case anyways. 74 return ((fnv1a<uint64_t>(file) << 16) ^ ((fnv1a<uint64_t>(file) >> 32) & 0xFFFF0000)) | 75 std::min(line, 0xFFFFu); 76 } 77 78 // TODO Permit disabling of logging at compile-time. 79 80 // TODO A non-nullptr dummy implementation that is a nop would be faster than checking for nullptr 81 // in the case when logging is enabled at compile-time and enabled at runtime, but it might be 82 // slower than nullptr check when logging is enabled at compile-time and disabled at runtime. 83 84 // Write formatted entry to log 85 #define LOGT(fmt, ...) do { NBLog::Writer *x = tlNBLogWriter; if (x != nullptr) \ 86 x->logFormat((fmt), hash(__FILE__, __LINE__), ##__VA_ARGS__); } \ 87 while (0) 88 89 // Write histogram timestamp entry 90 #define LOG_HIST_TS() do { NBLog::Writer *x = tlNBLogWriter; if (x != nullptr) \ 91 x->logEventHistTs(NBLog::EVENT_HISTOGRAM_ENTRY_TS, hash(__FILE__, __LINE__)); } while(0) 92 93 // Record that audio was turned on/off 94 #define LOG_AUDIO_STATE() do { NBLog::Writer *x = tlNBLogWriter; if (x != nullptr) \ 95 x->logEventHistTs(NBLog::EVENT_AUDIO_STATE, hash(__FILE__, __LINE__)); } while(0) 96 97 namespace android { 98 extern "C" { 99 extern thread_local NBLog::Writer *tlNBLogWriter; 100 } 101 } // namespace android 102 103 #endif // ANDROID_TYPED_LOGGER_H 104