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