homescreensrv_plat/idlefw_api/inc/debug.h
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Thu, 17 Dec 2009 08:54:17 +0200
changeset 0 79c6a41cd166
permissions -rw-r--r--
Revision: 200949 Kit: 200951

/*
* Copyright (c) 2005-2006 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:  Debug helpers
*
*/


#ifndef __AI2_DEBUG_H__
#define __AI2_DEBUG_H__

#include <e32def.h>

// Uncomment to turn on RD logging
//#define AI_ENABLE_RD_LOGGING

#ifdef __WINS__
    // On the emulator log to debug output
    #define AI_RD_LOG_TO_DEBUG_OUTPUT
#endif

#ifndef AI_ENABLE_RD_LOGGING
// RD logging is off

// Empty definitions of logging macros when RD logging is turned off
#define __TIME_MARK(_var)
#define __TIME_ENDMARK(_msg, _var)
#define __TIME(_msg, _code) _code;
#define __TICK(_msg)
#define __HEAP(_msg)
#define __DBG_FORMAT(_fmt) TAiEmptyDebugFormat()
#define __PRINT __impl_print_empty
#define __DBG_FORMAT8(_fmt) TAiEmptyDebugFormat()
#define __PRINT8 __impl_print_empty
#define __PRINTS(_str)
#define __PRINT_IF_ERROR(_stmt, _fmt) (void)_stmt;
#define __TRAP_AND_PRINT_IF_ERROR(_stmt, _fmt) TRAP_IGNORE(_stmt);

// Unnamed namespace to keep debug functions out of global namespace
namespace {

/**
 * Zero-overhead definition for an empty debug formatting string.
 * @see macro __DBG_FORMAT
 */
NONSHARABLE_STRUCT(TAiEmptyDebugFormat)
    { 
    };

/// Zero-overhead RD log print implementation when RD logging is turned off
inline void __impl_print_empty(const TAiEmptyDebugFormat&) { }

/// Zero-overhead RD log print implementation when RD logging is turned off
template<class T0> inline 
void __impl_print_empty(const TAiEmptyDebugFormat&,T0) { }

/// Zero-overhead RD log print implementation when RD logging is turned off
template<class T0, class T1> inline 
void __impl_print_empty(const TAiEmptyDebugFormat&,T0,T1) { }

/// Zero-overhead RD log print implementation when RD logging is turned off
template<class T0, class T1, class T2> inline 
void __impl_print_empty(const TAiEmptyDebugFormat&,T0,T1,T2) { }

/// Zero-overhead RD log print implementation when RD logging is turned off
template<class T0, class T1, class T2, class T3> inline 
void __impl_print_empty(const TAiEmptyDebugFormat&,T0,T1,T2,T3) { }

/// Zero-overhead RD log print implementation when RD logging is turned off
template<class T0, class T1, class T2, class T3, class T4> inline 
void __impl_print_empty(const TAiEmptyDebugFormat&,T0,T1,T2,T3,T4) { }

/// Zero-overhead RD log print implementation when RD logging is turned off
template<class T0, class T1, class T2, class T3, class T4, class T5> inline 
void __impl_print_empty(const TAiEmptyDebugFormat&,T0,T1,T2,T3,T4,T5) { }

/// Zero-overhead RD log print implementation when RD logging is turned off
template<class T0, class T1, class T2, class T3, class T4, class T5, class T6> inline 
void __impl_print_empty(const TAiEmptyDebugFormat&,T0,T1,T2,T3,T4,T5,T6) { }

/// Zero-overhead RD log print implementation when RD logging is turned off
template<class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7> inline 
void __impl_print_empty(const TAiEmptyDebugFormat&,T0,T1,T2,T3,T4,T5,T6,T7) { }

}  // namespace

#else
// RD logging is on

#include <e32std.h>
#include <e32debug.h>
#include <flogger.h>

/**
 * Stores the current time as microsecond value.
 *
 * @param _var A name, which will be declared as a TInt, and will receive the 
 *             current time value. After the macro, _var remains in scope until 
 *             the end of its enclosing block.
 * @see __TIME_ENDMARK
 */
#define __TIME_MARK(_var) TTime _var;_var.UniversalTime();

/**
 * Logs the microsecond difference between current value and stored earlier 
 * with __TIME_MARK macro.
 *
 * @param _msg textual message to write to the RD log file.
 * @param _var  the start time, the value is set by __TIME_MARK macro.
 * @see __TIME_MARK
 */
#define __TIME_ENDMARK(_msg, _var) __impl_time_endmark(_L(_msg), _var);

/**
 * Measures the execution time of a code statement
 *
 * @param _msg textual message to write to the RD log file.
 * @param _code code statements to be measured.
 */
#define __TIME(_msg, _code) {TTime _time;_time.UniversalTime();_code;__impl_time_endmark(_L(_msg),_time);};

/*
 * Prints a message and current time as ms to the RD log file.
 *
 * @param _msg textual message to write to the log file.
 */
#define __TICK(_msg) __impl_tick(_L(_msg));

/*
 * Prints a message and current heap memory status to the log file.
 *
 * @param _msg textual message to write to the log file.
 */
#define __HEAP(_msg) __impl_heap(_L(_msg));

/**
 * Defines an UNICODE RD logging format string. Used with __PRINT macro.
 * @see __PRINT
 */
#define __DBG_FORMAT(_fmt) _L(_fmt)

#ifdef AI_RD_LOG_TO_DEBUG_OUTPUT
    /**
     * Prints a printf-style formatted message to the debug output.
     * Format string needs to be defined with the __DBG_FORMAT macro.
     */
    #define __PRINT RDebug::Print
#else
    /**
     * Prints a printf-style formatted message to the RD log file.
     * Format string needs to be defined with the __DBG_FORMAT macro.
     */
    #define __PRINT __impl_print
#endif

#ifdef AI_RD_LOG_TO_DEBUG_OUTPUT
    /**
     * Defines a 8-bit RD logging format string. Used with __PRINT8 macro.
     * @see __PRINT8
     */
    #define __DBG_FORMAT8(_fmt) _fmt

    /**
     * Prints a printf-style formatted message to the debug output.
     * The format string (first parameter) needs to be a 8-bit literal
     * C string.
     */
    #define __PRINT8 RDebug::Printf
#else
    /**
     * Defines a 8-bit RD logging format string. Used with __PRINT8 macro.
     * @see __PRINT8
     */
    #define __DBG_FORMAT8(_fmt) _L8(_fmt)

    /**
     * Prints a printf-style formatted message to the debug output.
     * The format string (first parameter) needs to be a 8-bit literal
     * C string.
     */
    #define __PRINT8 __impl_print8
#endif 

/**
 * Prints a string to the RD log.
 * 
 * @param _msg textual message to write to the log file.
 */
#define __PRINTS(_msg) __impl_prints(_L(_msg));

/**
 * Prints a message to the RD log if a statement returns an error code other
 * than KErrNone.
 * 
 * @param _stmt statment to check for error return code.
 * @param _fmt textual message to write to the log file. If the message string
 *             contains %d directive it is replaced with the error code that
 *             _stmt returned.
 */
#define __PRINT_IF_ERROR(_stmt, _fmt) { TInt _error = _stmt; if (_error != KErrNone) __PRINT(_L(_fmt), _error); };

/**
 * Prints a message to the RD log if a statement leaves with an error code.
 * 
 * @param _stmt statment to check for leave.
 * @param _fmt textual message to write to the log file. If the message string
 *             contains %d directive it is replaced with the error code that
 *             _stmt leaved with.
 */
#define __TRAP_AND_PRINT_IF_ERROR(_stmt, _fmt) { TRAPD(_error, _stmt); if (_error != KErrNone) __PRINT(_L(_fmt), _error); };

/**
 * Directory under C:\Logs in the device filesystem where the ActiveIdle2 RD 
 * log file is stored.
 */
#define D_LOG_DIR _L("ActiveIdle2")

/**
 * Name of the ActiveIdle2 RD log file under D_LOG_DIR.
 */
#define D_LOG_FILE _L("debug.log")

// Unnamed namespace to keep debug functions out of global namespace
namespace {

// ----------------------------------------------------------------------------
//
// Performance logging operation, give results in microseconds 10^-6
// The metricts are based on the measurment current value of microseconds in 
// the begining of operation and in the end. The time difference is actual result
//
// The logging operations take about 5ms, which should be considered if inner
// tag are used.
//
// Examples:
//
// __TIME_MARK(t)
// DoOperation(...);
// __TIME_ENDMARK(_L("Message 1"), t);
//
// __TIME(_L("Message 1"), DoOperation(...))
//
// ----------------------------------------------------------------------------
//

//
// Actual implementation of 
// Logs the microsecond difference between current value and stored earlier
// aMsg - textual message stored to the log file
// aStart - the start time, the value is set by previous macros
//
inline void __impl_time_endmark(const TDesC& aMsg, TTime aStart)
{
	TTime now;
	now.UniversalTime();
	TTimeIntervalMicroSeconds delta = now.MicroSecondsFrom(aStart);
#ifdef AI_RD_LOG_TO_DEBUG_OUTPUT
    RDebug::Print( _L("\t[T]\t%S\tTime:\t%Ld"), &aMsg, delta.Int64() );
#else
	RFileLogger::WriteFormat(D_LOG_DIR, D_LOG_FILE, EFileLoggingModeAppend, _L("\t[T]\t%S\tTime:\t%Ld"), &aMsg, delta.Int64());	
#endif
}

//
// Prints the message and current ms value to the log file
//
inline void __impl_tick(const TDesC& aMsg)
{
	//Gets the nanokernel tick count. This is the current value of the machine's millisecond tick counter.
    TUint32 nTick = User::NTickCount();
#ifdef AI_RD_LOG_TO_DEBUG_OUTPUT
    RDebug::Print( _L("\t[T]\t%S\tMicro Sec:\t%d000"), &aMsg, nTick );
#else
	RFileLogger::WriteFormat(D_LOG_DIR, D_LOG_FILE, EFileLoggingModeAppend, _L("\t[T]\t%S\tMicro Sec:\t%d000"), &aMsg, nTick);	
#endif
}

// ----------------------------------------------------------------------------
//
// Logs the amout of used heap to log file. Notes that the Heap value equals
// to the result provided by Goofy tool.
//
// ----------------------------------------------------------------------------
//
inline void __impl_heap(const TDesC& aMsg)
    {
    TInt size;
    User::Heap().AllocSize(size);
#ifdef AI_RD_LOG_TO_DEBUG_OUTPUT
    RDebug::Print( _L("\t[M]\t%S\tAlloc:\t%d\tHeap:\t%d"), &aMsg, size, User::Heap().Size() );
#else
    RFileLogger::WriteFormat(D_LOG_DIR, D_LOG_FILE, EFileLoggingModeAppend, _L("\t[M]\t%S\tAlloc:\t%d\tHeap:\t%d"), &aMsg, size, User::Heap().Size());
#endif
    }

inline void __impl_print(TRefByValue<const TDesC16> aFmt, ...)
    {
	VA_LIST list;
	VA_START(list,aFmt);
    RFileLogger::WriteFormat(D_LOG_DIR, D_LOG_FILE, EFileLoggingModeAppend, aFmt, list);
    VA_END(list);
    }

inline void __impl_print8(TRefByValue<const TDesC8> aFmt, ...)
    {
	VA_LIST list;
	VA_START(list,aFmt);
    RFileLogger::WriteFormat(D_LOG_DIR, D_LOG_FILE, EFileLoggingModeAppend, aFmt, list);
    VA_END(list);
    }

inline void __impl_prints(const TDesC& aMsg)
    {
#ifdef AI_RD_LOG_TO_DEBUG_OUTPUT
    RDebug::Print( aMsg );
#else
	RFileLogger::WriteFormat(D_LOG_DIR, D_LOG_FILE, EFileLoggingModeAppend, _L("\t[I]\t%S"), &aMsg);
#endif
    }
    
}  // namespace

#endif // AI_ENABLE_DEBUG_LOGGING

#endif // !__AI2_DEBUG_H__