core/smn_profiler.cpp
author Michael McKoy <ferret99gt@gmail.com>
Wed Aug 08 23:45:24 2007 +0000 (2007-08-08)
changeset 1284 ac293d8351a3
parent 1231 17badaf66ce4
child 1330 ab94316bb52b
permissions -rw-r--r--
Import of baseplugins.sp
     1 /**
     2  * vim: set ts=4 :
     3  * ================================================================
     4  * SourceMod
     5  * Copyright (C) 2004-2007 AlliedModders LLC.  All rights reserved.
     6  * ================================================================
     7  *
     8  * This program is free software; you can redistribute it and/or 
     9  * modify it under the terms of the GNU General Public License, 
    10  * version 3.0, as published by the Free Software Foundation.
    11  * 
    12  * This program is distributed in the hope that it will be useful,
    13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    15  * GNU General Public License for more details.
    16  *
    17  * You should have received a copy of the GNU General Public License
    18  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    19  *
    20  * As a special exception, AlliedModders LLC gives you permission to 
    21  * link the code of this program (as well as its derivative works) to 
    22  * "Half-Life 2," the "Source Engine," the "SourcePawn JIT," and any 
    23  * Game MODs that run on software by the Valve Corporation.  You must 
    24  * obey the GNU General Public License in all respects for all other 
    25  * code used. Additionally, AlliedModders LLC grants this exception 
    26  * to all derivative works. AlliedModders LLC defines further 
    27  * exceptions, found in LICENSE.txt (as of this writing, version 
    28  * JULY-31-2007), or <http://www.sourcemod.net/license.php>.
    29  *
    30  * Version: $Id$
    31  */
    32 
    33 #include "sm_globals.h"
    34 #include "HandleSys.h"
    35 
    36 //Note: Do not add this to Linux yet, i haven't done the HPET timing research (if even available)
    37 //nonetheless we need accurate counting
    38 #if defined PLATFORM_LINUX
    39 #error "Not supported"
    40 #endif
    41 
    42 struct Profiler
    43 {
    44 	Profiler()
    45 	{
    46 		started = false;
    47 		stopped = false;
    48 	}
    49 #if defined PLATFORM_WINDOWS
    50 	LARGE_INTEGER start;
    51 	LARGE_INTEGER end;
    52 	double freq;
    53 #endif
    54 	bool started;
    55 	bool stopped;
    56 };
    57 
    58 HandleType_t g_ProfilerType = 0;
    59 
    60 class ProfilerHelpers : 
    61 	public SMGlobalClass,
    62 	public IHandleTypeDispatch
    63 {
    64 public:
    65 	void OnSourceModAllInitialized()
    66 	{
    67 		g_ProfilerType = g_HandleSys.CreateType("Profiler", this, 0, NULL, NULL, g_pCoreIdent, NULL);
    68 	}
    69 	void OnSourceModShutdown()
    70 	{
    71 		g_HandleSys.RemoveType(g_ProfilerType, g_pCoreIdent);
    72 	}
    73 	void OnHandleDestroy(HandleType_t type, void *object)
    74 	{
    75 		Profiler *prof = (Profiler *)object;
    76 		delete prof;
    77 	}
    78 } s_ProfHelpers;
    79 
    80 static cell_t CreateProfiler(IPluginContext *pContext, const cell_t *params)
    81 {
    82 	Profiler *p = new Profiler();
    83 
    84 #if defined PLATFORM_WINDOWS
    85 	LARGE_INTEGER qpf;
    86 	QueryPerformanceFrequency(&qpf);
    87 	p->freq = 1.0 / (double)(qpf.QuadPart);
    88 #endif
    89 
    90 	Handle_t hndl = g_HandleSys.CreateHandle(g_ProfilerType, p, pContext->GetIdentity(), g_pCoreIdent, NULL);
    91 	if (hndl == BAD_HANDLE)
    92 	{
    93 		delete p;
    94 	}
    95 
    96 	return hndl;
    97 }
    98 
    99 static cell_t StartProfiling(IPluginContext *pContext, const cell_t *params)
   100 {
   101 	Handle_t hndl = params[1];
   102 	HandleSecurity sec = HandleSecurity(pContext->GetIdentity(), g_pCoreIdent);
   103 	HandleError err;
   104 	Profiler *prof;
   105 
   106 	if ((err = g_HandleSys.ReadHandle(hndl, g_ProfilerType, &sec, (void **)&prof))
   107 		!= HandleError_None)
   108 	{
   109 		return pContext->ThrowNativeError("Invalid Handle %x (error %d)", hndl, err);
   110 	}
   111 
   112 #if defined PLATFORM_WINDOWS
   113 	QueryPerformanceCounter(&prof->start);
   114 #endif
   115 
   116 	prof->started = true;
   117 	prof->stopped = false;
   118 
   119 	return 1;
   120 }
   121 
   122 static cell_t StopProfiling(IPluginContext *pContext, const cell_t *params)
   123 {
   124 	Handle_t hndl = params[1];
   125 	HandleSecurity sec = HandleSecurity(pContext->GetIdentity(), g_pCoreIdent);
   126 	HandleError err;
   127 	Profiler *prof;
   128 
   129 	if ((err = g_HandleSys.ReadHandle(hndl, g_ProfilerType, &sec, (void **)&prof))
   130 		!= HandleError_None)
   131 	{
   132 		return pContext->ThrowNativeError("Invalid Handle %x (error %d)", hndl, err);
   133 	}
   134 
   135 	if (!prof->started)
   136 	{
   137 		return pContext->ThrowNativeError("Profiler was never started");
   138 	}
   139 
   140 #if defined PLATFORM_WINDOWS
   141 	QueryPerformanceCounter(&prof->end);
   142 #endif
   143 
   144 	prof->started = false;
   145 	prof->stopped = true;
   146 
   147 	return 1;
   148 }
   149 
   150 static cell_t GetProfilerTime(IPluginContext *pContext, const cell_t *params)
   151 {
   152 	Handle_t hndl = params[1];
   153 	HandleSecurity sec = HandleSecurity(pContext->GetIdentity(), g_pCoreIdent);
   154 	HandleError err;
   155 	Profiler *prof;
   156 
   157 	if ((err = g_HandleSys.ReadHandle(hndl, g_ProfilerType, &sec, (void **)&prof))
   158 		!= HandleError_None)
   159 	{
   160 		return pContext->ThrowNativeError("Invalid Handle %x (error %d)", hndl, err);
   161 	}
   162 
   163 	if (!prof->stopped)
   164 	{
   165 		return pContext->ThrowNativeError("Profiler was never stopped");
   166 	}
   167 
   168 	float fTime;
   169 
   170 #if defined PLATFORM_WINDOWS
   171 	LONGLONG diff = prof->end.QuadPart - prof->start.QuadPart;
   172 	double seconds = diff * prof->freq;
   173 	fTime = (float)seconds;
   174 #endif
   175 
   176 	return sp_ftoc(fTime);
   177 }
   178 
   179 REGISTER_NATIVES(profilerNatives)
   180 {
   181 	{"CreateProfiler",			CreateProfiler},
   182 	{"GetProfilerTime",			GetProfilerTime},
   183 	{"StartProfiling",			StartProfiling},
   184 	{"StopProfiling",			StopProfiling},
   185 	{NULL,						NULL},
   186 };