root/opal/mca/hwloc/hwloc201/hwloc/hwloc/components.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. hwloc__dlforeach_cb
  2. hwloc_plugins_exit
  3. hwloc_plugins_init
  4. hwloc_disc_component_type_string
  5. hwloc_disc_component_register
  6. hwloc_components_init
  7. hwloc_backends_init
  8. hwloc_disc_component_find
  9. hwloc_disc_component_force_enable
  10. hwloc_disc_component_try_enable
  11. hwloc_disc_components_enable_others
  12. hwloc_components_fini
  13. hwloc_backend_alloc
  14. hwloc_backend_disable
  15. hwloc_backend_enable
  16. hwloc_backends_is_thissystem
  17. hwloc_backends_find_callbacks
  18. hwloc_backends_disable_all

   1 /*
   2  * Copyright © 2009-2017 Inria.  All rights reserved.
   3  * Copyright © 2012 Université Bordeaux
   4  * See COPYING in top-level directory.
   5  */
   6 
   7 #include <private/autogen/config.h>
   8 #include <hwloc.h>
   9 #include <private/private.h>
  10 #include <private/xml.h>
  11 #include <private/misc.h>
  12 
  13 #define HWLOC_COMPONENT_STOP_NAME "stop"
  14 #define HWLOC_COMPONENT_EXCLUDE_CHAR '-'
  15 #define HWLOC_COMPONENT_SEPS ","
  16 
  17 /* list of all registered discovery components, sorted by priority, higher priority first.
  18  * noos is last because its priority is 0.
  19  * others' priority is 10.
  20  */
  21 static struct hwloc_disc_component * hwloc_disc_components = NULL;
  22 
  23 static unsigned hwloc_components_users = 0; /* first one initializes, last ones destroys */
  24 
  25 static int hwloc_components_verbose = 0;
  26 #ifdef HWLOC_HAVE_PLUGINS
  27 static int hwloc_plugins_verbose = 0;
  28 static const char * hwloc_plugins_blacklist = NULL;
  29 #endif
  30 
  31 /* hwloc_components_mutex serializes:
  32  * - loading/unloading plugins, and modifications of the hwloc_plugins list
  33  * - calls to ltdl, including in hwloc_check_plugin_namespace()
  34  * - registration of components with hwloc_disc_component_register()
  35  *   and hwloc_xml_callbacks_register()
  36  */
  37 #ifdef HWLOC_WIN_SYS
  38 /* Basic mutex on top of InterlockedCompareExchange() on windows,
  39  * Far from perfect, but easy to maintain, and way enough given that this code will never be needed for real. */
  40 #include <windows.h>
  41 static LONG hwloc_components_mutex = 0;
  42 #define HWLOC_COMPONENTS_LOCK() do {                                            \
  43   while (InterlockedCompareExchange(&hwloc_components_mutex, 1, 0) != 0)        \
  44     SwitchToThread();                                                           \
  45 } while (0)
  46 #define HWLOC_COMPONENTS_UNLOCK() do {                                          \
  47   assert(hwloc_components_mutex == 1);                                          \
  48   hwloc_components_mutex = 0;                                                   \
  49 } while (0)
  50 
  51 #elif defined HWLOC_HAVE_PTHREAD_MUTEX
  52 /* pthread mutex if available (except on windows) */
  53 #include <pthread.h>
  54 static pthread_mutex_t hwloc_components_mutex = PTHREAD_MUTEX_INITIALIZER;
  55 #define HWLOC_COMPONENTS_LOCK() pthread_mutex_lock(&hwloc_components_mutex)
  56 #define HWLOC_COMPONENTS_UNLOCK() pthread_mutex_unlock(&hwloc_components_mutex)
  57 
  58 #else /* HWLOC_WIN_SYS || HWLOC_HAVE_PTHREAD_MUTEX */
  59 #error No mutex implementation available
  60 #endif
  61 
  62 
  63 #ifdef HWLOC_HAVE_PLUGINS
  64 
  65 #include <ltdl.h>
  66 
  67 /* array of pointers to dynamically loaded plugins */
  68 static struct hwloc__plugin_desc {
  69   char *name;
  70   struct hwloc_component *component;
  71   char *filename;
  72   lt_dlhandle handle;
  73   struct hwloc__plugin_desc *next;
  74 } *hwloc_plugins = NULL;
  75 
  76 static int
  77 hwloc__dlforeach_cb(const char *filename, void *_data __hwloc_attribute_unused)
  78 {
  79   const char *basename;
  80   lt_dlhandle handle;
  81   struct hwloc_component *component;
  82   struct hwloc__plugin_desc *desc, **prevdesc;
  83 
  84   if (hwloc_plugins_verbose)
  85     fprintf(stderr, "Plugin dlforeach found `%s'\n", filename);
  86 
  87   basename = strrchr(filename, '/');
  88   if (!basename)
  89     basename = filename;
  90   else
  91     basename++;
  92 
  93   if (hwloc_plugins_blacklist && strstr(hwloc_plugins_blacklist, basename)) {
  94     if (hwloc_plugins_verbose)
  95       fprintf(stderr, "Plugin `%s' is blacklisted in the environment\n", basename);
  96     goto out;
  97   }
  98 
  99   /* dlopen and get the component structure */
 100   handle = lt_dlopenext(filename);
 101   if (!handle) {
 102     if (hwloc_plugins_verbose)
 103       fprintf(stderr, "Failed to load plugin: %s\n", lt_dlerror());
 104     goto out;
 105   }
 106 
 107 {
 108   char componentsymbolname[strlen(basename)+10+1];
 109   sprintf(componentsymbolname, "%s_component", basename);
 110   component = lt_dlsym(handle, componentsymbolname);
 111   if (!component) {
 112     if (hwloc_plugins_verbose)
 113       fprintf(stderr, "Failed to find component symbol `%s'\n",
 114               componentsymbolname);
 115     goto out_with_handle;
 116   }
 117   if (component->abi != HWLOC_COMPONENT_ABI) {
 118     if (hwloc_plugins_verbose)
 119       fprintf(stderr, "Plugin symbol ABI %u instead of %d\n",
 120               component->abi, HWLOC_COMPONENT_ABI);
 121     goto out_with_handle;
 122   }
 123   if (hwloc_plugins_verbose)
 124     fprintf(stderr, "Plugin contains expected symbol `%s'\n",
 125             componentsymbolname);
 126 }
 127 
 128   if (HWLOC_COMPONENT_TYPE_DISC == component->type) {
 129     if (strncmp(basename, "hwloc_", 6)) {
 130       if (hwloc_plugins_verbose)
 131         fprintf(stderr, "Plugin name `%s' doesn't match its type DISCOVERY\n", basename);
 132       goto out_with_handle;
 133     }
 134   } else if (HWLOC_COMPONENT_TYPE_XML == component->type) {
 135     if (strncmp(basename, "hwloc_xml_", 10)) {
 136       if (hwloc_plugins_verbose)
 137         fprintf(stderr, "Plugin name `%s' doesn't match its type XML\n", basename);
 138       goto out_with_handle;
 139     }
 140   } else {
 141     if (hwloc_plugins_verbose)
 142       fprintf(stderr, "Plugin name `%s' has invalid type %u\n",
 143               basename, (unsigned) component->type);
 144     goto out_with_handle;
 145   }
 146 
 147   /* allocate a plugin_desc and queue it */
 148   desc = malloc(sizeof(*desc));
 149   if (!desc)
 150     goto out_with_handle;
 151   desc->name = strdup(basename);
 152   desc->filename = strdup(filename);
 153   desc->component = component;
 154   desc->handle = handle;
 155   desc->next = NULL;
 156   if (hwloc_plugins_verbose)
 157     fprintf(stderr, "Plugin descriptor `%s' ready\n", basename);
 158 
 159   /* append to the list */
 160   prevdesc = &hwloc_plugins;
 161   while (*prevdesc)
 162     prevdesc = &((*prevdesc)->next);
 163   *prevdesc = desc;
 164   if (hwloc_plugins_verbose)
 165     fprintf(stderr, "Plugin descriptor `%s' queued\n", basename);
 166   return 0;
 167 
 168  out_with_handle:
 169   lt_dlclose(handle);
 170  out:
 171   return 0;
 172 }
 173 
 174 static void
 175 hwloc_plugins_exit(void)
 176 {
 177   struct hwloc__plugin_desc *desc, *next;
 178 
 179   if (hwloc_plugins_verbose)
 180     fprintf(stderr, "Closing all plugins\n");
 181 
 182   desc = hwloc_plugins;
 183   while (desc) {
 184     next = desc->next;
 185     lt_dlclose(desc->handle);
 186     free(desc->name);
 187     free(desc->filename);
 188     free(desc);
 189     desc = next;
 190   }
 191   hwloc_plugins = NULL;
 192 
 193   lt_dlexit();
 194 }
 195 
 196 static int
 197 hwloc_plugins_init(void)
 198 {
 199   const char *verboseenv;
 200   const char *path = HWLOC_PLUGINS_PATH;
 201   const char *env;
 202   int err;
 203 
 204   verboseenv = getenv("HWLOC_PLUGINS_VERBOSE");
 205   hwloc_plugins_verbose = verboseenv ? atoi(verboseenv) : 0;
 206 
 207   hwloc_plugins_blacklist = getenv("HWLOC_PLUGINS_BLACKLIST");
 208 
 209   err = lt_dlinit();
 210   if (err)
 211     goto out;
 212 
 213   env = getenv("HWLOC_PLUGINS_PATH");
 214   if (env)
 215     path = env;
 216 
 217   hwloc_plugins = NULL;
 218 
 219   if (hwloc_plugins_verbose)
 220     fprintf(stderr, "Starting plugin dlforeach in %s\n", path);
 221   err = lt_dlforeachfile(path, hwloc__dlforeach_cb, NULL);
 222   if (err)
 223     goto out_with_init;
 224 
 225   return 0;
 226 
 227  out_with_init:
 228   hwloc_plugins_exit();
 229  out:
 230   return -1;
 231 }
 232 
 233 #endif /* HWLOC_HAVE_PLUGINS */
 234 
 235 static const char *
 236 hwloc_disc_component_type_string(hwloc_disc_component_type_t type)
 237 {
 238   switch (type) {
 239   case HWLOC_DISC_COMPONENT_TYPE_CPU: return "cpu";
 240   case HWLOC_DISC_COMPONENT_TYPE_GLOBAL: return "global";
 241   case HWLOC_DISC_COMPONENT_TYPE_MISC: return "misc";
 242   default: return "**unknown**";
 243   }
 244 }
 245 
 246 static int
 247 hwloc_disc_component_register(struct hwloc_disc_component *component,
 248                               const char *filename)
 249 {
 250   struct hwloc_disc_component **prev;
 251 
 252   /* check that the component name is valid */
 253   if (!strcmp(component->name, HWLOC_COMPONENT_STOP_NAME)) {
 254     if (hwloc_components_verbose)
 255       fprintf(stderr, "Cannot register discovery component with reserved name `" HWLOC_COMPONENT_STOP_NAME "'\n");
 256     return -1;
 257   }
 258   if (strchr(component->name, HWLOC_COMPONENT_EXCLUDE_CHAR)
 259       || strcspn(component->name, HWLOC_COMPONENT_SEPS) != strlen(component->name)) {
 260     if (hwloc_components_verbose)
 261       fprintf(stderr, "Cannot register discovery component with name `%s' containing reserved characters `%c" HWLOC_COMPONENT_SEPS "'\n",
 262               component->name, HWLOC_COMPONENT_EXCLUDE_CHAR);
 263     return -1;
 264   }
 265   /* check that the component type is valid */
 266   switch ((unsigned) component->type) {
 267   case HWLOC_DISC_COMPONENT_TYPE_CPU:
 268   case HWLOC_DISC_COMPONENT_TYPE_GLOBAL:
 269   case HWLOC_DISC_COMPONENT_TYPE_MISC:
 270     break;
 271   default:
 272     fprintf(stderr, "Cannot register discovery component `%s' with unknown type %u\n",
 273             component->name, (unsigned) component->type);
 274     return -1;
 275   }
 276 
 277   prev = &hwloc_disc_components;
 278   while (NULL != *prev) {
 279     if (!strcmp((*prev)->name, component->name)) {
 280       /* if two components have the same name, only keep the highest priority one */
 281       if ((*prev)->priority < component->priority) {
 282         /* drop the existing component */
 283         if (hwloc_components_verbose)
 284           fprintf(stderr, "Dropping previously registered discovery component `%s', priority %u lower than new one %u\n",
 285                   (*prev)->name, (*prev)->priority, component->priority);
 286         *prev = (*prev)->next;
 287       } else {
 288         /* drop the new one */
 289         if (hwloc_components_verbose)
 290           fprintf(stderr, "Ignoring new discovery component `%s', priority %u lower than previously registered one %u\n",
 291                   component->name, component->priority, (*prev)->priority);
 292         return -1;
 293       }
 294     }
 295     prev = &((*prev)->next);
 296   }
 297   if (hwloc_components_verbose)
 298     fprintf(stderr, "Registered %s discovery component `%s' with priority %u (%s%s)\n",
 299             hwloc_disc_component_type_string(component->type), component->name, component->priority,
 300             filename ? "from plugin " : "statically build", filename ? filename : "");
 301 
 302   prev = &hwloc_disc_components;
 303   while (NULL != *prev) {
 304     if ((*prev)->priority < component->priority)
 305       break;
 306     prev = &((*prev)->next);
 307   }
 308   component->next = *prev;
 309   *prev = component;
 310   return 0;
 311 }
 312 
 313 #include <static-components.h>
 314 
 315 static void (**hwloc_component_finalize_cbs)(unsigned long);
 316 static unsigned hwloc_component_finalize_cb_count;
 317 
 318 void
 319 hwloc_components_init(void)
 320 {
 321 #ifdef HWLOC_HAVE_PLUGINS
 322   struct hwloc__plugin_desc *desc;
 323 #endif
 324   const char *verboseenv;
 325   unsigned i;
 326 
 327   HWLOC_COMPONENTS_LOCK();
 328   assert((unsigned) -1 != hwloc_components_users);
 329   if (0 != hwloc_components_users++) {
 330     HWLOC_COMPONENTS_UNLOCK();
 331     return;
 332   }
 333 
 334   verboseenv = getenv("HWLOC_COMPONENTS_VERBOSE");
 335   hwloc_components_verbose = verboseenv ? atoi(verboseenv) : 0;
 336 
 337 #ifdef HWLOC_HAVE_PLUGINS
 338   hwloc_plugins_init();
 339 #endif
 340 
 341   hwloc_component_finalize_cbs = NULL;
 342   hwloc_component_finalize_cb_count = 0;
 343   /* count the max number of finalize callbacks */
 344   for(i=0; NULL != hwloc_static_components[i]; i++)
 345     hwloc_component_finalize_cb_count++;
 346 #ifdef HWLOC_HAVE_PLUGINS
 347   for(desc = hwloc_plugins; NULL != desc; desc = desc->next)
 348     hwloc_component_finalize_cb_count++;
 349 #endif
 350   if (hwloc_component_finalize_cb_count) {
 351     hwloc_component_finalize_cbs = calloc(hwloc_component_finalize_cb_count,
 352                                           sizeof(*hwloc_component_finalize_cbs));
 353     assert(hwloc_component_finalize_cbs);
 354     /* forget that max number and recompute the real one below */
 355     hwloc_component_finalize_cb_count = 0;
 356   }
 357 
 358   /* hwloc_static_components is created by configure in static-components.h */
 359   for(i=0; NULL != hwloc_static_components[i]; i++) {
 360     if (hwloc_static_components[i]->flags) {
 361       fprintf(stderr, "Ignoring static component with invalid flags %lx\n",
 362               hwloc_static_components[i]->flags);
 363       continue;
 364     }
 365 
 366     /* initialize the component */
 367     if (hwloc_static_components[i]->init && hwloc_static_components[i]->init(0) < 0) {
 368       if (hwloc_components_verbose)
 369         fprintf(stderr, "Ignoring static component, failed to initialize\n");
 370       continue;
 371     }
 372     /* queue ->finalize() callback if any */
 373     if (hwloc_static_components[i]->finalize)
 374       hwloc_component_finalize_cbs[hwloc_component_finalize_cb_count++] = hwloc_static_components[i]->finalize;
 375 
 376     /* register for real now */
 377     if (HWLOC_COMPONENT_TYPE_DISC == hwloc_static_components[i]->type)
 378       hwloc_disc_component_register(hwloc_static_components[i]->data, NULL);
 379     else if (HWLOC_COMPONENT_TYPE_XML == hwloc_static_components[i]->type)
 380       hwloc_xml_callbacks_register(hwloc_static_components[i]->data);
 381     else
 382       assert(0);
 383   }
 384 
 385   /* dynamic plugins */
 386 #ifdef HWLOC_HAVE_PLUGINS
 387   for(desc = hwloc_plugins; NULL != desc; desc = desc->next) {
 388     if (desc->component->flags) {
 389       fprintf(stderr, "Ignoring plugin `%s' component with invalid flags %lx\n",
 390               desc->name, desc->component->flags);
 391       continue;
 392     }
 393 
 394     /* initialize the component */
 395     if (desc->component->init && desc->component->init(0) < 0) {
 396       if (hwloc_components_verbose)
 397         fprintf(stderr, "Ignoring plugin `%s', failed to initialize\n", desc->name);
 398       continue;
 399     }
 400     /* queue ->finalize() callback if any */
 401     if (desc->component->finalize)
 402       hwloc_component_finalize_cbs[hwloc_component_finalize_cb_count++] = desc->component->finalize;
 403 
 404     /* register for real now */
 405     if (HWLOC_COMPONENT_TYPE_DISC == desc->component->type)
 406       hwloc_disc_component_register(desc->component->data, desc->filename);
 407     else if (HWLOC_COMPONENT_TYPE_XML == desc->component->type)
 408       hwloc_xml_callbacks_register(desc->component->data);
 409     else
 410       assert(0);
 411   }
 412 #endif
 413 
 414   HWLOC_COMPONENTS_UNLOCK();
 415 }
 416 
 417 void
 418 hwloc_backends_init(struct hwloc_topology *topology)
 419 {
 420   topology->backends = NULL;
 421   topology->backend_excludes = 0;
 422 }
 423 
 424 static struct hwloc_disc_component *
 425 hwloc_disc_component_find(int type /* hwloc_disc_component_type_t or -1 if any */,
 426                                const char *name /* name of NULL if any */)
 427 {
 428   struct hwloc_disc_component *comp = hwloc_disc_components;
 429   while (NULL != comp) {
 430     if ((-1 == type || type == (int) comp->type)
 431        && (NULL == name || !strcmp(name, comp->name)))
 432       return comp;
 433     comp = comp->next;
 434   }
 435   return NULL;
 436 }
 437 
 438 /* used by set_xml(), set_synthetic(), ... environment variables, ... to force the first backend */
 439 int
 440 hwloc_disc_component_force_enable(struct hwloc_topology *topology,
 441                                   int envvar_forced,
 442                                   int type, const char *name,
 443                                   const void *data1, const void *data2, const void *data3)
 444 {
 445   struct hwloc_disc_component *comp;
 446   struct hwloc_backend *backend;
 447 
 448   if (topology->is_loaded) {
 449     errno = EBUSY;
 450     return -1;
 451   }
 452 
 453   comp = hwloc_disc_component_find(type, name);
 454   if (!comp) {
 455     errno = ENOSYS;
 456     return -1;
 457   }
 458 
 459   backend = comp->instantiate(comp, data1, data2, data3);
 460   if (backend) {
 461     backend->envvar_forced = envvar_forced;
 462     if (topology->backends)
 463       hwloc_backends_disable_all(topology);
 464     return hwloc_backend_enable(topology, backend);
 465   } else
 466     return -1;
 467 }
 468 
 469 static int
 470 hwloc_disc_component_try_enable(struct hwloc_topology *topology,
 471                                 struct hwloc_disc_component *comp,
 472                                 const char *comparg,
 473                                 int envvar_forced)
 474 {
 475   struct hwloc_backend *backend;
 476 
 477   if (topology->backend_excludes & comp->type) {
 478     if (hwloc_components_verbose)
 479       /* do not warn if envvar_forced since system-wide HWLOC_COMPONENTS must be silently ignored after set_xml() etc.
 480        */
 481       fprintf(stderr, "Excluding %s discovery component `%s', conflicts with excludes 0x%x\n",
 482               hwloc_disc_component_type_string(comp->type), comp->name, topology->backend_excludes);
 483     return -1;
 484   }
 485 
 486   backend = comp->instantiate(comp, comparg, NULL, NULL);
 487   if (!backend) {
 488     if (hwloc_components_verbose || envvar_forced)
 489       fprintf(stderr, "Failed to instantiate discovery component `%s'\n", comp->name);
 490     return -1;
 491   }
 492 
 493   backend->envvar_forced = envvar_forced;
 494   return hwloc_backend_enable(topology, backend);
 495 }
 496 
 497 void
 498 hwloc_disc_components_enable_others(struct hwloc_topology *topology)
 499 {
 500   struct hwloc_disc_component *comp;
 501   struct hwloc_backend *backend;
 502   int tryall = 1;
 503   const char *_env;
 504   char *env; /* we'll to modify the env value, so duplicate it */
 505 
 506   _env = getenv("HWLOC_COMPONENTS");
 507   env = _env ? strdup(_env) : NULL;
 508 
 509   /* enable explicitly listed components */
 510   if (env) {
 511     char *curenv = env;
 512     size_t s;
 513 
 514     while (*curenv) {
 515       s = strcspn(curenv, HWLOC_COMPONENT_SEPS);
 516       if (s) {
 517         char c;
 518 
 519         /* replace linuxpci with linuxio for backward compatibility with pre-v2.0 */
 520         if (!strncmp(curenv, "linuxpci", 8) && s == 8) {
 521           curenv[5] = 'i';
 522           curenv[6] = 'o';
 523           curenv[7] = *HWLOC_COMPONENT_SEPS;
 524         } else if (curenv[0] == HWLOC_COMPONENT_EXCLUDE_CHAR && !strncmp(curenv+1, "linuxpci", 8) && s == 9) {
 525           curenv[6] = 'i';
 526           curenv[7] = 'o';
 527           curenv[8] = *HWLOC_COMPONENT_SEPS;
 528           /* skip this name, it's a negated one */
 529           goto nextname;
 530         }
 531 
 532         if (curenv[0] == HWLOC_COMPONENT_EXCLUDE_CHAR)
 533           goto nextname;
 534 
 535         if (!strncmp(curenv, HWLOC_COMPONENT_STOP_NAME, s)) {
 536           tryall = 0;
 537           break;
 538         }
 539 
 540         /* save the last char and replace with \0 */
 541         c = curenv[s];
 542         curenv[s] = '\0';
 543 
 544         comp = hwloc_disc_component_find(-1, curenv);
 545         if (comp) {
 546           hwloc_disc_component_try_enable(topology, comp, NULL, 1 /* envvar forced */);
 547         } else {
 548           fprintf(stderr, "Cannot find discovery component `%s'\n", curenv);
 549         }
 550 
 551         /* restore chars (the second loop below needs env to be unmodified) */
 552         curenv[s] = c;
 553       }
 554 
 555 nextname:
 556       curenv += s;
 557       if (*curenv)
 558         /* Skip comma */
 559         curenv++;
 560     }
 561   }
 562 
 563   /* env is still the same, the above loop didn't modify it */
 564 
 565   /* now enable remaining components (except the explicitly '-'-listed ones) */
 566   if (tryall) {
 567     comp = hwloc_disc_components;
 568     while (NULL != comp) {
 569       if (!comp->enabled_by_default)
 570         goto nextcomp;
 571       /* check if this component was explicitly excluded in env */
 572       if (env) {
 573         char *curenv = env;
 574         while (*curenv) {
 575           size_t s = strcspn(curenv, HWLOC_COMPONENT_SEPS);
 576           if (curenv[0] == HWLOC_COMPONENT_EXCLUDE_CHAR && !strncmp(curenv+1, comp->name, s-1) && strlen(comp->name) == s-1) {
 577             if (hwloc_components_verbose)
 578               fprintf(stderr, "Excluding %s discovery component `%s' because of HWLOC_COMPONENTS environment variable\n",
 579             hwloc_disc_component_type_string(comp->type), comp->name);
 580             goto nextcomp;
 581           }
 582           curenv += s;
 583           if (*curenv)
 584             /* Skip comma */
 585             curenv++;
 586         }
 587       }
 588       hwloc_disc_component_try_enable(topology, comp, NULL, 0 /* defaults, not envvar forced */);
 589 nextcomp:
 590       comp = comp->next;
 591     }
 592   }
 593 
 594   if (hwloc_components_verbose) {
 595     /* print a summary */
 596     int first = 1;
 597     backend = topology->backends;
 598     fprintf(stderr, "Final list of enabled discovery components: ");
 599     while (backend != NULL) {
 600       fprintf(stderr, "%s%s", first ? "" : ",", backend->component->name);
 601       backend = backend->next;
 602       first = 0;
 603     }
 604     fprintf(stderr, "\n");
 605   }
 606 
 607   free(env);
 608 }
 609 
 610 void
 611 hwloc_components_fini(void)
 612 {
 613   unsigned i;
 614 
 615   HWLOC_COMPONENTS_LOCK();
 616   assert(0 != hwloc_components_users);
 617   if (0 != --hwloc_components_users) {
 618     HWLOC_COMPONENTS_UNLOCK();
 619     return;
 620   }
 621 
 622   for(i=0; i<hwloc_component_finalize_cb_count; i++)
 623     hwloc_component_finalize_cbs[hwloc_component_finalize_cb_count-i-1](0);
 624   free(hwloc_component_finalize_cbs);
 625   hwloc_component_finalize_cbs = NULL;
 626   hwloc_component_finalize_cb_count = 0;
 627 
 628   /* no need to unlink/free the list of components, they'll be unloaded below */
 629 
 630   hwloc_disc_components = NULL;
 631   hwloc_xml_callbacks_reset();
 632 
 633 #ifdef HWLOC_HAVE_PLUGINS
 634   hwloc_plugins_exit();
 635 #endif
 636 
 637   HWLOC_COMPONENTS_UNLOCK();
 638 }
 639 
 640 struct hwloc_backend *
 641 hwloc_backend_alloc(struct hwloc_disc_component *component)
 642 {
 643   struct hwloc_backend * backend = malloc(sizeof(*backend));
 644   if (!backend) {
 645     errno = ENOMEM;
 646     return NULL;
 647   }
 648   backend->component = component;
 649   backend->flags = 0;
 650   backend->discover = NULL;
 651   backend->get_pci_busid_cpuset = NULL;
 652   backend->disable = NULL;
 653   backend->is_thissystem = -1;
 654   backend->next = NULL;
 655   backend->envvar_forced = 0;
 656   return backend;
 657 }
 658 
 659 static void
 660 hwloc_backend_disable(struct hwloc_backend *backend)
 661 {
 662   if (backend->disable)
 663     backend->disable(backend);
 664   free(backend);
 665 }
 666 
 667 int
 668 hwloc_backend_enable(struct hwloc_topology *topology, struct hwloc_backend *backend)
 669 {
 670   struct hwloc_backend **pprev;
 671 
 672   /* check backend flags */
 673   if (backend->flags) {
 674     fprintf(stderr, "Cannot enable %s discovery component `%s' with unknown flags %lx\n",
 675             hwloc_disc_component_type_string(backend->component->type), backend->component->name, backend->flags);
 676     return -1;
 677   }
 678 
 679   /* make sure we didn't already enable this backend, we don't want duplicates */
 680   pprev = &topology->backends;
 681   while (NULL != *pprev) {
 682     if ((*pprev)->component == backend->component) {
 683       if (hwloc_components_verbose)
 684         fprintf(stderr, "Cannot enable %s discovery component `%s' twice\n",
 685                 hwloc_disc_component_type_string(backend->component->type), backend->component->name);
 686       hwloc_backend_disable(backend);
 687       errno = EBUSY;
 688       return -1;
 689     }
 690     pprev = &((*pprev)->next);
 691   }
 692 
 693   if (hwloc_components_verbose)
 694     fprintf(stderr, "Enabling %s discovery component `%s'\n",
 695             hwloc_disc_component_type_string(backend->component->type), backend->component->name);
 696 
 697   /* enqueue at the end */
 698   pprev = &topology->backends;
 699   while (NULL != *pprev)
 700     pprev = &((*pprev)->next);
 701   backend->next = *pprev;
 702   *pprev = backend;
 703 
 704   backend->topology = topology;
 705   topology->backend_excludes |= backend->component->excludes;
 706   return 0;
 707 }
 708 
 709 void
 710 hwloc_backends_is_thissystem(struct hwloc_topology *topology)
 711 {
 712   struct hwloc_backend *backend;
 713   const char *local_env;
 714 
 715   /* Apply is_thissystem topology flag before we enforce envvar backends.
 716    * If the application changed the backend with set_foo(),
 717    * it may use set_flags() update the is_thissystem flag here.
 718    * If it changes the backend with environment variables below,
 719    * it may use HWLOC_THISSYSTEM envvar below as well.
 720    */
 721 
 722   topology->is_thissystem = 1;
 723 
 724   /* apply thissystem from normally-given backends (envvar_forced=0, either set_foo() or defaults) */
 725   backend = topology->backends;
 726   while (backend != NULL) {
 727     if (backend->envvar_forced == 0 && backend->is_thissystem != -1) {
 728       assert(backend->is_thissystem == 0);
 729       topology->is_thissystem = 0;
 730     }
 731     backend = backend->next;
 732   }
 733 
 734   /* override set_foo() with flags */
 735   if (topology->flags & HWLOC_TOPOLOGY_FLAG_IS_THISSYSTEM)
 736     topology->is_thissystem = 1;
 737 
 738   /* now apply envvar-forced backend (envvar_forced=1) */
 739   backend = topology->backends;
 740   while (backend != NULL) {
 741     if (backend->envvar_forced == 1 && backend->is_thissystem != -1) {
 742       assert(backend->is_thissystem == 0);
 743       topology->is_thissystem = 0;
 744     }
 745     backend = backend->next;
 746   }
 747 
 748   /* override with envvar-given flag */
 749   local_env = getenv("HWLOC_THISSYSTEM");
 750   if (local_env)
 751     topology->is_thissystem = atoi(local_env);
 752 }
 753 
 754 void
 755 hwloc_backends_find_callbacks(struct hwloc_topology *topology)
 756 {
 757   struct hwloc_backend *backend = topology->backends;
 758   /* use the first backend's get_pci_busid_cpuset callback */
 759   topology->get_pci_busid_cpuset_backend = NULL;
 760   while (backend != NULL) {
 761     if (backend->get_pci_busid_cpuset) {
 762       topology->get_pci_busid_cpuset_backend = backend;
 763       return;
 764     }
 765     backend = backend->next;
 766   }
 767   return;
 768 }
 769 
 770 void
 771 hwloc_backends_disable_all(struct hwloc_topology *topology)
 772 {
 773   struct hwloc_backend *backend;
 774 
 775   while (NULL != (backend = topology->backends)) {
 776     struct hwloc_backend *next = backend->next;
 777     if (hwloc_components_verbose)
 778       fprintf(stderr, "Disabling %s discovery component `%s'\n",
 779               hwloc_disc_component_type_string(backend->component->type), backend->component->name);
 780     hwloc_backend_disable(backend);
 781     topology->backends = next;
 782   }
 783   topology->backends = NULL;
 784   topology->backend_excludes = 0;
 785 }

/* [<][>][^][v][top][bottom][index][help] */