1 /**
2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #ifndef LIBPANDABASE_TRACE_TRACE_H
17 #define LIBPANDABASE_TRACE_TRACE_H
18
19 #include <cstdint>
20 #include <iosfwd>
21 #include <sstream>
22 #include <string>
23
24 #include "macros.h"
25
26 namespace panda::trace {
27
28 namespace internal {
29 extern int g_trace_marker_fd;
30 bool DoInit();
31 void DoBeginTracePoint(const char *str);
32 void DoEndTracePoint();
33 void DoIntTracePoint(const char *str, int32_t val);
34 void DoInt64TracePoint(const char *str, int64_t val);
35 } // namespace internal
36
IsEnabled()37 static inline bool IsEnabled()
38 {
39 return internal::g_trace_marker_fd != -1;
40 }
41
BeginTracePoint(const char * str)42 static inline void BeginTracePoint(const char *str)
43 {
44 if (UNLIKELY(IsEnabled())) {
45 internal::DoBeginTracePoint(str);
46 }
47 }
48
EndTracePoint()49 static inline void EndTracePoint()
50 {
51 if (UNLIKELY(IsEnabled())) {
52 internal::DoEndTracePoint();
53 }
54 }
55
IntTracePoint(const char * str,int32_t val)56 static inline void IntTracePoint(const char *str, int32_t val)
57 {
58 if (UNLIKELY(IsEnabled())) {
59 internal::DoIntTracePoint(str, val);
60 }
61 }
62
Int64TracePoint(const char * str,int64_t val)63 static inline void Int64TracePoint(const char *str, int64_t val)
64 {
65 if (UNLIKELY(IsEnabled())) {
66 internal::DoInt64TracePoint(str, val);
67 }
68 }
69
70 class ScopedTrace {
71 public:
ScopedTrace(const char * str)72 explicit ScopedTrace(const char *str)
73 {
74 BeginTracePoint(str);
75 }
ScopedTrace(const std::string & str)76 explicit ScopedTrace(const std::string &str) : ScopedTrace(str.c_str()) {}
77
~ScopedTrace()78 ~ScopedTrace()
79 {
80 EndTracePoint();
81 }
82
83 NO_COPY_SEMANTIC(ScopedTrace);
84 NO_MOVE_SEMANTIC(ScopedTrace);
85 };
86
87 namespace internal {
88 class ScopeTraceStremHelperBegin {
89 public:
90 ScopeTraceStremHelperBegin() = default;
~ScopeTraceStremHelperBegin()91 ~ScopeTraceStremHelperBegin()
92 {
93 BeginTracePoint(message_buffer_.str().c_str());
94 }
95
GetStream()96 std::ostream &GetStream()
97 {
98 return message_buffer_;
99 }
100
101 NO_COPY_SEMANTIC(ScopeTraceStremHelperBegin);
102 NO_MOVE_SEMANTIC(ScopeTraceStremHelperBegin);
103
104 private:
105 std::ostringstream message_buffer_;
106 };
107
108 class ScopeTraceStremHelperEnd {
109 public:
110 ScopeTraceStremHelperEnd() = default;
~ScopeTraceStremHelperEnd()111 ~ScopeTraceStremHelperEnd()
112 {
113 EndTracePoint();
114 }
115
116 NO_COPY_SEMANTIC(ScopeTraceStremHelperEnd);
117 NO_MOVE_SEMANTIC(ScopeTraceStremHelperEnd);
118 };
119 } // namespace internal
120
121 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
122 #define SCOPED_TRACE_STREAM \
123 ::panda::trace::internal::ScopeTraceStremHelperEnd MERGE_WORDS(end_trace_point, __LINE__); \
124 UNLIKELY(::panda::trace::IsEnabled()) && ::panda::trace::internal::ScopeTraceStremHelperBegin().GetStream()
125
126 } // namespace panda::trace
127
128 #endif // LIBPANDABASE_TRACE_TRACE_H
129