Open-AVB AVTP Pipeline SDK  1.4
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
openavb_trace_pub.h
1 /*************************************************************************************************************
2 Copyright (c) 2012-2015, Symphony Teleca Corporation, a Harman International Industries, Incorporated company
3 All rights reserved.
4 
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
7 
8 1. Redistributions of source code must retain the above copyright notice, this
9  list of conditions and the following disclaimer.
10 2. Redistributions in binary form must reproduce the above copyright notice,
11  this list of conditions and the following disclaimer in the documentation
12  and/or other materials provided with the distribution.
13 
14 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS LISTED "AS IS" AND
15 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS LISTED BE LIABLE FOR
18 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 
25 Attributions: The inih library portion of the source code is licensed from
26 Brush Technology and Ben Hoyt - Copyright (c) 2009, Brush Technology and Copyright (c) 2009, Ben Hoyt.
27 Complete license and copyright information can be found at
28 https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175.
29 *************************************************************************************************************/
30 
31 /*
32 * MODULE SUMMARY : Provide a simple tracing facility for use
33 * during development.
34 *
35 * Based off of the openavb_log facility.
36 *
37 * NOTE: The Tracing uses a high resolution timer and therefore
38 * librt must be linked into any application that uses this
39 * facility.
40 */
41 
42 #ifndef AVB_TRACE_PUB_H
43 #define AVB_TRACE_PUB_H 1
44 
45 #include "openavb_platform_pub.h"
46 #include <stdio.h>
47 #include "openavb_types_pub.h"
48 
49 // Uncomment AVB_TRACE_ON to enable tracing.
50 //#define AVB_TRACE_ON 1
51 
52 // Specific reporting modes
53 #define AVB_TRACE_MODE_NONE 0
54 #define AVB_TRACE_MODE_MINIMAL 1
55 #define AVB_TRACE_MODE_NORMAL 2
56 #define AVB_TRACE_MODE_DELTA_TIME 3
57 #define AVB_TRACE_MODE_DELTA_STATS 4
58 #define AVB_TRACE_MODE_FUNC_TIME 5
59 #define AVB_TRACE_MODE_DOC 6
60 
61 // One of the above reporting modes must be set here
62 #define AVB_TRACE_MODE AVB_TRACE_MODE_NORMAL
63 
64 // Delta Stats Interval
65 #define AVB_TRACE_OPT_DELTA_STATS_INTERVAL 80000
66 
67 // Function Time interval
68 #define AVB_TRACE_OPT_FUNC_TIME_INTERVAL 80000
69 //#define AVB_TRACE_OPT_FUNC_TIME_INTERVAL 100
70 
71 // Option to show file name
72 //#define AVB_TRACE_OPT_SHOW_FILE_NAME 1
73 
74 
75 //#define AVB_TRACE_PRINTF(FMT, ...) fprintf(stderr, FMT, __VA_ARGS__)
76 //#define AVB_TRACE_PRINTF(FMT, ...) fprintf(stdout, FMT, __VA_ARGS__)
77 #define AVB_TRACE_PRINTF(FMT, ...) printf(FMT, __VA_ARGS__)
78 
79 
80 // Features to trace. 1 is enabled, 0 is disabled.
81 #define AVB_TRACE_MAP 0
82 #define AVB_TRACE_MAP_DETAIL 0
83 #define AVB_TRACE_MAP_LINE 0
84 #define AVB_TRACE_INTF 0
85 #define AVB_TRACE_INTF_DETAIL 0
86 #define AVB_TRACE_INTF_LINE 0
87 #define AVB_TRACE_HOST 0
88 
89 #define TRACE_VAR1(x, y) x ## y
90 #define TRACE_VAR2(x, y) TRACE_VAR1(x, y)
91 
92 #ifdef AVB_TRACE_OPT_SHOW_FILE_NAME
93 #define TRACE_FILE_NAME __FILE__
94 #else
95 #define TRACE_FILE_NAME ""
96 #endif
97 
98 
99 #if !defined(AVB_TRACE_ON) || (AVB_TRACE_MODE == AVB_TRACE_MODE_NONE)
100 #define AVB_TRACE_LINE(FEATURE)
101 #define AVB_TRACE_ENTRY(FEATURE)
102 #define AVB_TRACE_EXIT(FEATURE)
103 #define AVB_TRACE_LOOP_ENTRY(FEATURE)
104 #define AVB_TRACE_LOOP_EXIT(FEATURE)
105 #elif (AVB_TRACE_MODE == AVB_TRACE_MODE_MINIMAL)
106 #define AVB_TRACE_LINE(FEATURE) avbTraceMinimalFn(FEATURE, "TRACE LINE ", __FUNCTION__, TRACE_FILE_NAME, __LINE__)
107 #define AVB_TRACE_ENTRY(FEATURE) avbTraceMinimalFn(FEATURE, "TRACE ENTRY", __FUNCTION__, TRACE_FILE_NAME, __LINE__)
108 #define AVB_TRACE_EXIT(FEATURE) avbTraceMinimalFn(FEATURE, "TRACE EXIT ", __FUNCTION__, TRACE_FILE_NAME, __LINE__)
109 #define AVB_TRACE_LOOP_ENTRY(FEATURE) avbTraceMinimalFn(FEATURE, "TRACE LOOP{", __FUNCTION__, TRACE_FILE_NAME, __LINE__)
110 #define AVB_TRACE_LOOP_EXIT(FEATURE) avbTraceMinimalFn(FEATURE, "TRACE LOOP}", __FUNCTION__, TRACE_FILE_NAME, __LINE__)
111 #elif (AVB_TRACE_MODE == AVB_TRACE_MODE_NORMAL)
112 #define AVB_TRACE_LINE(FEATURE) avbTraceNormalFn(FEATURE, "TRACE LINE ", __FUNCTION__, TRACE_FILE_NAME, __LINE__)
113 #define AVB_TRACE_ENTRY(FEATURE) avbTraceNormalFn(FEATURE, "TRACE ENTRY", __FUNCTION__, TRACE_FILE_NAME, __LINE__)
114 #define AVB_TRACE_EXIT(FEATURE) avbTraceNormalFn(FEATURE, "TRACE EXIT ", __FUNCTION__, TRACE_FILE_NAME, __LINE__)
115 #define AVB_TRACE_LOOP_ENTRY(FEATURE) avbTraceNormalFn(FEATURE, "TRACE LOOP{", __FUNCTION__, TRACE_FILE_NAME, __LINE__)
116 #define AVB_TRACE_LOOP_EXIT(FEATURE) avbTraceNormalFn(FEATURE, "TRACE LOOP}", __FUNCTION__, TRACE_FILE_NAME, __LINE__)
117 #elif (AVB_TRACE_MODE == AVB_TRACE_MODE_DELTA_TIME)
118 #define AVB_TRACE_LINE(FEATURE) avbTraceDeltaTimeFn(FEATURE, "TRACE LINE ", __FUNCTION__, TRACE_FILE_NAME, __LINE__, NULL, NULL)
119 #define AVB_TRACE_ENTRY(FEATURE) avbTraceDeltaTimeFn(FEATURE, "TRACE ENTRY", __FUNCTION__, TRACE_FILE_NAME, __LINE__, NULL, NULL)
120 #define AVB_TRACE_EXIT(FEATURE) avbTraceDeltaTimeFn(FEATURE, "TRACE EXIT ", __FUNCTION__, TRACE_FILE_NAME, __LINE__, NULL, NULL)
121 #define AVB_TRACE_LOOP_ENTRY(FEATURE) avbTraceDeltaTimeFn(FEATURE, "TRACE LOOP{", __FUNCTION__, TRACE_FILE_NAME, __LINE__, NULL, NULL)
122 #define AVB_TRACE_LOOP_EXIT(FEATURE) avbTraceDeltaTimeFn(FEATURE, "TRACE LOOP}", __FUNCTION__, TRACE_FILE_NAME, __LINE__, NULL, NULL)
123 #elif (AVB_TRACE_MODE == AVB_TRACE_MODE_DELTA_STATS)
124 #define AVB_TRACE_LINE(FEATURE) static U64 TRACE_VAR2(traceCnt,__LINE__); static U64 TRACE_VAR2(traceNSec, __LINE__); avbTraceDeltaTimeFn(FEATURE, "TRACE LINE ", __FUNCTION__, TRACE_FILE_NAME, __LINE__, &TRACE_VAR2(traceCnt,__LINE__), &TRACE_VAR2(traceNSec, __LINE__))
125 #define AVB_TRACE_ENTRY(FEATURE) static U64 TRACE_VAR2(traceCnt,__LINE__); static U64 TRACE_VAR2(traceNSec, __LINE__); avbTraceDeltaTimeFn(FEATURE, "TRACE ENTRY", __FUNCTION__, TRACE_FILE_NAME, __LINE__, &TRACE_VAR2(traceCnt,__LINE__), &TRACE_VAR2(traceNSec, __LINE__))
126 #define AVB_TRACE_EXIT(FEATURE) static U64 TRACE_VAR2(traceCnt,__LINE__); static U64 TRACE_VAR2(traceNSec, __LINE__); avbTraceDeltaTimeFn(FEATURE, "TRACE EXIT ", __FUNCTION__, TRACE_FILE_NAME, __LINE__, &TRACE_VAR2(traceCnt,__LINE__), &TRACE_VAR2(traceNSec, __LINE__))
127 #define AVB_TRACE_LOOP_ENTRY(FEATURE) static U64 TRACE_VAR2(traceCnt,__LINE__); static U64 TRACE_VAR2(traceNSec, __LINE__); avbTraceDeltaTimeFn(FEATURE, "TRACE LOOP{", __FUNCTION__, TRACE_FILE_NAME, __LINE__, &TRACE_VAR2(traceCnt,__LINE__), &TRACE_VAR2(traceNSec, __LINE__))
128 #define AVB_TRACE_LOOP_EXIT(FEATURE) static U64 TRACE_VAR2(traceCnt,__LINE__); static U64 TRACE_VAR2(traceNSec, __LINE__); avbTraceDeltaTimeFn(FEATURE, "TRACE LOOP}", __FUNCTION__, TRACE_FILE_NAME, __LINE__, &TRACE_VAR2(traceCnt,__LINE__), &TRACE_VAR2(traceNSec, __LINE__))
129 #elif (AVB_TRACE_MODE == AVB_TRACE_MODE_FUNC_TIME)
130 #define AVB_TRACE_LINE(FEATURE)
131 #define AVB_TRACE_ENTRY(FEATURE) static struct timespec TRACE_VAR2(tsFuncEntry,__FUNCTION__); avbTraceFuncTimeFn(FEATURE, TRUE, __FUNCTION__, TRACE_FILE_NAME, __LINE__, &TRACE_VAR2(tsFuncEntry,__FUNCTION__), NULL, NULL)
132 #define AVB_TRACE_EXIT(FEATURE) static U64 TRACE_VAR2(traceCnt,__LINE__); static U64 TRACE_VAR2(traceNSec, __LINE__); avbTraceFuncTimeFn(FEATURE, FALSE, __FUNCTION__, TRACE_FILE_NAME, __LINE__, &TRACE_VAR2(tsFuncEntry,__FUNCTION__), &TRACE_VAR2(traceCnt,__LINE__), &TRACE_VAR2(traceNSec, __LINE__))
133 #define AVB_TRACE_LOOP_ENTRY(FEATURE) static struct timespec TRACE_VAR2(tsLoopEntry,__FUNCTION__); avbTraceFuncTimeFn(FEATURE, TRUE, __FUNCTION__, TRACE_FILE_NAME, __LINE__, &TRACE_VAR2(tsLoopEntry,__FUNCTION__), NULL, NULL)
134 #define AVB_TRACE_LOOP_EXIT(FEATURE) static U64 TRACE_VAR2(traceCnt,__LINE__); static U64 TRACE_VAR2(traceNSec, __LINE__); avbTraceFuncTimeFn(FEATURE, FALSE, __FUNCTION__, TRACE_FILE_NAME, __LINE__, &TRACE_VAR2(tsLoopEntry,__FUNCTION__), &TRACE_VAR2(traceCnt,__LINE__), &TRACE_VAR2(traceNSec, __LINE__))
135 #elif (AVB_TRACE_MODE == AVB_TRACE_MODE_DOC)
136 #define AVB_TRACE_LINE(FEATURE) avbTraceDocFn(FEATURE, "|", __FUNCTION__, TRACE_FILE_NAME, __LINE__, NULL, NULL)
137 #define AVB_TRACE_ENTRY(FEATURE) avbTraceDocFn(FEATURE, ">", __FUNCTION__, TRACE_FILE_NAME, __LINE__, NULL, NULL)
138 #define AVB_TRACE_EXIT(FEATURE) avbTraceDocFn(FEATURE, "<", __FUNCTION__, TRACE_FILE_NAME, __LINE__, NULL, NULL)
139 #define AVB_TRACE_LOOP_ENTRY(FEATURE)
140 #define AVB_TRACE_LOOP_EXIT(FEATURE)
141 #endif
142 
143 #ifdef AVB_TRACE_ON
144 
145 static inline void avbTraceMinimalFn(int featureOn, const char *tag, const char *function, const char *file, int line)
146 {
147  if (featureOn) {
148  AVB_TRACE_PRINTF("%s: %s():%d %s\n", tag, function, line, file);
149  }
150 }
151 
152 static inline void avbTraceNormalFn(int featureOn, const char *tag, const char *function, const char *file, int line)
153 {
154  if (featureOn) {
155  time_t tNow = time(NULL);
156  struct tm tmNow;
157  localtime_r(&tNow, &tmNow);
158 
159  AVB_TRACE_PRINTF("[%2.2d:%2.2d:%2.2d] [P:%5.5d T:%lu] %s: %s():%d %s\n",
160  tmNow.tm_hour, tmNow.tm_min, tmNow.tm_sec, GET_PID(), THREAD_SELF(), tag, function, line, file);
161  }
162 }
163 
164 static inline void avbTraceDeltaTimeFn(int featureOn, const char *tag, const char *function, const char *file, int line, U64 *pCnt, U64 *pNSec)
165 {
166  if (featureOn) {
167  static struct timespec traceDeltaTimePrevTS;
168 
169  struct timespec nowTS;
170  CLOCK_GETTIME(OPENAVB_CLOCK_REALTIME, &nowTS);
171 
172  time_t tNow = time(NULL);
173  struct tm tmNow;
174  localtime_r(&tNow, &tmNow);
175 
176  U64 prevNSec = ((U64)traceDeltaTimePrevTS.tv_sec * (U64)NANOSECONDS_PER_SECOND) + (U64)traceDeltaTimePrevTS.tv_nsec;
177  U64 nowNSec = ((U64)nowTS.tv_sec * (U64)NANOSECONDS_PER_SECOND) + (U64)nowTS.tv_nsec;
178  U64 deltaNSec = nowNSec - prevNSec;
179 
180  if (pCnt && pNSec) {
181  // Delta Stats
182  (*pCnt)++;
183  *pNSec += deltaNSec;
184 
185  if (*pCnt % AVB_TRACE_OPT_DELTA_STATS_INTERVAL == 0) {
186  AVB_TRACE_PRINTF("[%2.2d:%2.2d:%2.2d] [P:%5.5d T:%lu] [cnt:%6llu deltaUS:%10llu totalUS:%10llu] %s: %s():%d %s\n",
187  tmNow.tm_hour, tmNow.tm_min, tmNow.tm_sec, GET_PID(), THREAD_SELF(), (unsigned long long)(*pCnt), (unsigned long long)(deltaNSec / 1000), (unsigned long long)(*pNSec / 1000), tag, function, line, file);
188  }
189  }
190  else {
191  AVB_TRACE_PRINTF("[%2.2d:%2.2d:%2.2d] [P:%5.5d T:%lu] [deltaUS:%10llu] %s: %s():%d %s\n",
192  tmNow.tm_hour, tmNow.tm_min, tmNow.tm_sec, GET_PID(), THREAD_SELF(), (unsigned long long)(deltaNSec / 1000), tag, function, line, file);
193  }
194 
195  CLOCK_GETTIME(OPENAVB_CLOCK_REALTIME, &traceDeltaTimePrevTS);
196  }
197 }
198 
199 static inline void avbTraceFuncTimeFn(int featureOn, bool bEntry, const char *function, const char *file, int line, struct timespec *pTS, U64 *pCnt, U64 *pNSec)
200 {
201  if (featureOn) {
202  if (bEntry) {
203  CLOCK_GETTIME(OPENAVB_CLOCK_REALTIME, pTS);
204  }
205  else {
206  struct timespec nowTS;
207  CLOCK_GETTIME(OPENAVB_CLOCK_REALTIME, &nowTS);
208 
209  time_t tNow = time(NULL);
210  struct tm tmNow;
211  localtime_r(&tNow, &tmNow);
212 
213  U64 entryNSec = ((U64)pTS->tv_sec * (U64)NANOSECONDS_PER_SECOND) + (U64)pTS->tv_nsec;
214  U64 nowNSec = ((U64)nowTS.tv_sec * (U64)NANOSECONDS_PER_SECOND) + (U64)nowTS.tv_nsec;
215  U64 deltaNSec = nowNSec - entryNSec;
216 
217  (*pCnt)++;
218  *pNSec += deltaNSec;
219 
220  if (*pCnt % AVB_TRACE_OPT_FUNC_TIME_INTERVAL == 0) {
221  AVB_TRACE_PRINTF("[%2.2d:%2.2d:%2.2d] [P:%5.5d T:%lu] [cnt:%6llu lastUS:%10llu totalUS:%10llu avgUS:%10llu] %s():%d %s\n",
222  tmNow.tm_hour, tmNow.tm_min, tmNow.tm_sec, GET_PID(), THREAD_SELF(), (unsigned long long)(*pCnt), (unsigned long long)(deltaNSec / 1000), (unsigned long long)(*pNSec / 1000), (unsigned long long)((*pNSec / *pCnt) / 1000), function, line, file);
223  }
224  }
225  }
226 }
227 
228 static inline void avbTraceDocFn(int featureOn, const char *tag, const char *function, const char *file, int line, U64 *pCnt, U64 *pNSec)
229 {
230  if (featureOn) {
231  static int depthTrace = 0;
232  if (tag[0] == '>') {
233  AVB_TRACE_PRINTF("%*s%s %s [%s]\n", depthTrace * 4, "", tag, function, file);
234  depthTrace++;
235  }
236  else if (tag[0] == '<') {
237  depthTrace--;
238  AVB_TRACE_PRINTF("%*s%s %s [%s]\n", depthTrace * 4, "", tag, function, file);
239  }
240  else {
241  AVB_TRACE_PRINTF("%*s%s %s [%s]\n", depthTrace * 4, "", tag, function, file);
242  }
243  }
244 }
245 
246 #endif // AVB_TRACE_ON
247 #endif // AVB_TRACE_PUB_H
uint64_t U64
Unsigned 64 bit type.
Definition: openavb_types_base_pub.h:89
#define NANOSECONDS_PER_SECOND
Number of nanoseconds in second.
Definition: openavb_types_base_pub.h:52
#define NULL
Null pointer value.
Definition: openavb_types_base_pub.h:71