blob: f23762a0a645471d19833b76d4fe8a0eec1cdbf7 [file] [log] [blame]
/*
* Copyright (c) 2007-2017, 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 <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#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 MOS_QueryPerformanceFrequency 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;
}