1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/js/src/vtune/jitprofiling.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,528 @@ 1.4 +/* 1.5 + This file is provided under a dual BSD/GPLv2 license. When using or 1.6 + redistributing this file, you may do so under either license. 1.7 + 1.8 + GPL LICENSE SUMMARY 1.9 + 1.10 + Copyright (c) 2005-2012 Intel Corporation. All rights reserved. 1.11 + 1.12 + This program is free software; you can redistribute it and/or modify 1.13 + it under the terms of version 2 of the GNU General Public License as 1.14 + published by the Free Software Foundation. 1.15 + 1.16 + This program is distributed in the hope that it will be useful, but 1.17 + WITHOUT ANY WARRANTY; without even the implied warranty of 1.18 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1.19 + General Public License for more details. 1.20 + 1.21 + You should have received a copy of the GNU General Public License 1.22 + along with this program; if not, write to the Free Software 1.23 + Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 1.24 + The full GNU General Public License is included in this distribution 1.25 + in the file called LICENSE.GPL. 1.26 + 1.27 + Contact Information: 1.28 + http://software.intel.com/en-us/articles/intel-vtune-amplifier-xe/ 1.29 + 1.30 + BSD LICENSE 1.31 + 1.32 + Copyright (c) 2005-2012 Intel Corporation. All rights reserved. 1.33 + All rights reserved. 1.34 + 1.35 + Redistribution and use in source and binary forms, with or without 1.36 + modification, are permitted provided that the following conditions 1.37 + are met: 1.38 + 1.39 + * Redistributions of source code must retain the above copyright 1.40 + notice, this list of conditions and the following disclaimer. 1.41 + * Redistributions in binary form must reproduce the above copyright 1.42 + notice, this list of conditions and the following disclaimer in 1.43 + the documentation and/or other materials provided with the 1.44 + distribution. 1.45 + * Neither the name of Intel Corporation nor the names of its 1.46 + contributors may be used to endorse or promote products derived 1.47 + from this software without specific prior written permission. 1.48 + 1.49 + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1.50 + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1.51 + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1.52 + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 1.53 + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 1.54 + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 1.55 + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 1.56 + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 1.57 + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 1.58 + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 1.59 + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 1.60 +*/ 1.61 +#include "vtune/ittnotify_config.h" 1.62 + 1.63 +#if ITT_PLATFORM==ITT_PLATFORM_WIN 1.64 +#include <windows.h> 1.65 +#pragma optimize("", off) 1.66 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 1.67 +#include <pthread.h> 1.68 +#include <dlfcn.h> 1.69 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 1.70 +#include <malloc.h> 1.71 +#include <stdlib.h> 1.72 + 1.73 +#include "vtune/jitprofiling.h" 1.74 + 1.75 +static const char rcsid[] = "\n@(#) $Revision: 294150 $\n"; 1.76 + 1.77 +#define DLL_ENVIRONMENT_VAR "VS_PROFILER" 1.78 + 1.79 +#ifndef NEW_DLL_ENVIRONMENT_VAR 1.80 +#if ITT_ARCH==ITT_ARCH_IA32 1.81 +#define NEW_DLL_ENVIRONMENT_VAR "INTEL_JIT_PROFILER32" 1.82 +#else 1.83 +#define NEW_DLL_ENVIRONMENT_VAR "INTEL_JIT_PROFILER64" 1.84 +#endif 1.85 +#endif /* NEW_DLL_ENVIRONMENT_VAR */ 1.86 + 1.87 +#if ITT_PLATFORM==ITT_PLATFORM_WIN 1.88 +#define DEFAULT_DLLNAME "JitPI.dll" 1.89 +HINSTANCE m_libHandle = NULL; 1.90 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 1.91 +#define DEFAULT_DLLNAME "libJitPI.so" 1.92 +void* m_libHandle = NULL; 1.93 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 1.94 + 1.95 +/* default location of JIT profiling agent on Android */ 1.96 +#define ANDROID_JIT_AGENT_PATH "/data/intel/libittnotify.so" 1.97 + 1.98 +/* the function pointers */ 1.99 +typedef unsigned int(*TPInitialize)(void); 1.100 +static TPInitialize FUNC_Initialize=NULL; 1.101 + 1.102 +typedef unsigned int(*TPNotify)(unsigned int, void*); 1.103 +static TPNotify FUNC_NotifyEvent=NULL; 1.104 + 1.105 +static iJIT_IsProfilingActiveFlags executionMode = iJIT_NOTHING_RUNNING; 1.106 + 1.107 +/* end collector dll part. */ 1.108 + 1.109 +/* loadiJIT_Funcs() : this function is called just in the beginning 1.110 + * and is responsible to load the functions from BistroJavaCollector.dll 1.111 + * result: 1.112 + * on success: the functions loads, iJIT_DLL_is_missing=0, return value = 1 1.113 + * on failure: the functions are NULL, iJIT_DLL_is_missing=1, return value = 0 1.114 + */ 1.115 +static int loadiJIT_Funcs(void); 1.116 + 1.117 +/* global representing whether the BistroJavaCollector can't be loaded */ 1.118 +static int iJIT_DLL_is_missing = 0; 1.119 + 1.120 +/* Virtual stack - the struct is used as a virtual stack for each thread. 1.121 + * Every thread initializes with a stack of size INIT_TOP_STACK. 1.122 + * Every method entry decreases from the current stack point, 1.123 + * and when a thread stack reaches its top of stack (return from the global 1.124 + * function), the top of stack and the current stack increase. Notice that 1.125 + * when returning from a function the stack pointer is the address of 1.126 + * the function return. 1.127 +*/ 1.128 +#if ITT_PLATFORM==ITT_PLATFORM_WIN 1.129 +static DWORD threadLocalStorageHandle = 0; 1.130 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 1.131 +static pthread_key_t threadLocalStorageHandle = (pthread_key_t)0; 1.132 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 1.133 + 1.134 +#define INIT_TOP_Stack 10000 1.135 + 1.136 +typedef struct 1.137 +{ 1.138 + unsigned int TopStack; 1.139 + unsigned int CurrentStack; 1.140 +} ThreadStack, *pThreadStack; 1.141 + 1.142 +/* end of virtual stack. */ 1.143 + 1.144 +/* 1.145 + * The function for reporting virtual-machine related events to VTune. 1.146 + * Note: when reporting iJVM_EVENT_TYPE_ENTER_NIDS, there is no need to fill 1.147 + * in the stack_id field in the iJIT_Method_NIDS structure, as VTune fills it. 1.148 + * The return value in iJVM_EVENT_TYPE_ENTER_NIDS && 1.149 + * iJVM_EVENT_TYPE_LEAVE_NIDS events will be 0 in case of failure. 1.150 + * in iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED event 1.151 + * it will be -1 if EventSpecificData == 0 otherwise it will be 0. 1.152 +*/ 1.153 + 1.154 +ITT_EXTERN_C int JITAPI 1.155 +iJIT_NotifyEvent(iJIT_JVM_EVENT event_type, void *EventSpecificData) 1.156 +{ 1.157 + int ReturnValue; 1.158 + 1.159 + /* 1.160 + * This section is for debugging outside of VTune. 1.161 + * It creates the environment variables that indicates call graph mode. 1.162 + * If running outside of VTune remove the remark. 1.163 + * 1.164 + * 1.165 + * static int firstTime = 1; 1.166 + * char DoCallGraph[12] = "DoCallGraph"; 1.167 + * if (firstTime) 1.168 + * { 1.169 + * firstTime = 0; 1.170 + * SetEnvironmentVariable( "BISTRO_COLLECTORS_DO_CALLGRAPH", DoCallGraph); 1.171 + * } 1.172 + * 1.173 + * end of section. 1.174 + */ 1.175 + 1.176 + /* initialization part - the functions have not been loaded yet. This part 1.177 + * will load the functions, and check if we are in Call Graph mode. 1.178 + * (for special treatment). 1.179 + */ 1.180 + if (!FUNC_NotifyEvent) 1.181 + { 1.182 + if (iJIT_DLL_is_missing) 1.183 + return 0; 1.184 + 1.185 + /* load the Function from the DLL */ 1.186 + if (!loadiJIT_Funcs()) 1.187 + return 0; 1.188 + 1.189 + /* Call Graph initialization. */ 1.190 + } 1.191 + 1.192 + /* If the event is method entry/exit, check that in the current mode 1.193 + * VTune is allowed to receive it 1.194 + */ 1.195 + if ((event_type == iJVM_EVENT_TYPE_ENTER_NIDS || 1.196 + event_type == iJVM_EVENT_TYPE_LEAVE_NIDS) && 1.197 + (executionMode != iJIT_CALLGRAPH_ON)) 1.198 + { 1.199 + return 0; 1.200 + } 1.201 + /* This section is performed when method enter event occurs. 1.202 + * It updates the virtual stack, or creates it if this is the first 1.203 + * method entry in the thread. The stack pointer is decreased. 1.204 + */ 1.205 + if (event_type == iJVM_EVENT_TYPE_ENTER_NIDS) 1.206 + { 1.207 +#if ITT_PLATFORM==ITT_PLATFORM_WIN 1.208 + pThreadStack threadStack = 1.209 + (pThreadStack)TlsGetValue (threadLocalStorageHandle); 1.210 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 1.211 + pThreadStack threadStack = 1.212 + (pThreadStack)pthread_getspecific(threadLocalStorageHandle); 1.213 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 1.214 + 1.215 + /* check for use of reserved method IDs */ 1.216 + if ( ((piJIT_Method_NIDS) EventSpecificData)->method_id <= 999 ) 1.217 + return 0; 1.218 + 1.219 + if (!threadStack) 1.220 + { 1.221 + /* initialize the stack. */ 1.222 + threadStack = (pThreadStack) calloc (sizeof(ThreadStack), 1); 1.223 + if (!threadStack) 1.224 + return 0; 1.225 + threadStack->TopStack = INIT_TOP_Stack; 1.226 + threadStack->CurrentStack = INIT_TOP_Stack; 1.227 +#if ITT_PLATFORM==ITT_PLATFORM_WIN 1.228 + TlsSetValue(threadLocalStorageHandle,(void*)threadStack); 1.229 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 1.230 + pthread_setspecific(threadLocalStorageHandle,(void*)threadStack); 1.231 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 1.232 + } 1.233 + 1.234 + /* decrease the stack. */ 1.235 + ((piJIT_Method_NIDS) EventSpecificData)->stack_id = 1.236 + (threadStack->CurrentStack)--; 1.237 + } 1.238 + 1.239 + /* This section is performed when method leave event occurs 1.240 + * It updates the virtual stack. 1.241 + * Increases the stack pointer. 1.242 + * If the stack pointer reached the top (left the global function) 1.243 + * increase the pointer and the top pointer. 1.244 + */ 1.245 + if (event_type == iJVM_EVENT_TYPE_LEAVE_NIDS) 1.246 + { 1.247 +#if ITT_PLATFORM==ITT_PLATFORM_WIN 1.248 + pThreadStack threadStack = 1.249 + (pThreadStack)TlsGetValue (threadLocalStorageHandle); 1.250 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 1.251 + pThreadStack threadStack = 1.252 + (pThreadStack)pthread_getspecific(threadLocalStorageHandle); 1.253 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 1.254 + 1.255 + /* check for use of reserved method IDs */ 1.256 + if ( ((piJIT_Method_NIDS) EventSpecificData)->method_id <= 999 ) 1.257 + return 0; 1.258 + 1.259 + if (!threadStack) 1.260 + { 1.261 + /* Error: first report in this thread is method exit */ 1.262 + exit (1); 1.263 + } 1.264 + 1.265 + ((piJIT_Method_NIDS) EventSpecificData)->stack_id = 1.266 + ++(threadStack->CurrentStack) + 1; 1.267 + 1.268 + if (((piJIT_Method_NIDS) EventSpecificData)->stack_id 1.269 + > threadStack->TopStack) 1.270 + ((piJIT_Method_NIDS) EventSpecificData)->stack_id = 1.271 + (unsigned int)-1; 1.272 + } 1.273 + 1.274 + if (event_type == iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED) 1.275 + { 1.276 + /* check for use of reserved method IDs */ 1.277 + if ( ((piJIT_Method_Load) EventSpecificData)->method_id <= 999 ) 1.278 + return 0; 1.279 + } 1.280 + else if (event_type == iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED_V2) 1.281 + { 1.282 + /* check for use of reserved method IDs */ 1.283 + if ( ((piJIT_Method_Load_V2) EventSpecificData)->method_id <= 999 ) 1.284 + return 0; 1.285 + } 1.286 + 1.287 + ReturnValue = (int)FUNC_NotifyEvent(event_type, EventSpecificData); 1.288 + 1.289 + return ReturnValue; 1.290 +} 1.291 + 1.292 +/* The new mode call back routine */ 1.293 +ITT_EXTERN_C void JITAPI 1.294 +iJIT_RegisterCallbackEx(void *userdata, iJIT_ModeChangedEx 1.295 + NewModeCallBackFuncEx) 1.296 +{ 1.297 + /* is it already missing... or the load of functions from the DLL failed */ 1.298 + if (iJIT_DLL_is_missing || !loadiJIT_Funcs()) 1.299 + { 1.300 + /* then do not bother with notifications */ 1.301 + NewModeCallBackFuncEx(userdata, iJIT_NO_NOTIFICATIONS); 1.302 + /* Error: could not load JIT functions. */ 1.303 + return; 1.304 + } 1.305 + /* nothing to do with the callback */ 1.306 +} 1.307 + 1.308 +/* 1.309 + * This function allows the user to query in which mode, if at all, 1.310 + *VTune is running 1.311 + */ 1.312 +ITT_EXTERN_C iJIT_IsProfilingActiveFlags JITAPI iJIT_IsProfilingActive() 1.313 +{ 1.314 + if (!iJIT_DLL_is_missing) 1.315 + { 1.316 + loadiJIT_Funcs(); 1.317 + } 1.318 + 1.319 + return executionMode; 1.320 +} 1.321 + 1.322 +/* this function loads the collector dll (BistroJavaCollector) 1.323 + * and the relevant functions. 1.324 + * on success: all functions load, iJIT_DLL_is_missing = 0, return value = 1 1.325 + * on failure: all functions are NULL, iJIT_DLL_is_missing = 1, return value = 0 1.326 + */ 1.327 +static int loadiJIT_Funcs() 1.328 +{ 1.329 + static int bDllWasLoaded = 0; 1.330 + char *dllName = (char*)rcsid; /* !! Just to avoid unused code elimination */ 1.331 +#if ITT_PLATFORM==ITT_PLATFORM_WIN 1.332 + DWORD dNameLength = 0; 1.333 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 1.334 + 1.335 + if(bDllWasLoaded) 1.336 + { 1.337 + /* dll was already loaded, no need to do it for the second time */ 1.338 + return 1; 1.339 + } 1.340 + 1.341 + /* Assumes that the DLL will not be found */ 1.342 + iJIT_DLL_is_missing = 1; 1.343 + FUNC_NotifyEvent = NULL; 1.344 + 1.345 + if (m_libHandle) 1.346 + { 1.347 +#if ITT_PLATFORM==ITT_PLATFORM_WIN 1.348 + FreeLibrary(m_libHandle); 1.349 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 1.350 + dlclose(m_libHandle); 1.351 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 1.352 + m_libHandle = NULL; 1.353 + } 1.354 + 1.355 + /* Try to get the dll name from the environment */ 1.356 +#if ITT_PLATFORM==ITT_PLATFORM_WIN 1.357 + dNameLength = GetEnvironmentVariableA(NEW_DLL_ENVIRONMENT_VAR, NULL, 0); 1.358 + if (dNameLength) 1.359 + { 1.360 + DWORD envret = 0; 1.361 + dllName = (char*)malloc(sizeof(char) * (dNameLength + 1)); 1.362 + envret = GetEnvironmentVariableA(NEW_DLL_ENVIRONMENT_VAR, 1.363 + dllName, dNameLength); 1.364 + if (envret) 1.365 + { 1.366 + /* Try to load the dll from the PATH... */ 1.367 + m_libHandle = LoadLibraryExA(dllName, 1.368 + NULL, LOAD_WITH_ALTERED_SEARCH_PATH); 1.369 + } 1.370 + free(dllName); 1.371 + } else { 1.372 + /* Try to use old VS_PROFILER variable */ 1.373 + dNameLength = GetEnvironmentVariableA(DLL_ENVIRONMENT_VAR, NULL, 0); 1.374 + if (dNameLength) 1.375 + { 1.376 + DWORD envret = 0; 1.377 + dllName = (char*)malloc(sizeof(char) * (dNameLength + 1)); 1.378 + envret = GetEnvironmentVariableA(DLL_ENVIRONMENT_VAR, 1.379 + dllName, dNameLength); 1.380 + if (envret) 1.381 + { 1.382 + /* Try to load the dll from the PATH... */ 1.383 + m_libHandle = LoadLibraryA(dllName); 1.384 + } 1.385 + free(dllName); 1.386 + } 1.387 + } 1.388 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 1.389 + dllName = getenv(NEW_DLL_ENVIRONMENT_VAR); 1.390 + if (!dllName) 1.391 + dllName = getenv(DLL_ENVIRONMENT_VAR); 1.392 +#ifdef ANDROID 1.393 + if (!dllName) 1.394 + dllName = ANDROID_JIT_AGENT_PATH; 1.395 +#endif 1.396 + if (dllName) 1.397 + { 1.398 + /* Try to load the dll from the PATH... */ 1.399 + m_libHandle = dlopen(dllName, RTLD_LAZY); 1.400 + } 1.401 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 1.402 + 1.403 + if (!m_libHandle) 1.404 + { 1.405 +#if ITT_PLATFORM==ITT_PLATFORM_WIN 1.406 + m_libHandle = LoadLibraryA(DEFAULT_DLLNAME); 1.407 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 1.408 + m_libHandle = dlopen(DEFAULT_DLLNAME, RTLD_LAZY); 1.409 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 1.410 + } 1.411 + 1.412 + /* if the dll wasn't loaded - exit. */ 1.413 + if (!m_libHandle) 1.414 + { 1.415 + iJIT_DLL_is_missing = 1; /* don't try to initialize 1.416 + * JIT agent the second time 1.417 + */ 1.418 + return 0; 1.419 + } 1.420 + 1.421 +#if ITT_PLATFORM==ITT_PLATFORM_WIN 1.422 + FUNC_NotifyEvent = (TPNotify)GetProcAddress(m_libHandle, "NotifyEvent"); 1.423 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 1.424 + FUNC_NotifyEvent = (TPNotify)dlsym(m_libHandle, "NotifyEvent"); 1.425 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 1.426 + if (!FUNC_NotifyEvent) 1.427 + { 1.428 + FUNC_Initialize = NULL; 1.429 + return 0; 1.430 + } 1.431 + 1.432 +#if ITT_PLATFORM==ITT_PLATFORM_WIN 1.433 + FUNC_Initialize = (TPInitialize)GetProcAddress(m_libHandle, "Initialize"); 1.434 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 1.435 + FUNC_Initialize = (TPInitialize)dlsym(m_libHandle, "Initialize"); 1.436 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 1.437 + if (!FUNC_Initialize) 1.438 + { 1.439 + FUNC_NotifyEvent = NULL; 1.440 + return 0; 1.441 + } 1.442 + 1.443 + executionMode = (iJIT_IsProfilingActiveFlags)FUNC_Initialize(); 1.444 + 1.445 + bDllWasLoaded = 1; 1.446 + iJIT_DLL_is_missing = 0; /* DLL is ok. */ 1.447 + 1.448 + /* 1.449 + * Call Graph mode: init the thread local storage 1.450 + * (need to store the virtual stack there). 1.451 + */ 1.452 + if ( executionMode == iJIT_CALLGRAPH_ON ) 1.453 + { 1.454 + /* Allocate a thread local storage slot for the thread "stack" */ 1.455 + if (!threadLocalStorageHandle) 1.456 +#if ITT_PLATFORM==ITT_PLATFORM_WIN 1.457 + threadLocalStorageHandle = TlsAlloc(); 1.458 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 1.459 + pthread_key_create(&threadLocalStorageHandle, NULL); 1.460 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 1.461 + } 1.462 + 1.463 + return 1; 1.464 +} 1.465 + 1.466 +/* 1.467 + * This function should be called by the user whenever a thread ends, 1.468 + * to free the thread "virtual stack" storage 1.469 + */ 1.470 +ITT_EXTERN_C void JITAPI FinalizeThread() 1.471 +{ 1.472 + if (threadLocalStorageHandle) 1.473 + { 1.474 +#if ITT_PLATFORM==ITT_PLATFORM_WIN 1.475 + pThreadStack threadStack = 1.476 + (pThreadStack)TlsGetValue (threadLocalStorageHandle); 1.477 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 1.478 + pThreadStack threadStack = 1.479 + (pThreadStack)pthread_getspecific(threadLocalStorageHandle); 1.480 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 1.481 + if (threadStack) 1.482 + { 1.483 + free (threadStack); 1.484 + threadStack = NULL; 1.485 +#if ITT_PLATFORM==ITT_PLATFORM_WIN 1.486 + TlsSetValue (threadLocalStorageHandle, threadStack); 1.487 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 1.488 + pthread_setspecific(threadLocalStorageHandle, threadStack); 1.489 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 1.490 + } 1.491 + } 1.492 +} 1.493 + 1.494 +/* 1.495 + * This function should be called by the user when the process ends, 1.496 + * to free the local storage index 1.497 +*/ 1.498 +ITT_EXTERN_C void JITAPI FinalizeProcess() 1.499 +{ 1.500 + if (m_libHandle) 1.501 + { 1.502 +#if ITT_PLATFORM==ITT_PLATFORM_WIN 1.503 + FreeLibrary(m_libHandle); 1.504 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 1.505 + dlclose(m_libHandle); 1.506 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 1.507 + m_libHandle = NULL; 1.508 + } 1.509 + 1.510 + if (threadLocalStorageHandle) 1.511 +#if ITT_PLATFORM==ITT_PLATFORM_WIN 1.512 + TlsFree (threadLocalStorageHandle); 1.513 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 1.514 + pthread_key_delete(threadLocalStorageHandle); 1.515 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 1.516 +} 1.517 + 1.518 +/* 1.519 + * This function should be called by the user for any method once. 1.520 + * The function will return a unique method ID, the user should maintain 1.521 + * the ID for each method 1.522 + */ 1.523 +ITT_EXTERN_C unsigned int JITAPI iJIT_GetNewMethodID() 1.524 +{ 1.525 + static unsigned int methodID = 0x100000; 1.526 + 1.527 + if (methodID == 0) 1.528 + return 0; /* ERROR : this is not a valid value */ 1.529 + 1.530 + return methodID++; 1.531 +}