core/smn_profiler.cpp
author Borja Ferrer <faluco@alliedmods.net>
Thu Jul 05 14:47:36 2007 +0000 (2007-07-05)
changeset 1041 f7b2073013df
parent 914 cd241af51653
child 1231 17badaf66ce4
permissions -rw-r--r--
added a time stamp argument to FormatTime
     1 /**
     2  * vim: set ts=4 :
     3  * ===============================================================
     4  * SourceMod (C)2004-2007 AlliedModders LLC.  All rights reserved.
     5  * ===============================================================
     6  *
     7  * This file is not open source and may not be copied without explicit
     8  * written permission of AlliedModders LLC.  This file may not be redistributed 
     9  * in whole or significant part.
    10  * For information, see LICENSE.txt or http://www.sourcemod.net/license.php
    11  *
    12  * Version: $Id$
    13  */
    14 
    15 #include "sm_globals.h"
    16 #include "HandleSys.h"
    17 
    18 //Note: Do not add this to Linux yet, i haven't done the HPET timing research (if even available)
    19 //nonetheless we need accurate counting
    20 #if defined PLATFORM_LINUX
    21 #error "Not supported"
    22 #endif
    23 
    24 struct Profiler
    25 {
    26 	Profiler()
    27 	{
    28 		started = false;
    29 		stopped = false;
    30 	}
    31 #if defined PLATFORM_WINDOWS
    32 	LARGE_INTEGER start;
    33 	LARGE_INTEGER end;
    34 	double freq;
    35 #endif
    36 	bool started;
    37 	bool stopped;
    38 };
    39 
    40 HandleType_t g_ProfilerType = 0;
    41 
    42 class ProfilerHelpers : 
    43 	public SMGlobalClass,
    44 	public IHandleTypeDispatch
    45 {
    46 public:
    47 	void OnSourceModAllInitialized()
    48 	{
    49 		g_ProfilerType = g_HandleSys.CreateType("Profiler", this, 0, NULL, NULL, g_pCoreIdent, NULL);
    50 	}
    51 	void OnSourceModShutdown()
    52 	{
    53 		g_HandleSys.RemoveType(g_ProfilerType, g_pCoreIdent);
    54 	}
    55 	void OnHandleDestroy(HandleType_t type, void *object)
    56 	{
    57 		Profiler *prof = (Profiler *)object;
    58 		delete prof;
    59 	}
    60 } s_ProfHelpers;
    61 
    62 static cell_t CreateProfiler(IPluginContext *pContext, const cell_t *params)
    63 {
    64 	Profiler *p = new Profiler();
    65 
    66 #if defined PLATFORM_WINDOWS
    67 	LARGE_INTEGER qpf;
    68 	QueryPerformanceFrequency(&qpf);
    69 	p->freq = 1.0 / (double)(qpf.QuadPart);
    70 #endif
    71 
    72 	Handle_t hndl = g_HandleSys.CreateHandle(g_ProfilerType, p, pContext->GetIdentity(), g_pCoreIdent, NULL);
    73 	if (hndl == BAD_HANDLE)
    74 	{
    75 		delete p;
    76 	}
    77 
    78 	return hndl;
    79 }
    80 
    81 static cell_t StartProfiling(IPluginContext *pContext, const cell_t *params)
    82 {
    83 	Handle_t hndl = params[1];
    84 	HandleSecurity sec = HandleSecurity(pContext->GetIdentity(), g_pCoreIdent);
    85 	HandleError err;
    86 	Profiler *prof;
    87 
    88 	if ((err = g_HandleSys.ReadHandle(hndl, g_ProfilerType, &sec, (void **)&prof))
    89 		!= HandleError_None)
    90 	{
    91 		return pContext->ThrowNativeError("Invalid Handle %x (error %d)", hndl, err);
    92 	}
    93 
    94 #if defined PLATFORM_WINDOWS
    95 	QueryPerformanceCounter(&prof->start);
    96 #endif
    97 
    98 	prof->started = true;
    99 	prof->stopped = false;
   100 
   101 	return 1;
   102 }
   103 
   104 static cell_t StopProfiling(IPluginContext *pContext, const cell_t *params)
   105 {
   106 	Handle_t hndl = params[1];
   107 	HandleSecurity sec = HandleSecurity(pContext->GetIdentity(), g_pCoreIdent);
   108 	HandleError err;
   109 	Profiler *prof;
   110 
   111 	if ((err = g_HandleSys.ReadHandle(hndl, g_ProfilerType, &sec, (void **)&prof))
   112 		!= HandleError_None)
   113 	{
   114 		return pContext->ThrowNativeError("Invalid Handle %x (error %d)", hndl, err);
   115 	}
   116 
   117 	if (!prof->started)
   118 	{
   119 		return pContext->ThrowNativeError("Profiler was never started");
   120 	}
   121 
   122 #if defined PLATFORM_WINDOWS
   123 	QueryPerformanceCounter(&prof->end);
   124 #endif
   125 
   126 	prof->started = false;
   127 	prof->stopped = true;
   128 
   129 	return 1;
   130 }
   131 
   132 static cell_t GetProfilerTime(IPluginContext *pContext, const cell_t *params)
   133 {
   134 	Handle_t hndl = params[1];
   135 	HandleSecurity sec = HandleSecurity(pContext->GetIdentity(), g_pCoreIdent);
   136 	HandleError err;
   137 	Profiler *prof;
   138 
   139 	if ((err = g_HandleSys.ReadHandle(hndl, g_ProfilerType, &sec, (void **)&prof))
   140 		!= HandleError_None)
   141 	{
   142 		return pContext->ThrowNativeError("Invalid Handle %x (error %d)", hndl, err);
   143 	}
   144 
   145 	if (!prof->stopped)
   146 	{
   147 		return pContext->ThrowNativeError("Profiler was never stopped");
   148 	}
   149 
   150 	float fTime;
   151 
   152 #if defined PLATFORM_WINDOWS
   153 	LONGLONG diff = prof->end.QuadPart - prof->start.QuadPart;
   154 	double seconds = diff * prof->freq;
   155 	fTime = (float)seconds;
   156 #endif
   157 
   158 	return sp_ftoc(fTime);
   159 }
   160 
   161 REGISTER_NATIVES(profilerNatives)
   162 {
   163 	{"CreateProfiler",			CreateProfiler},
   164 	{"GetProfilerTime",			GetProfilerTime},
   165 	{"StartProfiling",			StartProfiling},
   166 	{"StopProfiling",			StopProfiling},
   167 	{NULL,						NULL},
   168 };