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>
hash(const char (& file)[n],uint32_t line)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