|
|
|||
File indexing completed on 2026-05-10 08:45:13
0001 /* 0002 * SPDX-FileCopyrightText: Copyright (c) 2009-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 0003 * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 0004 * 0005 * Licensed under the Apache License, Version 2.0 (the "License"); 0006 * you may not use this file except in compliance with the License. 0007 * You may obtain a copy of the License at 0008 * 0009 * http://www.apache.org/licenses/LICENSE-2.0 0010 * 0011 * Unless required by applicable law or agreed to in writing, software 0012 * distributed under the License is distributed on an "AS IS" BASIS, 0013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 0014 * See the License for the specific language governing permissions and 0015 * limitations under the License. 0016 * 0017 * Licensed under the Apache License v2.0 with LLVM Exceptions. 0018 * See https://nvidia.github.io/NVTX/LICENSE.txt for license information. 0019 */ 0020 0021 #ifndef NVTX_IMPL_GUARD 0022 #error Never include this file directly -- it is automatically included by nvToolsExt.h (except when NVTX_NO_IMPL is defined). 0023 #endif 0024 0025 #if defined(NVTX_AS_SYSTEM_HEADER) 0026 #if defined(__clang__) 0027 #pragma clang system_header 0028 #elif defined(__GNUC__) || defined(__NVCOMPILER) 0029 #pragma GCC system_header 0030 #elif defined(_MSC_VER) 0031 #pragma system_header 0032 #endif 0033 #endif 0034 0035 /* ---- Platform-independent helper definitions and functions ---- */ 0036 0037 /* Prefer macros over inline functions to reduce symbol resolution at link time */ 0038 0039 #if defined(_WIN32) 0040 #define NVTX_PATHCHAR wchar_t 0041 #define NVTX_STR(x) L##x 0042 #define NVTX_GETENV _wgetenv 0043 #define NVTX_BUFSIZE 16384 0044 #define NVTX_DLLHANDLE HMODULE 0045 #define NVTX_DLLOPEN(x) LoadLibraryW(x) 0046 #define NVTX_DLLFUNC(h, x) NVTX_REINTERPRET_CAST(void(*)(void), GetProcAddress((h), (x))) 0047 #define NVTX_DLLCLOSE FreeLibrary 0048 #define NVTX_DLLDEFAULT NVTX_NULLPTR 0049 #define NVTX_YIELD() SwitchToThread() 0050 #define NVTX_MEMBAR() MemoryBarrier() 0051 #define NVTX_ATOMIC_WRITE_32(address, value) \ 0052 InterlockedExchange(NVTX_REINTERPRET_CAST(volatile LONG*, (address)), (value)) 0053 #define NVTX_ATOMIC_CAS_32(old, address, exchange, comparand) \ 0054 (old) = InterlockedCompareExchange(NVTX_REINTERPRET_CAST(volatile LONG*, (address)), (exchange), (comparand)) 0055 #elif defined(__GNUC__) 0056 #define NVTX_PATHCHAR char 0057 #define NVTX_STR(x) x 0058 #define NVTX_GETENV getenv 0059 #define NVTX_BUFSIZE 16384 0060 #define NVTX_DLLHANDLE void* 0061 #define NVTX_DLLOPEN(x) dlopen(x, RTLD_LAZY) 0062 #define NVTX_DLLFUNC(h, x) dlsym((h), (x)) 0063 #define NVTX_DLLCLOSE dlclose 0064 #if !defined(__APPLE__) 0065 #define NVTX_DLLDEFAULT NVTX_NULLPTR 0066 #else 0067 #define NVTX_DLLDEFAULT RTLD_DEFAULT 0068 #endif 0069 #define NVTX_YIELD() sched_yield() 0070 #define NVTX_MEMBAR() __sync_synchronize() 0071 /* Ensure full memory barrier for atomics, to match Windows functions */ 0072 #define NVTX_ATOMIC_WRITE_32(address, value) \ 0073 __sync_synchronize(); *(address) = (value); __sync_synchronize() 0074 #define NVTX_ATOMIC_CAS_32(old, address, exchange, comparand) \ 0075 (old) = __sync_val_compare_and_swap((address), (comparand), (exchange)) 0076 #else 0077 #error The library does not support your configuration! 0078 #endif 0079 0080 /* NVTX_LOAD_SEQUENCE_VERSION macro 0081 * 0082 * NVTX3 can update the search sequence used for finding a suitable injection library. 0083 * If multiple copies of the NVTX3 headers are included in the same translation unit, 0084 * the one included first sets the loader sequence. If there is any problem where a 0085 * tool is expected to load, but is not loading, the app can test this macro to verify 0086 * which version of the search is being used. Check if NVTX_LOAD_SEQUENCE_VERSION is 0087 * defined; if it is not, the version is 1. Otherwise, the version is indicated by 0088 * the value of NVTX_LOAD_SEQUENCE_VERSION. 0089 * 0090 * Version history: 0091 * 1: NVTX3 initial implementation. The search continues until a usable function 0092 * pointer is found. If none is found, init aborts and rolls back anything it 0093 * did during the search (e.g. any loaded libraries are unloaded). If a non-zero 0094 * function pointer is found, it is called. If that function returns non-zero 0095 * ("true" in C), that indicates a tool successfully initialized. If it returns 0096 * zero ("false"), the tool init was unsuccessful, so init aborts and rolls back 0097 * anything it did. No further attempt is made to search for a different init 0098 * function if the first one found returns false. The search order is: 0099 * - Check for env var NVTX_INJECTION64_PATH (or "32" in 32-bit process) 0100 * - Treat env var value as path to dynamic library, try loading it 0101 * - If it loads, try get the exported symbol "InitializeInjectionNvtx2" 0102 * - If this returns a non-null pointer, the search finishes here 0103 * - (Android only) Look for libNvtxInjection64.so (or "32" in 32-bit process) 0104 * - Must be in the /data/data/<package name>/files" directory 0105 * - Treat env var value as path to dynamic library, try loading it 0106 * - If it loads, try get the exported symbol "InitializeInjectionNvtx2" 0107 * - If this returns a non-null pointer, the search finishes here 0108 * Note: There were two other options partially implemented, but disabled. 0109 * - For supporting a pre-injected library on POSIX platforms, e.g. with 0110 * LD_PRELOAD, try using dlsym with a null module handle to get the init 0111 * function. This was unconditionally disabled after finding cases where 0112 * a tool loaded multiple injections that supported NVTX, and couldn't 0113 * control which one was getting picked by the NVTX loader. 0114 * - (Linux only, not including Cygwin) Check for static injection using a 0115 * weak symbol. This was implemented incorrectly, so it wasn't usable. 0116 * 0117 * 2: Fix the support for static injection libraries. This is meant for cases 0118 * where dlopen is not supported or allowed, and the executable format has 0119 * support for weak symbols. Tools may provide a static library with a 0120 * C-linkage symbol named "InitializeInjectionNvtx2_fnptr", whose type is 0121 * NvtxInitializeInjectionNvtxFunc_t, i.e. a function pointer to NVTX init 0122 * function. If such a symbol is provided by a static library, the NVTX 0123 * loader's weak symbol will bind to it and call it for initialization. 0124 * Otherwise, the weak symbol will be defined by NVTX and default to null, 0125 * indicating no static injection library is present. Static injection is 0126 * last in the load sequence, because it gives all the run-time methods of 0127 * injection to override a program's compiled-in tool without rebuilding the 0128 * program. The search order is: 0129 * - Check for env var NVTX_INJECTION64_PATH (or "32" in 32-bit process) 0130 * - Treat env var value as path to dynamic library, try loading it 0131 * - If it loads, try get the exported symbol "InitializeInjectionNvtx2" 0132 * - If this returns a non-null pointer, the search finishes here 0133 * - (Android only) Look for libNvtxInjection64.so (or "32" in 32-bit process) 0134 * - Must be in the /data/data/<package name>/files" directory 0135 * - Treat env var value as path to dynamic library, try loading it 0136 * - If it loads, try get the exported symbol "InitializeInjectionNvtx2" 0137 * - If this returns a non-null pointer, the search finishes here 0138 * - (Currently disabled, experimental support for non-Windows) Use dlsym 0139 * with a null module handle to query the process-wide dynamic symbol 0140 * table for a function named "InitializeInjectionNvtx2Preinject". The 0141 * symbol is different to prevent injections from being loaded this way 0142 * unless they choose to do so. 0143 * - If this returns a non-null pointer, the search finishes here 0144 * - (GCC-like compilers with ELF binary targets only) Check for static 0145 * injection using a weak symbol "InitializeInjectionNvtx2_fnptr". 0146 * If the default support choices in this header are not working as expected, 0147 * clients may now override load sequence support decisions by defining these 0148 * macros before including the NVTX header files: 0149 * - NVTX_SUPPORT_ENV_VARS 0150 * - NVTX_SUPPORT_DYNAMIC_INJECTION_LIBRARY 0151 * - NVTX_SUPPORT_ANDROID_INJECTION_LIBRARY_IN_PACKAGE 0152 * - NVTX_SUPPORT_ALREADY_INJECTED_LIBRARY 0153 * - NVTX_SUPPORT_STATIC_INJECTION_LIBRARY 0154 */ 0155 #define NVTX_LOAD_SEQUENCE_VERSION 2 0156 0157 #ifndef NVTX_SUPPORT_ALREADY_INJECTED_LIBRARY 0158 /* Define this to 1 for platforms that where pre-injected libraries can be discovered. */ 0159 #if defined(_WIN32) 0160 /* Windows has no process-wide table of dynamic library symbols, so this can't be supported. */ 0161 #define NVTX_SUPPORT_ALREADY_INJECTED_LIBRARY 0 0162 #else 0163 /* POSIX platforms allow calling dlsym on a null module to use the process-wide table. 0164 * Note: Still disabled in load sequence version 2. Needs to support following the 0165 * RTLD_NEXT chain, and needs more testing before support can be enabled by default.*/ 0166 #define NVTX_SUPPORT_ALREADY_INJECTED_LIBRARY 0 0167 #endif 0168 #endif 0169 0170 #ifndef NVTX_SUPPORT_ENV_VARS 0171 /* Define this to 1 for platforms that support environment variables */ 0172 /* TODO: Detect UWP, a.k.a. Windows Store app, and set this to 0. */ 0173 /* Try: #if defined(WINAPI_FAMILY_PARTITION) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) */ 0174 #define NVTX_SUPPORT_ENV_VARS 1 0175 #endif 0176 0177 #ifndef NVTX_SUPPORT_DYNAMIC_INJECTION_LIBRARY 0178 /* Define this to 1 for platforms that support dynamic/shared libraries */ 0179 #define NVTX_SUPPORT_DYNAMIC_INJECTION_LIBRARY 1 0180 #endif 0181 0182 #ifndef NVTX_SUPPORT_ANDROID_INJECTION_LIBRARY_IN_PACKAGE 0183 #if defined(__ANDROID__) 0184 #define NVTX_SUPPORT_ANDROID_INJECTION_LIBRARY_IN_PACKAGE 1 0185 #else 0186 #define NVTX_SUPPORT_ANDROID_INJECTION_LIBRARY_IN_PACKAGE 0 0187 #endif 0188 #endif 0189 0190 #ifndef NVTX_SUPPORT_STATIC_INJECTION_LIBRARY 0191 /* On platforms that support weak symbols (i.e. non-Windows), injection libraries may 0192 * be statically linked into an application. This is useful for platforms where dynamic 0193 * injection is not available. Weak symbols not marked extern are definitions, not just 0194 * declarations. They are guaranteed to be initialized to zero if no normal definitions 0195 * are found by the linker to override them. This means the NVTX load sequence can safely 0196 * detect the presence of a static injection -- if InitializeInjectionNvtx2_fnptr is zero, 0197 * there is no static injection. */ 0198 #if defined(__GNUC__) && !defined(_WIN32) && !defined(__CYGWIN__) 0199 #define NVTX_SUPPORT_STATIC_INJECTION_LIBRARY 1 0200 #else 0201 #define NVTX_SUPPORT_STATIC_INJECTION_LIBRARY 0 0202 #endif 0203 #endif 0204 0205 #if NVTX_SUPPORT_STATIC_INJECTION_LIBRARY && !defined(NVTX_STATIC_INJECTION_IMPL) 0206 /* To make an NVTX injection library support static injection, it must do these things: 0207 * - Define InitializeInjectionNvtx2_fnptr as a normal symbol (not weak), pointing to 0208 * the implementation of InitializeInjectionNvtx2 (which does not need to be a 0209 * dynamic export if only supporting static injection). 0210 * - Define NVTX_STATIC_INJECTION_IMPL so the weak definition below is skipped. 0211 * - Compile the static injection files with -fPIC if they are to be linked with other 0212 * files compiled this way. If you forget this, GCC will simply tell you to add it. 0213 * When building the application, there a few ways to link in a static injection: 0214 * - Compile the injection's source files normally, and include the .o files as inputs 0215 * to the linker. 0216 * - If the injection is provided as an archive (.a file), it will not resolve any 0217 * unresolved symbols, so the linker will skip it by default. This can be fixed 0218 * by wrapping the static injection's name on the linker command line with options 0219 * to treat it differently. For example: 0220 * gcc example.o libfoo.a -Wl,--whole-archive libinj-static.a -Wl,--no-whole-archive libbar.a 0221 * Note that libinj-static.a is bracketed by options to turn on "whole archive" and 0222 * then back off again afterwards, so libfoo.a and libbar.a are linked normally. 0223 * - In CMake, a static injection can be added with options like this: 0224 * target_link_libraries(app PRIVATE -Wl,--whole-archive inj-static -Wl,--no-whole-archive) 0225 */ 0226 __attribute__((weak)) NvtxInitializeInjectionNvtxFunc_t InitializeInjectionNvtx2_fnptr; 0227 #endif 0228 0229 /* This function tries to find or load an NVTX injection library and get the 0230 * address of its InitializeInjection2 function. If such a function pointer 0231 * is found, it is called, and passed the address of this NVTX instance's 0232 * nvtxGetExportTable function, so the injection can attach to this instance. 0233 * If the initialization fails for any reason, any dynamic library loaded will 0234 * be freed, and all NVTX implementation functions will be set to no-ops. If 0235 * initialization succeeds, NVTX functions not attached to the tool will be set 0236 * to no-ops. This is implemented as one function instead of several small 0237 * functions to minimize the number of weak symbols the linker must resolve. 0238 * Order of search is: 0239 * - Pre-injected library exporting InitializeInjectionNvtx2 0240 * - Loadable library exporting InitializeInjectionNvtx2 0241 * - Path specified by env var NVTX_INJECTION??_PATH (?? is 32 or 64) 0242 * - On Android, libNvtxInjection??.so within the package (?? is 32 or 64) 0243 * - Statically-linked injection library defining InitializeInjectionNvtx2_fnptr 0244 */ 0245 NVTX_LINKONCE_FWDDECL_FUNCTION int NVTX_VERSIONED_IDENTIFIER(nvtxInitializeInjectionLibrary)(void); 0246 NVTX_LINKONCE_DEFINE_FUNCTION int NVTX_VERSIONED_IDENTIFIER(nvtxInitializeInjectionLibrary)(void) 0247 { 0248 static const char initFuncName[] = "InitializeInjectionNvtx2"; 0249 #if NVTX_SUPPORT_ALREADY_INJECTED_LIBRARY 0250 static const char initFuncPreinjectName[] = "InitializeInjectionNvtx2Preinject"; 0251 #endif 0252 NvtxInitializeInjectionNvtxFunc_t init_fnptr = NVTX_NULLPTR; 0253 NVTX_DLLHANDLE injectionLibraryHandle = NVTX_DLLDEFAULT; 0254 int entryPointStatus = 0; 0255 0256 #if NVTX_SUPPORT_DYNAMIC_INJECTION_LIBRARY 0257 /* Try discovering dynamic injection library to load */ 0258 { 0259 #if NVTX_SUPPORT_ENV_VARS 0260 /* If env var NVTX_INJECTION64_PATH is set, it should contain the path 0261 * to a 64-bit dynamic NVTX injection library (and similar for 32-bit). */ 0262 const NVTX_PATHCHAR* const nvtxEnvVarName = (sizeof(void*) == 4) 0263 ? NVTX_STR("NVTX_INJECTION32_PATH") 0264 : NVTX_STR("NVTX_INJECTION64_PATH"); 0265 #endif /* NVTX_SUPPORT_ENV_VARS */ 0266 NVTX_PATHCHAR injectionLibraryPathBuf[NVTX_BUFSIZE]; 0267 const NVTX_PATHCHAR* injectionLibraryPath = NVTX_NULLPTR; 0268 0269 /* Refer to this variable explicitly in case all references to it are #if'ed out */ 0270 (void)injectionLibraryPathBuf; 0271 0272 #if NVTX_SUPPORT_ENV_VARS 0273 /* Disable the warning for getenv & _wgetenv -- this usage is safe because 0274 * these functions are not called again before using the returned value. */ 0275 #if defined(_MSC_VER) 0276 #pragma warning( push ) 0277 #pragma warning( disable : 4996 ) 0278 #endif 0279 injectionLibraryPath = NVTX_GETENV(nvtxEnvVarName); 0280 #if defined(_MSC_VER) 0281 #pragma warning( pop ) 0282 #endif 0283 #endif 0284 0285 #if NVTX_SUPPORT_ANDROID_INJECTION_LIBRARY_IN_PACKAGE 0286 if (!injectionLibraryPath) 0287 { 0288 const char *bits = (sizeof(void*) == 4) ? "32" : "64"; 0289 char cmdlineBuf[32]; 0290 char pkgName[PATH_MAX]; 0291 int count; 0292 int pid; 0293 FILE *fp; 0294 size_t bytesRead; 0295 size_t pos; 0296 0297 pid = NVTX_STATIC_CAST(int, getpid()); 0298 count = snprintf(cmdlineBuf, sizeof(cmdlineBuf), "/proc/%d/cmdline", pid); 0299 if (count <= 0 || count >= NVTX_STATIC_CAST(int, sizeof(cmdlineBuf))) 0300 { 0301 NVTX_ERR("Path buffer too small for: /proc/%d/cmdline\n", pid); 0302 return NVTX_ERR_INIT_ACCESS_LIBRARY; 0303 } 0304 0305 fp = fopen(cmdlineBuf, "r"); 0306 if (!fp) 0307 { 0308 NVTX_ERR("File couldn't be opened: %s\n", cmdlineBuf); 0309 return NVTX_ERR_INIT_ACCESS_LIBRARY; 0310 } 0311 0312 bytesRead = fread(pkgName, 1, sizeof(pkgName) - 1, fp); 0313 fclose(fp); 0314 if (bytesRead == 0) 0315 { 0316 NVTX_ERR("Package name couldn't be read from file: %s\n", cmdlineBuf); 0317 return NVTX_ERR_INIT_ACCESS_LIBRARY; 0318 } 0319 0320 pkgName[bytesRead] = 0; 0321 0322 /* String can contain colon as a process separator. In this case the package name is before the colon. */ 0323 pos = 0; 0324 while (pos < bytesRead && pkgName[pos] != ':' && pkgName[pos] != '\0') 0325 { 0326 ++pos; 0327 } 0328 pkgName[pos] = 0; 0329 0330 count = snprintf(injectionLibraryPathBuf, NVTX_BUFSIZE, "/data/data/%s/files/libNvtxInjection%s.so", pkgName, bits); 0331 if (count <= 0 || count >= NVTX_BUFSIZE) 0332 { 0333 NVTX_ERR("Path buffer too small for: /data/data/%s/files/libNvtxInjection%s.so\n", pkgName, bits); 0334 return NVTX_ERR_INIT_ACCESS_LIBRARY; 0335 } 0336 0337 /* On Android, verify path is accessible due to aggressive file access restrictions. */ 0338 /* For dlopen, if the filename contains a leading slash, then it is interpreted as a */ 0339 /* relative or absolute pathname; otherwise it will follow the rules in ld.so. */ 0340 if (injectionLibraryPathBuf[0] == '/') 0341 { 0342 #if (__ANDROID_API__ < 21) 0343 int access_err = access(injectionLibraryPathBuf, F_OK | R_OK); 0344 #else 0345 int access_err = faccessat(AT_FDCWD, injectionLibraryPathBuf, F_OK | R_OK, 0); 0346 #endif 0347 if (access_err != 0) 0348 { 0349 NVTX_ERR("Injection library path wasn't accessible [code=%s] [path=%s]\n", strerror(errno), injectionLibraryPathBuf); 0350 return NVTX_ERR_INIT_ACCESS_LIBRARY; 0351 } 0352 } 0353 injectionLibraryPath = injectionLibraryPathBuf; 0354 } 0355 #endif /* NVTX_SUPPORT_ANDROID_INJECTION_LIBRARY_IN_PACKAGE */ 0356 0357 /* At this point, injectionLibraryPath is specified if a dynamic 0358 * injection library was specified by a tool. */ 0359 if (injectionLibraryPath) 0360 { 0361 /* Load the injection library */ 0362 injectionLibraryHandle = NVTX_DLLOPEN(injectionLibraryPath); 0363 if (!injectionLibraryHandle) 0364 { 0365 NVTX_ERR("Failed to load injection library\n"); 0366 return NVTX_ERR_INIT_LOAD_LIBRARY; 0367 } 0368 else 0369 { 0370 /* Attempt to get the injection library's entry-point */ 0371 init_fnptr = NVTX_REINTERPRET_CAST(NvtxInitializeInjectionNvtxFunc_t, NVTX_DLLFUNC(injectionLibraryHandle, initFuncName)); 0372 if (!init_fnptr) 0373 { 0374 NVTX_DLLCLOSE(injectionLibraryHandle); 0375 NVTX_ERR("Failed to get address of function InitializeInjectionNvtx2 from injection library\n"); 0376 return NVTX_ERR_INIT_MISSING_LIBRARY_ENTRY_POINT; 0377 } 0378 } 0379 } 0380 } 0381 #endif /* NVTX_SUPPORT_DYNAMIC_INJECTION_LIBRARY */ 0382 0383 #if NVTX_SUPPORT_ALREADY_INJECTED_LIBRARY 0384 if (!init_fnptr) 0385 { 0386 /* Use POSIX global symbol chain to query for init function from any module */ 0387 init_fnptr = NVTX_REINTERPRET_CAST(NvtxInitializeInjectionNvtxFunc_t, NVTX_DLLFUNC(NVTX_DLLDEFAULT, initFuncPreinjectName)); 0388 } 0389 #endif 0390 0391 #if NVTX_SUPPORT_STATIC_INJECTION_LIBRARY 0392 if (!init_fnptr) 0393 { 0394 /* Check weakly-defined function pointer. A statically-linked injection can define this 0395 * as a normal symbol and set it to the address of the NVTX init function -- this will 0396 * provide a non-null value here. If there is no other definition of this symbol, it 0397 * will be null here. */ 0398 if (InitializeInjectionNvtx2_fnptr) 0399 { 0400 init_fnptr = InitializeInjectionNvtx2_fnptr; 0401 } 0402 } 0403 #endif 0404 0405 /* At this point, if init_fnptr is not set, then no tool has specified 0406 * an NVTX injection library -- return non-success result so all NVTX 0407 * API functions will be set to no-ops. */ 0408 if (!init_fnptr) 0409 { 0410 return NVTX_ERR_NO_INJECTION_LIBRARY_AVAILABLE; 0411 } 0412 0413 /* Invoke injection library's initialization function. If it returns 0414 * 0 (failure) and a dynamic injection was loaded, unload it. */ 0415 entryPointStatus = init_fnptr(NVTX_VERSIONED_IDENTIFIER(nvtxGetExportTable)); 0416 if (entryPointStatus == 0) 0417 { 0418 NVTX_ERR("Failed to initialize injection library -- initialization function returned 0\n"); 0419 if (injectionLibraryHandle) 0420 { 0421 NVTX_DLLCLOSE(injectionLibraryHandle); 0422 } 0423 return NVTX_ERR_INIT_FAILED_LIBRARY_ENTRY_POINT; 0424 } 0425 0426 return NVTX_SUCCESS; 0427 } 0428 0429 NVTX_LINKONCE_DEFINE_FUNCTION void NVTX_VERSIONED_IDENTIFIER(nvtxInitOnce)(void) 0430 { 0431 unsigned int old; 0432 if (NVTX_VERSIONED_IDENTIFIER(nvtxGlobals).initState == NVTX_INIT_STATE_COMPLETE) 0433 { 0434 return; 0435 } 0436 0437 NVTX_ATOMIC_CAS_32( 0438 old, 0439 &NVTX_VERSIONED_IDENTIFIER(nvtxGlobals).initState, 0440 NVTX_INIT_STATE_STARTED, 0441 NVTX_INIT_STATE_FRESH); 0442 if (old == NVTX_INIT_STATE_FRESH) 0443 { 0444 int result; 0445 int forceAllToNoops; 0446 0447 /* Load & initialize injection library -- it will assign the function pointers */ 0448 result = NVTX_VERSIONED_IDENTIFIER(nvtxInitializeInjectionLibrary)(); 0449 0450 /* Set all pointers not assigned by the injection to null */ 0451 forceAllToNoops = result != NVTX_SUCCESS; /* Set all to null if injection init failed */ 0452 NVTX_VERSIONED_IDENTIFIER(nvtxSetInitFunctionsToNoops)(forceAllToNoops); 0453 0454 /* Signal that initialization has finished, so now the assigned function pointers will be used */ 0455 NVTX_ATOMIC_WRITE_32( 0456 &NVTX_VERSIONED_IDENTIFIER(nvtxGlobals).initState, 0457 NVTX_INIT_STATE_COMPLETE); 0458 } 0459 else /* Spin-wait until initialization has finished */ 0460 { 0461 NVTX_MEMBAR(); 0462 while (NVTX_VERSIONED_IDENTIFIER(nvtxGlobals).initState != NVTX_INIT_STATE_COMPLETE) 0463 { 0464 NVTX_YIELD(); 0465 NVTX_MEMBAR(); 0466 } 0467 } 0468 }
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|