123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271 |
- /*
- AngelCode Scripting Library
- Copyright (c) 2003-2016 Andreas Jonsson
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any
- damages arising from the use of this software.
- Permission is granted to anyone to use this software for any
- purpose, including commercial applications, and to alter it and
- redistribute it freely, subject to the following restrictions:
- 1. The origin of this software must not be misrepresented; you
- must not claim that you wrote the original software. If you use
- this software in a product, an acknowledgment in the product
- documentation would be appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and
- must not be misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source
- distribution.
- The original version of this library can be located at:
- http://www.angelcode.com/angelscript/
- Andreas Jonsson
- andreas@angelcode.com
- */
- //
- // as_debug.h
- //
- #ifndef AS_DEBUG_H
- #define AS_DEBUG_H
- #include "as_config.h"
- #if defined(AS_DEBUG)
- #ifndef AS_WII
- // The Wii SDK doesn't have these, we'll survive without AS_DEBUG
- #ifndef _WIN32_WCE
- // Neither does WinCE
- #ifndef AS_PSVITA
- // Possible on PSVita, but requires SDK access
- #if !defined(_MSC_VER) && (defined(__GNUC__) || defined(AS_MARMALADE))
- #ifdef __ghs__
- // WIIU defines __GNUC__ but types are not defined here in 'conventional' way
- #include <types.h>
- typedef signed char int8_t;
- typedef unsigned char uint8_t;
- typedef signed short int16_t;
- typedef unsigned short uint16_t;
- typedef signed int int32_t;
- typedef unsigned int uint32_t;
- typedef signed long long int64_t;
- typedef unsigned long long uint64_t;
- typedef float float32_t;
- typedef double float64_t;
- #else
- // Define mkdir for GNUC
- #include <sys/stat.h>
- #include <sys/types.h>
- #define _mkdir(dirname) mkdir(dirname, S_IRWXU)
- #endif
- #else
- #include <direct.h>
- #endif
- #endif // AS_PSVITA
- #endif // _WIN32_WCE
- #endif // AS_WII
- #endif // !defined(AS_DEBUG)
- #if defined(_MSC_VER) && defined(AS_PROFILE)
- // Currently only do profiling with MSVC++
- #include <mmsystem.h>
- #include <direct.h>
- #include "as_string.h"
- #include "as_map.h"
- #include "as_string_util.h"
- BEGIN_AS_NAMESPACE
- struct TimeCount
- {
- double time;
- int count;
- double max;
- double min;
- };
- class CProfiler
- {
- public:
- CProfiler()
- {
- // We need to know how often the clock is updated
- __int64 tps;
- if( !QueryPerformanceFrequency((LARGE_INTEGER *)&tps) )
- usePerformance = false;
- else
- {
- usePerformance = true;
- ticksPerSecond = double(tps);
- }
- timeOffset = GetTime();
- }
- ~CProfiler()
- {
- WriteSummary();
- }
- double GetTime()
- {
- if( usePerformance )
- {
- __int64 ticks;
- QueryPerformanceCounter((LARGE_INTEGER *)&ticks);
- return double(ticks)/ticksPerSecond - timeOffset;
- }
-
- return double(timeGetTime())/1000.0 - timeOffset;
- }
- double Begin(const char *name)
- {
- double time = GetTime();
- // Add the scope to the key
- if( key.GetLength() )
- key += "|";
- key += name;
- // Compensate for the time spent writing to the file
- timeOffset += GetTime() - time;
- return time;
- }
- void End(const char * /*name*/, double beginTime)
- {
- double time = GetTime();
- double elapsed = time - beginTime;
- // Update the profile info for this scope
- asSMapNode<asCString, TimeCount> *cursor;
- if( map.MoveTo(&cursor, key) )
- {
- cursor->value.time += elapsed;
- cursor->value.count++;
- if( cursor->value.max < elapsed )
- cursor->value.max = elapsed;
- if( cursor->value.min > elapsed )
- cursor->value.min = elapsed;
- }
- else
- {
- TimeCount tc = {elapsed, 1, elapsed, elapsed};
- map.Insert(key, tc);
- }
- // Remove the inner most scope from the key
- int n = key.FindLast("|");
- if( n > 0 )
- key.SetLength(n);
- else
- key.SetLength(0);
- // Compensate for the time spent writing to the file
- timeOffset += GetTime() - time;
- }
-
- protected:
- void WriteSummary()
- {
- // Write the analyzed info into a file for inspection
- _mkdir("AS_DEBUG");
- FILE *fp;
- #if _MSC_VER >= 1500 && !defined(AS_MARMALADE)
- fopen_s(&fp, "AS_DEBUG/profiling_summary.txt", "wt");
- #else
- fp = fopen("AS_DEBUG/profiling_summary.txt", "wt");
- #endif
- if( fp == 0 )
- return;
- fprintf(fp, "%-60s %10s %15s %15s %15s %15s\n\n", "Scope", "Count", "Tot time", "Avg time", "Max time", "Min time");
- asSMapNode<asCString, TimeCount> *cursor;
- map.MoveLast(&cursor);
- while( cursor )
- {
- asCString key = cursor->key;
- int count;
- int n = key.FindLast("|", &count);
- if( count )
- {
- key = asCString(" ", count) + key.SubString(n+1);
- }
- fprintf(fp, "%-60s %10d %15.6f %15.6f %15.6f %15.6f\n", key.AddressOf(), cursor->value.count, cursor->value.time, cursor->value.time / cursor->value.count, cursor->value.max, cursor->value.min);
- map.MovePrev(&cursor, cursor);
- }
- fclose(fp);
- }
- double timeOffset;
- double ticksPerSecond;
- bool usePerformance;
- asCString key;
- asCMap<asCString, TimeCount> map;
- };
- extern CProfiler g_profiler;
- class CProfilerScope
- {
- public:
- CProfilerScope(const char *name)
- {
- this->name = name;
- beginTime = g_profiler.Begin(name);
- }
- ~CProfilerScope()
- {
- g_profiler.End(name, beginTime);
- }
- protected:
- const char *name;
- double beginTime;
- };
- #define TimeIt(x) CProfilerScope profilescope(x)
- END_AS_NAMESPACE
- #else // !(_MSC_VER && AS_PROFILE)
- // Define it so nothing is done
- #define TimeIt(x)
- #endif // !(_MSC_VER && AS_PROFILE)
- #endif // defined(AS_DEBUG_H)
|