Intel(R) Threading Building Blocks Doxygen Documentation  version 4.2.3
dynamic_link.cpp
Go to the documentation of this file.
1 /*
2  Copyright (c) 2005-2019 Intel Corporation
3 
4  Licensed under the Apache License, Version 2.0 (the "License");
5  you may not use this file except in compliance with the License.
6  You may obtain a copy of the License at
7 
8  http://www.apache.org/licenses/LICENSE-2.0
9 
10  Unless required by applicable law or agreed to in writing, software
11  distributed under the License is distributed on an "AS IS" BASIS,
12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  See the License for the specific language governing permissions and
14  limitations under the License.
15 
16 
17 
18 
19 */
20 
21 #include "dynamic_link.h"
22 #include "tbb/tbb_config.h"
23 
24 /*
25  This file is used by both TBB and OpenMP RTL. Do not use __TBB_ASSERT() macro
26  and runtime_warning() function because they are not available in OpenMP. Use
27  LIBRARY_ASSERT and DYNAMIC_LINK_WARNING instead.
28 */
29 
30 #include <cstdarg> // va_list etc.
31 #if _WIN32
32  #include <malloc.h>
33 
34  // Unify system calls
35  #define dlopen( name, flags ) LoadLibrary( name )
36  #define dlsym( handle, name ) GetProcAddress( handle, name )
37  #define dlclose( handle ) ( ! FreeLibrary( handle ) )
38  #define dlerror() GetLastError()
39 #ifndef PATH_MAX
40  #define PATH_MAX MAX_PATH
41 #endif
42 #else /* _WIN32 */
43  #include <dlfcn.h>
44  #include <string.h>
45  #include <unistd.h>
46  #include <limits.h>
47  #include <stdlib.h>
48 #endif /* _WIN32 */
49 
50 #if __TBB_WEAK_SYMBOLS_PRESENT && !__TBB_DYNAMIC_LOAD_ENABLED
51  //TODO: use function attribute for weak symbols instead of the pragma.
52  #pragma weak dlopen
53  #pragma weak dlsym
54  #pragma weak dlclose
55 #endif /* __TBB_WEAK_SYMBOLS_PRESENT && !__TBB_DYNAMIC_LOAD_ENABLED */
56 
57 #include "tbb_misc.h"
58 
59 #define __USE_TBB_ATOMICS ( !(__linux__&&__ia64__) || __TBB_BUILD )
60 #define __USE_STATIC_DL_INIT ( !__ANDROID__ )
61 
62 #if !__USE_TBB_ATOMICS
63 #include <pthread.h>
64 #endif
65 
66 /*
67 dynamic_link is a common interface for searching for required symbols in an
68 executable and dynamic libraries.
69 
70 dynamic_link provides certain guarantees:
71  1. Either all or none of the requested symbols are resolved. Moreover, if
72  symbols are not resolved, the dynamic_link_descriptor table is not modified;
73  2. All returned symbols have secured lifetime: this means that none of them
74  can be invalidated until dynamic_unlink is called;
75  3. Any loaded library is loaded only via the full path. The full path is that
76  from which the runtime itself was loaded. (This is done to avoid security
77  issues caused by loading libraries from insecure paths).
78 
79 dynamic_link searches for the requested symbols in three stages, stopping as
80 soon as all of the symbols have been resolved.
81 
82  1. Search the global scope:
83  a. On Windows: dynamic_link tries to obtain the handle of the requested
84  library and if it succeeds it resolves the symbols via that handle.
85  b. On Linux: dynamic_link tries to search for the symbols in the global
86  scope via the main program handle. If the symbols are present in the global
87  scope their lifetime is not guaranteed (since dynamic_link does not know
88  anything about the library from which they are exported). Therefore it
89  tries to "pin" the symbols by obtaining the library name and reopening it.
90  dlopen may fail to reopen the library in two cases:
91  i. The symbols are exported from the executable. Currently dynamic _link
92  cannot handle this situation, so it will not find these symbols in this
93  step.
94  ii. The necessary library has been unloaded and cannot be reloaded. It
95  seems there is nothing that can be done in this case. No symbols are
96  returned.
97 
98  2. Dynamic load: an attempt is made to load the requested library via the
99  full path.
100  The full path used is that from which the runtime itself was loaded. If the
101  library can be loaded, then an attempt is made to resolve the requested
102  symbols in the newly loaded library.
103  If the symbols are not found the library is unloaded.
104 
105  3. Weak symbols: if weak symbols are available they are returned.
106 */
107 
109 
110 #if __TBB_WEAK_SYMBOLS_PRESENT || __TBB_DYNAMIC_LOAD_ENABLED
111 
112 #if !defined(DYNAMIC_LINK_WARNING) && !__TBB_WIN8UI_SUPPORT && __TBB_DYNAMIC_LOAD_ENABLED
113  // Report runtime errors and continue.
114  #define DYNAMIC_LINK_WARNING dynamic_link_warning
115  static void dynamic_link_warning( dynamic_link_error_t code, ... ) {
116  (void) code;
117  } // library_warning
118 #endif /* !defined(DYNAMIC_LINK_WARNING) && !__TBB_WIN8UI_SUPPORT && __TBB_DYNAMIC_LOAD_ENABLED */
119 
120  static bool resolve_symbols( dynamic_link_handle module, const dynamic_link_descriptor descriptors[], size_t required )
121  {
122  if ( !module )
123  return false;
124 
125  #if !__TBB_DYNAMIC_LOAD_ENABLED /* only __TBB_WEAK_SYMBOLS_PRESENT is defined */
126  if ( !dlsym ) return false;
127  #endif /* !__TBB_DYNAMIC_LOAD_ENABLED */
128 
129  const size_t n_desc=20; // Usually we don't have more than 20 descriptors per library
130  LIBRARY_ASSERT( required <= n_desc, "Too many descriptors is required" );
131  if ( required > n_desc ) return false;
132  pointer_to_handler h[n_desc];
133 
134  for ( size_t k = 0; k < required; ++k ) {
135  dynamic_link_descriptor const & desc = descriptors[k];
136  pointer_to_handler addr = (pointer_to_handler)dlsym( module, desc.name );
137  if ( !addr ) {
138  return false;
139  }
140  h[k] = addr;
141  }
142 
143  // Commit the entry points.
144  // Cannot use memset here, because the writes must be atomic.
145  for( size_t k = 0; k < required; ++k )
146  *descriptors[k].handler = h[k];
147  return true;
148  }
149 
150 #if __TBB_WIN8UI_SUPPORT
151  bool dynamic_link( const char* library, const dynamic_link_descriptor descriptors[], size_t required, dynamic_link_handle*, int flags ) {
152  dynamic_link_handle tmp_handle = NULL;
153  TCHAR wlibrary[256];
154  if ( MultiByteToWideChar(CP_UTF8, 0, library, -1, wlibrary, 255) == 0 ) return false;
155  if ( flags & DYNAMIC_LINK_LOAD )
156  tmp_handle = LoadPackagedLibrary( wlibrary, 0 );
157  if (tmp_handle != NULL){
158  return resolve_symbols(tmp_handle, descriptors, required);
159  }else{
160  return false;
161  }
162  }
164  void dynamic_unlink_all() {}
165 #else
166 #if __TBB_DYNAMIC_LOAD_ENABLED
167 /*
168  There is a security issue on Windows: LoadLibrary() may load and execute malicious code.
169  See http://www.microsoft.com/technet/security/advisory/2269637.mspx for details.
170  To avoid the issue, we have to pass full path (not just library name) to LoadLibrary. This
171  function constructs full path to the specified library (it is assumed the library located
172  side-by-side with the tbb.dll.
173 
174  The function constructs absolute path for given relative path. Important: Base directory is not
175  current one, it is the directory tbb.dll loaded from.
176 
177  Example:
178  Let us assume "tbb.dll" is located in "c:\program files\common\intel\" directory, e. g.
179  absolute path of tbb library is "c:\program files\common\intel\tbb.dll". Absolute path for
180  "tbbmalloc.dll" would be "c:\program files\common\intel\tbbmalloc.dll". Absolute path for
181  "malloc\tbbmalloc.dll" would be "c:\program files\common\intel\malloc\tbbmalloc.dll".
182 */
183 
184  // Struct handle_storage is used by dynamic_link routine to store handles of
185  // all loaded or pinned dynamic libraries. When TBB is shut down, it calls
186  // dynamic_unlink_all() that unloads modules referenced by handle_storage.
187  // This struct should not have any constructors since it may be used before
188  // the constructor is called.
189  #define MAX_LOADED_MODULES 8 // The number of maximum possible modules which can be loaded
190 
191 #if __USE_TBB_ATOMICS
192  typedef ::tbb::atomic<size_t> atomic_incrementer;
193  void init_atomic_incrementer( atomic_incrementer & ) {}
194 
195  static void atomic_once( void( *func ) (void), tbb::atomic< tbb::internal::do_once_state > &once_state ) {
196  tbb::internal::atomic_do_once( func, once_state );
197  }
198  #define ATOMIC_ONCE_DECL( var ) tbb::atomic< tbb::internal::do_once_state > var
199 #else
200  static void pthread_assert( int error_code, const char* msg ) {
201  LIBRARY_ASSERT( error_code == 0, msg );
202  }
203 
204  class atomic_incrementer {
205  size_t my_val;
206  pthread_spinlock_t my_lock;
207  public:
208  void init() {
209  my_val = 0;
210  pthread_assert( pthread_spin_init( &my_lock, PTHREAD_PROCESS_PRIVATE ), "pthread_spin_init failed" );
211  }
212  size_t operator++(int) {
213  pthread_assert( pthread_spin_lock( &my_lock ), "pthread_spin_lock failed" );
214  size_t prev_val = my_val++;
215  pthread_assert( pthread_spin_unlock( &my_lock ), "pthread_spin_unlock failed" );
216  return prev_val;
217  }
218  operator size_t() {
219  pthread_assert( pthread_spin_lock( &my_lock ), "pthread_spin_lock failed" );
220  size_t val = my_val;
221  pthread_assert( pthread_spin_unlock( &my_lock ), "pthread_spin_unlock failed" );
222  return val;
223  }
224  ~atomic_incrementer() {
225  pthread_assert( pthread_spin_destroy( &my_lock ), "pthread_spin_destroy failed" );
226  }
227  };
228 
229  void init_atomic_incrementer( atomic_incrementer &r ) {
230  r.init();
231  }
232 
233  static void atomic_once( void( *func ) (), pthread_once_t &once_state ) {
234  pthread_assert( pthread_once( &once_state, func ), "pthread_once failed" );
235  }
236  #define ATOMIC_ONCE_DECL( var ) pthread_once_t var = PTHREAD_ONCE_INIT
237 #endif /* __USE_TBB_ATOMICS */
238 
239  struct handles_t {
240  atomic_incrementer my_size;
241  dynamic_link_handle my_handles[MAX_LOADED_MODULES];
242 
243  void init() {
244  init_atomic_incrementer( my_size );
245  }
246 
247  void add(const dynamic_link_handle &handle) {
248  const size_t ind = my_size++;
249  LIBRARY_ASSERT( ind < MAX_LOADED_MODULES, "Too many modules are loaded" );
250  my_handles[ind] = handle;
251  }
252 
253  void free() {
254  const size_t size = my_size;
255  for (size_t i=0; i<size; ++i)
256  dynamic_unlink( my_handles[i] );
257  }
258  } handles;
259 
260  ATOMIC_ONCE_DECL( init_dl_data_state );
261 
262  static struct ap_data_t {
263  char _path[PATH_MAX+1];
264  size_t _len;
265  } ap_data;
266 
267  static void init_ap_data() {
268  #if _WIN32
269  // Get handle of our DLL first.
270  HMODULE handle;
271  BOOL brc = GetModuleHandleEx(
272  GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
273  (LPCSTR)( & dynamic_link ), // any function inside the library can be used for the address
274  & handle
275  );
276  if ( !brc ) { // Error occurred.
277  int err = GetLastError();
278  DYNAMIC_LINK_WARNING( dl_sys_fail, "GetModuleHandleEx", err );
279  return;
280  }
281  // Now get path to our DLL.
282  DWORD drc = GetModuleFileName( handle, ap_data._path, static_cast< DWORD >( PATH_MAX ) );
283  if ( drc == 0 ) { // Error occurred.
284  int err = GetLastError();
285  DYNAMIC_LINK_WARNING( dl_sys_fail, "GetModuleFileName", err );
286  return;
287  }
288  if ( drc >= PATH_MAX ) { // Buffer too short.
289  DYNAMIC_LINK_WARNING( dl_buff_too_small );
290  return;
291  }
292  // Find the position of the last backslash.
293  char *backslash = strrchr( ap_data._path, '\\' );
294 
295  if ( !backslash ) { // Backslash not found.
296  LIBRARY_ASSERT( backslash!=NULL, "Unbelievable.");
297  return;
298  }
299  LIBRARY_ASSERT( backslash >= ap_data._path, "Unbelievable.");
300  ap_data._len = (size_t)(backslash - ap_data._path) + 1;
301  *(backslash+1) = 0;
302  #else
303  // Get the library path
304  Dl_info dlinfo;
305  int res = dladdr( (void*)&dynamic_link, &dlinfo ); // any function inside the library can be used for the address
306  if ( !res ) {
307  char const * err = dlerror();
308  DYNAMIC_LINK_WARNING( dl_sys_fail, "dladdr", err );
309  return;
310  } else {
311  LIBRARY_ASSERT( dlinfo.dli_fname!=NULL, "Unbelievable." );
312  }
313 
314  char const *slash = strrchr( dlinfo.dli_fname, '/' );
315  size_t fname_len=0;
316  if ( slash ) {
317  LIBRARY_ASSERT( slash >= dlinfo.dli_fname, "Unbelievable.");
318  fname_len = (size_t)(slash - dlinfo.dli_fname) + 1;
319  }
320 
321  size_t rc;
322  if ( dlinfo.dli_fname[0]=='/' ) {
323  // The library path is absolute
324  rc = 0;
325  ap_data._len = 0;
326  } else {
327  // The library path is relative so get the current working directory
328  if ( !getcwd( ap_data._path, sizeof(ap_data._path)/sizeof(ap_data._path[0]) ) ) {
329  DYNAMIC_LINK_WARNING( dl_buff_too_small );
330  return;
331  }
332  ap_data._len = strlen( ap_data._path );
333  ap_data._path[ap_data._len++]='/';
334  rc = ap_data._len;
335  }
336 
337  if ( fname_len>0 ) {
338  if ( ap_data._len>PATH_MAX ) {
339  DYNAMIC_LINK_WARNING( dl_buff_too_small );
340  ap_data._len=0;
341  return;
342  }
343  strncpy( ap_data._path+rc, dlinfo.dli_fname, fname_len );
344  ap_data._len += fname_len;
345  ap_data._path[ap_data._len]=0;
346  }
347  #endif /* _WIN32 */
348  }
349 
350  static void init_dl_data() {
351  handles.init();
352  init_ap_data();
353  }
354 
355  /*
356  The function constructs absolute path for given relative path. Important: Base directory is not
357  current one, it is the directory libtbb.so loaded from.
358 
359  Arguments:
360  in name -- Name of a file (may be with relative path; it must not be an absolute one).
361  out path -- Buffer to save result (absolute path) to.
362  in len -- Size of buffer.
363  ret -- 0 -- Error occurred.
364  > len -- Buffer too short, required size returned.
365  otherwise -- Ok, number of characters (incl. terminating null) written to buffer.
366  */
367  static size_t abs_path( char const * name, char * path, size_t len ) {
368  if ( ap_data._len == 0 )
369  return 0;
370 
371  size_t name_len = strlen( name );
372  size_t full_len = name_len+ap_data._len;
373  if ( full_len < len ) {
374  __TBB_ASSERT(ap_data._path[ap_data._len] == 0, NULL);
375  strcpy( path, ap_data._path );
376  strcat( path, name );
377  }
378  return full_len+1; // +1 for null character
379  }
380 #endif // __TBB_DYNAMIC_LOAD_ENABLED
381 
382  void init_dynamic_link_data() {
383  #if __TBB_DYNAMIC_LOAD_ENABLED
384  atomic_once( &init_dl_data, init_dl_data_state );
385  #endif
386  }
387 
388  #if __USE_STATIC_DL_INIT
389  // ap_data structure is initialized with current directory on Linux.
390  // So it should be initialized as soon as possible since the current directory may be changed.
391  // static_init_ap_data object provides this initialization during library loading.
392  static struct static_init_dl_data_t {
393  static_init_dl_data_t() {
394  init_dynamic_link_data();
395  }
396  } static_init_dl_data;
397  #endif
398 
399  #if __TBB_WEAK_SYMBOLS_PRESENT
400  static bool weak_symbol_link( const dynamic_link_descriptor descriptors[], size_t required )
401  {
402  // Check if the required entries are present in what was loaded into our process.
403  for ( size_t k = 0; k < required; ++k )
404  if ( !descriptors[k].ptr )
405  return false;
406  // Commit the entry points.
407  for ( size_t k = 0; k < required; ++k )
408  *descriptors[k].handler = (pointer_to_handler) descriptors[k].ptr;
409  return true;
410  }
411  #else
412  static bool weak_symbol_link( const dynamic_link_descriptor[], size_t ) {
413  return false;
414  }
415  #endif /* __TBB_WEAK_SYMBOLS_PRESENT */
416 
417  void dynamic_unlink( dynamic_link_handle handle ) {
418  #if !__TBB_DYNAMIC_LOAD_ENABLED /* only __TBB_WEAK_SYMBOLS_PRESENT is defined */
419  if ( !dlclose ) return;
420  #endif
421  if ( handle ) {
422  dlclose( handle );
423  }
424  }
425 
426  void dynamic_unlink_all() {
427  #if __TBB_DYNAMIC_LOAD_ENABLED
428  handles.free();
429  #endif
430  }
431 
432 #if !_WIN32
433 #if __TBB_DYNAMIC_LOAD_ENABLED
434  static dynamic_link_handle pin_symbols( dynamic_link_descriptor desc, const dynamic_link_descriptor* descriptors, size_t required ) {
435  // It is supposed that all symbols are from the only one library
436  // The library has been loaded by another module and contains at least one requested symbol.
437  // But after we obtained the symbol the library can be unloaded by another thread
438  // invalidating our symbol. Therefore we need to pin the library in memory.
439  dynamic_link_handle library_handle = 0;
440  Dl_info info;
441  // Get library's name from earlier found symbol
442  if ( dladdr( (void*)*desc.handler, &info ) ) {
443  // Pin the library
444  library_handle = dlopen( info.dli_fname, RTLD_LAZY );
445  if ( library_handle ) {
446  // If original library was unloaded before we pinned it
447  // and then another module loaded in its place, the earlier
448  // found symbol would become invalid. So revalidate them.
449  if ( !resolve_symbols( library_handle, descriptors, required ) ) {
450  // Wrong library.
451  dynamic_unlink(library_handle);
452  library_handle = 0;
453  }
454  } else {
455  char const * err = dlerror();
456  DYNAMIC_LINK_WARNING( dl_lib_not_found, info.dli_fname, err );
457  }
458  }
459  // else the library has been unloaded by another thread
460  return library_handle;
461  }
462 #endif /* __TBB_DYNAMIC_LOAD_ENABLED */
463 #endif /* !_WIN32 */
464 
465  static dynamic_link_handle global_symbols_link( const char* library, const dynamic_link_descriptor descriptors[], size_t required ) {
467  dynamic_link_handle library_handle;
468 #if _WIN32
469  if ( GetModuleHandleEx( 0, library, &library_handle ) ) {
470  if ( resolve_symbols( library_handle, descriptors, required ) )
471  return library_handle;
472  else
473  FreeLibrary( library_handle );
474  }
475 #else /* _WIN32 */
476  #if !__TBB_DYNAMIC_LOAD_ENABLED /* only __TBB_WEAK_SYMBOLS_PRESENT is defined */
477  if ( !dlopen ) return 0;
478  #endif /* !__TBB_DYNAMIC_LOAD_ENABLED */
479  library_handle = dlopen( NULL, RTLD_LAZY );
480  #if !__ANDROID__
481  // On Android dlopen( NULL ) returns NULL if it is called during dynamic module initialization.
482  LIBRARY_ASSERT( library_handle, "The handle for the main program is NULL" );
483  #endif
484  #if __TBB_DYNAMIC_LOAD_ENABLED
485  // Check existence of the first symbol only, then use it to find the library and load all necessary symbols.
486  pointer_to_handler handler;
488  desc.name = descriptors[0].name;
489  desc.handler = &handler;
490  if ( resolve_symbols( library_handle, &desc, 1 ) ) {
491  dynamic_unlink( library_handle );
492  return pin_symbols( desc, descriptors, required );
493  }
494  #else /* only __TBB_WEAK_SYMBOLS_PRESENT is defined */
495  if ( resolve_symbols( library_handle, descriptors, required ) )
496  return library_handle;
497  #endif
498  dynamic_unlink( library_handle );
499 #endif /* _WIN32 */
500  return 0;
501  }
502 
503  static void save_library_handle( dynamic_link_handle src, dynamic_link_handle *dst ) {
504  LIBRARY_ASSERT( src, "The library handle to store must be non-zero" );
505  if ( dst )
506  *dst = src;
507  #if __TBB_DYNAMIC_LOAD_ENABLED
508  else
509  handles.add( src );
510  #endif /* __TBB_DYNAMIC_LOAD_ENABLED */
511  }
512 
513  dynamic_link_handle dynamic_load( const char* library, const dynamic_link_descriptor descriptors[], size_t required ) {
514  ::tbb::internal::suppress_unused_warning( library, descriptors, required );
515 #if __TBB_DYNAMIC_LOAD_ENABLED
516 
517  size_t const len = PATH_MAX + 1;
518  char path[ len ];
519  size_t rc = abs_path( library, path, len );
520  if ( 0 < rc && rc <= len ) {
521 #if _WIN32
522  // Prevent Windows from displaying silly message boxes if it fails to load library
523  // (e.g. because of MS runtime problems - one of those crazy manifest related ones)
524  UINT prev_mode = SetErrorMode (SEM_FAILCRITICALERRORS);
525 #endif /* _WIN32 */
526  dynamic_link_handle library_handle = dlopen( path, RTLD_LAZY );
527 #if _WIN32
528  SetErrorMode (prev_mode);
529 #endif /* _WIN32 */
530  if( library_handle ) {
531  if( !resolve_symbols( library_handle, descriptors, required ) ) {
532  // The loaded library does not contain all the expected entry points
533  dynamic_unlink( library_handle );
534  library_handle = NULL;
535  }
536  } else
537  DYNAMIC_LINK_WARNING( dl_lib_not_found, path, dlerror() );
538  return library_handle;
539  } else if ( rc>len )
540  DYNAMIC_LINK_WARNING( dl_buff_too_small );
541  // rc == 0 means failing of init_ap_data so the warning has already been issued.
542 
543 #endif /* __TBB_DYNAMIC_LOAD_ENABLED */
544  return 0;
545  }
546 
547  bool dynamic_link( const char* library, const dynamic_link_descriptor descriptors[], size_t required, dynamic_link_handle *handle, int flags ) {
548  init_dynamic_link_data();
549 
550  // TODO: May global_symbols_link find weak symbols?
551  dynamic_link_handle library_handle = ( flags & DYNAMIC_LINK_GLOBAL ) ? global_symbols_link( library, descriptors, required ) : 0;
552 
553  if ( !library_handle && ( flags & DYNAMIC_LINK_LOAD ) )
554  library_handle = dynamic_load( library, descriptors, required );
555 
556  if ( !library_handle && ( flags & DYNAMIC_LINK_WEAK ) )
557  return weak_symbol_link( descriptors, required );
558 
559  if ( library_handle ) {
560  save_library_handle( library_handle, handle );
561  return true;
562  }
563  return false;
564  }
565 
566 #endif /*__TBB_WIN8UI_SUPPORT*/
567 #else /* __TBB_WEAK_SYMBOLS_PRESENT || __TBB_DYNAMIC_LOAD_ENABLED */
568  bool dynamic_link( const char*, const dynamic_link_descriptor*, size_t, dynamic_link_handle *handle, int ) {
569  if ( handle )
570  *handle=0;
571  return false;
572  }
575 #endif /* __TBB_WEAK_SYMBOLS_PRESENT || __TBB_DYNAMIC_LOAD_ENABLED */
576 
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function h
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
Definition: tbb_stddef.h:169
void suppress_unused_warning(const T1 &)
Utility template function to prevent "unused" warnings by various compilers.
Definition: tbb_stddef.h:381
const char * name
Name of the handler.
Definition: dynamic_link.h:66
void * addr
#define CLOSE_INTERNAL_NAMESPACE
Definition: dynamic_link.h:40
Association between a handler name and location of pointer to it.
Definition: dynamic_link.h:64
OPEN_INTERNAL_NAMESPACE bool dynamic_link(const char *, const dynamic_link_descriptor *, size_t, dynamic_link_handle *handle, int)
const int DYNAMIC_LINK_WEAK
Definition: dynamic_link.h:83
#define OPEN_INTERNAL_NAMESPACE
Definition: dynamic_link.h:39
const int DYNAMIC_LINK_LOAD
Definition: dynamic_link.h:82
void * dynamic_link_handle
Definition: dynamic_link.h:78
#define PATH_MAX
void atomic_do_once(const F &initializer, atomic< do_once_state > &state)
One-time initialization function.
Definition: tbb_misc.h:210
const int DYNAMIC_LINK_GLOBAL
Definition: dynamic_link.h:81
Primary template for atomic.
Definition: atomic.h:407
pointer_to_handler * handler
Pointer to the handler.
Definition: dynamic_link.h:68
void dynamic_unlink_all()
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t size
OPEN_INTERNAL_NAMESPACE typedef void(* pointer_to_handler)()
Type definition for a pointer to a void somefunc(void)
Definition: dynamic_link.h:51
dynamic_link_error_t
Definition: dynamic_link.h:112
#define LIBRARY_ASSERT(x, y)
Definition: dynamic_link.h:32
void dynamic_unlink(dynamic_link_handle)
void const char const char int ITT_FORMAT __itt_group_sync x void const char * name

Copyright © 2005-2019 Intel Corporation. All Rights Reserved.

Intel, Pentium, Intel Xeon, Itanium, Intel XScale and VTune are registered trademarks or trademarks of Intel Corporation or its subsidiaries in the United States and other countries.

* Other names and brands may be claimed as the property of others.