/* * Copyright (c) 2007-2021, Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ //! //! \file cm_ftrace.cpp //! \brief Class Cm Ftrace definitions //! #include "cm_ftrace.h" #include #include #include #include #include #include "cm_task_internal.h" #define TRACE_MARKER_PATH "/sys/kernel/debug/tracing/trace_marker" #define TRACE_FLAG_PATH "/sys/kernel/debug/tracing/tracing_on" #define MSG_LENGTH 1024 #define PRINT_TO_STRING(_fmt, _value) \ byteInput = snprintf(msgBuf + byteOffset, MSG_LENGTH - byteOffset, _fmt, _value); \ byteOffset += byteInput; //Global static pointer to ensure a single instance CmFtrace* CmFtrace::m_ftrace = nullptr; CmFtrace::CmFtrace() { m_filehandle = open( TRACE_MARKER_PATH, O_WRONLY ); } CmFtrace::~CmFtrace() { if(m_filehandle >= 0) { close(m_filehandle); } } CmFtrace* CmFtrace::GetInstance() { if(m_ftrace == nullptr) { m_ftrace = new (std::nothrow) CmFtrace(); } return m_ftrace; } void CmFtrace::WriteTaskProfilingInfo(CM_PROFILING_INFO *taskInfo) { if(taskInfo == nullptr) { return ; } char msgBuf[MSG_LENGTH]; uint byteOffset = 0; uint byteInput = 0; PRINT_TO_STRING("%s: ", "mdf_v1") PRINT_TO_STRING("kernelcount=%d|", taskInfo->kernelCount); PRINT_TO_STRING("taskid=%d|", taskInfo->taskID); PRINT_TO_STRING("threadid=%u|", taskInfo->threadID); uint kernelNameOffset = 0; for(uint i=0 ; i< taskInfo->kernelCount; i++) { //Kernel name. char *kernelname = taskInfo->kernelNames + kernelNameOffset; PRINT_TO_STRING("kernelname=%s|", kernelname); kernelNameOffset += strlen(kernelname) + 1; //Local work width&height PRINT_TO_STRING("localwidth=%d|", taskInfo->localWorkWidth[i]); PRINT_TO_STRING("localheight=%d|", taskInfo->localWorkHeight[i]); //Global work width&height PRINT_TO_STRING("globalwidth=%d|", taskInfo->globalWorkWidth[i]); PRINT_TO_STRING("globalheight=%d|", taskInfo->globalWorkHeight[i]); } //Note: enqueuetime/flushtime/completetime are measured in performance counter //Don't need to convert to nanosec on Linux since MosUtilities::MosQueryPerformanceFrequency returns 1 //On linux, we can't get the gpu ticks when the command submitted, so that //we can't do the adjustment the ticks b/w cpu and gpu, as what we did on windoes by GetGpuTime //hw_start_time = flush_time; hw_end_time = hw_start_time + kernel_execution_time LARGE_INTEGER kernelExeTime; kernelExeTime.QuadPart = taskInfo->hwEndTime.QuadPart - taskInfo->hwStartTime.QuadPart; //write time stampes PRINT_TO_STRING("enqueuetime=%lld|", (long long)taskInfo->enqueueTime.QuadPart); PRINT_TO_STRING("flushtime=%lld|", (long long)taskInfo->flushTime.QuadPart); PRINT_TO_STRING("hwstarttime=%lld|", (long long)taskInfo->flushTime.QuadPart); PRINT_TO_STRING("hwendtime=%lld|", (long long)(taskInfo->flushTime.QuadPart + kernelExeTime.QuadPart) ); PRINT_TO_STRING("completetime=%lld\n", (long long)taskInfo->completeTime.QuadPart); // write message to trace_marker size_t writeSize = write(m_filehandle, msgBuf, byteOffset); return; }