1 /*
2 * Copyright (c) 2007-2021, Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 //!
23 //! \file cm_ftrace.cpp
24 //! \brief Class Cm Ftrace definitions
25 //!
26
27 #include "cm_ftrace.h"
28 #include <unistd.h>
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 #include <fcntl.h>
32 #include <string.h>
33
34 #include "cm_task_internal.h"
35
36 #define TRACE_MARKER_PATH "/sys/kernel/debug/tracing/trace_marker"
37
38 #define TRACE_FLAG_PATH "/sys/kernel/debug/tracing/tracing_on"
39
40 #define MSG_LENGTH 1024
41
42 #define PRINT_TO_STRING(_fmt, _value) \
43 byteInput = snprintf(msgBuf + byteOffset, MSG_LENGTH - byteOffset, _fmt, _value); \
44 byteOffset += byteInput;
45
46 //Global static pointer to ensure a single instance
47 CmFtrace* CmFtrace::m_ftrace = nullptr;
48
CmFtrace()49 CmFtrace::CmFtrace()
50 {
51 m_filehandle = open( TRACE_MARKER_PATH, O_WRONLY );
52 }
53
~CmFtrace()54 CmFtrace::~CmFtrace()
55 {
56 if(m_filehandle >= 0)
57 {
58 close(m_filehandle);
59 }
60 }
61
GetInstance()62 CmFtrace* CmFtrace::GetInstance()
63 {
64 if(m_ftrace == nullptr)
65 {
66 m_ftrace = new (std::nothrow) CmFtrace();
67 }
68
69 return m_ftrace;
70 }
71
WriteTaskProfilingInfo(CM_PROFILING_INFO * taskInfo)72 void CmFtrace::WriteTaskProfilingInfo(CM_PROFILING_INFO *taskInfo)
73 {
74 if(taskInfo == nullptr)
75 {
76 return ;
77 }
78
79 char msgBuf[MSG_LENGTH];
80 uint byteOffset = 0;
81 uint byteInput = 0;
82
83 PRINT_TO_STRING("%s: ", "mdf_v1")
84 PRINT_TO_STRING("kernelcount=%d|", taskInfo->kernelCount);
85 PRINT_TO_STRING("taskid=%d|", taskInfo->taskID);
86 PRINT_TO_STRING("threadid=%u|", taskInfo->threadID);
87
88 uint kernelNameOffset = 0;
89 for(uint i=0 ; i< taskInfo->kernelCount; i++)
90 {
91 //Kernel name.
92 char *kernelname = taskInfo->kernelNames + kernelNameOffset;
93 PRINT_TO_STRING("kernelname=%s|", kernelname);
94 kernelNameOffset += strlen(kernelname) + 1;
95
96 //Local work width&height
97 PRINT_TO_STRING("localwidth=%d|", taskInfo->localWorkWidth[i]);
98 PRINT_TO_STRING("localheight=%d|", taskInfo->localWorkHeight[i]);
99
100 //Global work width&height
101 PRINT_TO_STRING("globalwidth=%d|", taskInfo->globalWorkWidth[i]);
102 PRINT_TO_STRING("globalheight=%d|", taskInfo->globalWorkHeight[i]);
103 }
104
105 //Note: enqueuetime/flushtime/completetime are measured in performance counter
106 //Don't need to convert to nanosec on Linux since MosUtilities::MosQueryPerformanceFrequency returns 1
107 //On linux, we can't get the gpu ticks when the command submitted, so that
108 //we can't do the adjustment the ticks b/w cpu and gpu, as what we did on windoes by GetGpuTime
109 //hw_start_time = flush_time; hw_end_time = hw_start_time + kernel_execution_time
110
111 LARGE_INTEGER kernelExeTime;
112 kernelExeTime.QuadPart = taskInfo->hwEndTime.QuadPart - taskInfo->hwStartTime.QuadPart;
113
114 //write time stampes
115 PRINT_TO_STRING("enqueuetime=%lld|", (long long)taskInfo->enqueueTime.QuadPart);
116 PRINT_TO_STRING("flushtime=%lld|", (long long)taskInfo->flushTime.QuadPart);
117 PRINT_TO_STRING("hwstarttime=%lld|", (long long)taskInfo->flushTime.QuadPart);
118 PRINT_TO_STRING("hwendtime=%lld|", (long long)(taskInfo->flushTime.QuadPart + kernelExeTime.QuadPart) );
119 PRINT_TO_STRING("completetime=%lld\n", (long long)taskInfo->completeTime.QuadPart);
120
121 // write message to trace_marker
122 size_t writeSize = write(m_filehandle, msgBuf, byteOffset);
123
124 return;
125 }
126